Simple snippet of ListView and getView - java

I want a simple snippet of a ListView which is composed of items taken from a dataset array which also makes use of getView() method. ListView only contains text entries unlike text and images both.

http://www.ezzylearning.com/tutorial.aspx?tid=1763429
<TextView android:id="#+id/txtTitle"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:textStyle="bold"
android:textSize="22dp"
android:textColor="#000000"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp" />
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
WeatherHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new WeatherHolder();
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder);
}
else
{
holder = (WeatherHolder)row.getTag();
}
Weather weather = data[position];
holder.txtTitle.setText(weather.title);
return row;
}

Related

button.OnClick code runs but doesn't execute changes?

I'm trying to make an OnClick listener for an imagebutton, that is supposed to remove a bitmap (set it to null) on click. However, nothing happens when I press the button, except it does print my "Log.d()" message, and the bitmap IS actually null after the click, however changes doesn't show. The code is written inside my adapter. I even tried inserting it inside a runOnUIThread to see if that makes a difference, however there's no change.
I also tried setImageDrawable(null) and setImageResource(0) with no luck. I even tried changing other UI elements, and that doesn't work either. Only thing I can make it do is print the log message...
Here's my getView with my onClick method:
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.item_create_product_gridview_normal, parent, false);
//Set up viewholder
viewHolder = new ViewHolder();
viewHolder.productImageIv = (ImageView) convertView.findViewById(R.id.android_gridview_image);
viewHolder.addImageIb = (ImageButton) convertView.findViewById(R.id.addImageButton);
viewHolder.removeImageIb = (ImageButton) convertView.findViewById(R.id.removeImageButton);
viewHolder.productImageIv.setImageBitmap(images[position]);
checkForNullImages(viewHolder, position);
//Store the holder with the view
convertView.setTag(viewHolder);
viewHolder.removeImageIb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runOnUiThread (new Thread(new Runnable() {
public void run() {
images[position] = null;
viewHolder.productImageIv.setImageBitmap(images[position]);
notifyDataSetChanged();
//Does print this message, item is null, but image is still shown
Log.e("LogMSG", "item should be null " + getItem(position));
}
}));
}
});
}
return convertView;
}
And if relevant, here's my corresponding XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/android_custom_gridview_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
app:cardCornerRadius="10dp"
app:cardBackgroundColor="#color/white">
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
app:cardCornerRadius="10dp">
<ImageView
android:id="#+id/android_gridview_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#drawable/gradient_background"
android:scaleType="centerCrop" />
</android.support.v7.widget.CardView>
</android.support.v7.widget.CardView>
<ImageButton
android:id="#+id/addImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-30dp"
android:elevation="#dimen/standard_12"
android:background="#drawable/icon_add" />
<ImageButton
android:id="#+id/removeImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-30dp"
android:background="#drawable/icon_remove"
android:elevation="#dimen/standard_12" />
This is because your row view recycling is incorrect. You're not recycling the view with the following code:
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
// ...
}
return convertView;
}
because you're not using the previous convertView if it's not null.
So, change your code to something like this:
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.item_create_product_gridview_normal, parent, false);
//Set up viewholder
holder = new ViewHolder();
holder.productImageIv = (ImageView) convertView.findViewById(R.id.android_gridview_image);
holder.addImageIb = (ImageButton) convertView.findViewById(R.id.addImageButton);
holder.removeImageIb = (ImageButton) convertView.findViewById(R.id.removeImageButton);
// set click listener here.
// don't use runOnUiThread for click listener.
// bind the view here.
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// set the value for view here
holder.productImageIv.setImageBitmap(images[position]);
return convertView;
}

Can't set background color for GridView layouts

I've never worked with GridView on Android. I try to inflate my layout in a GridView, and i want to have different background for every layout. I can't set background color for each layout separately, everytime i get gray color for all layouts.
My XML code :
<RelativeLayout
android:layout_width="200dp"
android:layout_height="150dp"
android:id="#+id/back">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/imageView"
android:layout_marginTop="10dp"
android:src="#drawable/splashscreen"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Science"
android:textSize="15sp"
android:layout_marginTop="10dp"
android:id="#+id/categoryTextView"
android:layout_below="#+id/imageView"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Grid adapter :
public class CellAdapter extends BaseAdapter {
private Context context;
private LinkedList<CellGrid> list;
public CellAdapter(Context context, LinkedList<CellGrid> list){
this.context = context;
this.list = list;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = (View) inflater.inflate(
R.layout.grid_cell_layout, null);
}
convertView.setBackgroundColor(list.get(position).getBackground());
TextView categoryTextView = (TextView)convertView.findViewById(R.id.categoryTextView);
ImageView imageView = (ImageView)convertView.findViewById(R.id.imageView);
categoryTextView.setText(list.get(position).getText());
imageView.setImageResource(list.get(position).getImageId());
RelativeLayout relativeLayout = (RelativeLayout) convertView.findViewById(R.id.back);
Log.d("COLOR", Integer.toString(list.get(position).getBackground()));
return convertView;
}
}
If any specific color is not satisfied then you can set random bg to every view as :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// generate the random integers for r, g and b value
int r = rand.nextInt(255);
int g = rand.nextInt(255);
int b = rand.nextInt(255);
int randomColor = Color.rgb(r,g,b);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = (View) inflater.inflate(
R.layout.grid_cell_layout, null);
convertView.setBackgroundColor(randomColor);
}
Please try following code it helpful for you.
Replace your adapter code with following code
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = (View) inflater.inflate(
R.layout.grid_cell_layout, null);
}
Random rnd = new Random();
int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
convertView.setBackgroundColor(color);
TextView categoryTextView = (TextView)convertView.findViewById(R.id.categoryTextView);
ImageView imageView = (ImageView)convertView.findViewById(R.id.imageView);
categoryTextView.setText(list.get(position).getText());
imageView.setImageResource(list.get(position).getImageId());
RelativeLayout relativeLayout = (RelativeLayout) convertView.findViewById(R.id.back);
Log.d("COLOR", Integer.toString(list.get(position).getBackground()));
return convertView;
}
}
Feel free for comment if you have any issue
Use resources().getColor() to get color from list and set it as background
relativelayout.setBackgroundColor(getResources().getColor(list.get(position).getBackground()));
Here is my sample code..
**<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
android:orientation="vertical"
android:background="#color/dark_gray" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:background="#android:color/transparent"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:text="TextView"
android:textColor="#android:color/black"
android:textSize="13dp" />
**
Do you set color (AARRGGBB int value) or color resource (R.color.*)?
convertView.setBackgroundColor(list.get(position).getBackground());
There should be color in AARRGGBB format.
To get value from resources use:
context.getResources().getColor(R.color.your_color);

Listview sometimes null when I use gettag

I have a problem with my view in Android. I use a GridView with items inside it. Each item does have a name, button,description and icon. But each item also has a listview. When I click on the button I want to show the listview that is linked to that button.
On startup it works, but when I scroll up and down a few times my listview either doesn't show or it shows the wrong listview.
I have read alot of other questions and articles, but I cant find the thing I am doing wrong.
Also tried something like this but that still gives the same result
if (convertView == null){
holder = new new ListHolder();
convertView.setTag(holder);
}
else {
holder = (ListHolder) convertView.getTag();
}
The getView
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ListHolder holder;
HarmonicaItem harmonicaItem = ((MainActivity) context).getHarmonicaItems().get(position);
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
}
holder = new ListHolder();
holder.logo = (ImageView) row.findViewById(R.id.logo);
holder.line = (TextView) row.findViewById(R.id.line);
holder.button = (Button) row.findViewById(R.id.button);
holder.listView = (ListView) row.findViewById(R.id.subHarmonica);
holder.logo.setImageResource(harmonicaItem.logo);
holder.button.setText(harmonicaItem.title);
holder.button.setOnClickListener(onClickListener);
harmonicaItem.listView = holder.listView;
harmonicaItem.button = holder.button;
holder.listView.setTag(harmonicaItem);
holder.button.setTag(harmonicaItem);
row.setTag(holder);
return row;
}
The Model class
static class ListHolder {
ImageView logo;
TextView line;
Button button;
ListView listView;
}
How I retrieve the item
#Override
public void onClick(View v) {
HarmonicaItem item = (HarmonicaItem) v.getTag();
}
layout of item inside gridview:
<RelativeLayout
android:id="#+id/buttonLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:gravity="center_vertical|left"
android:paddingLeft="115dp"
android:paddingRight="10dp"
android:text="loop"
android:textColor="#android:color/black"
android:textStyle="bold"/>
<ImageView
android:id="#+id/logo"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp" />
<TextView
android:id="#+id/line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/button"
android:layout_alignBottom="#+id/button"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#+id/logo"
android:text="00:00"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/black"
android:textStyle="bold"/>
</RelativeLayout>
<ListView
android:id="#+id/subHarmonica"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/buttonLayout"
android:visibility="gone"/>
So a summary of my problem:
item.listView is sometimes null and sometimes the wrong listview.
My goal is to fill the listview and make it visible when you click the button.
What am I doing wrong?
Edit
Apparently I made a mistake in other code. When the listviews went back to gone I saved the listview. When I wanted it to show again it sometimes took the wrong list. So there is actually nothing wrong with the adapter.
Try this. Some issue in your code
1. You miss the else part
2.need to Set tag inside if condition
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ListHolder holder;
HarmonicaItem harmonicaItem = ((MainActivity) context).getHarmonicaItems().get(position);
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ListHolder();
holder.logo = (ImageView) row.findViewById(R.id.logo);
holder.line = (TextView) row.findViewById(R.id.line);
holder.button = (Button) row.findViewById(R.id.button);
holder.listView = (ListView) row.findViewById(R.id.subHarmonica);
holder.listView.setTag(harmonicaItem);
holder.button.setTag(harmonicaItem);
row.setTag(holder);
}else{
holder = (ListHolder)row.getTag();
}
holder.logo.setImageResource(harmonicaItem.logo);
holder.button.setText(harmonicaItem.title);
holder.button.setOnClickListener(onClickListener);
return row;
}
Edit:
I removed 2 lines of code in that is
armonicaItem.listView = holder.listView;
harmonicaItem.button = holder.button;
I think this is not needed. Try without this.
Plz update your getView method
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
{
holder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.list_row, null);
holder.logo = (ImageView) row.findViewById(R.id.logo);
holder.line = (TextView) row.findViewById(R.id.line);
holder.button = (Button) row.findViewById(R.id.button);
holder.listView = (ListView) holder.findViewById(R.id.subHarmonica);
holder.listView.setTag(harmonicaItem);
holder.button.setTag(harmonicaItem);
holder.setTag(holder);
}
else {
holder = (ListHolder)row.getTag();
}
holder.logo.setImageResource(harmonicaItem.logo);
holder.button.setText(harmonicaItem.title);
holder.button.setOnClickListener(onClickListener);
return convertView;
}

First progressBar in listview doesn't progress

I have a very bad issue.
I have a listview with an adapter.
public class MediaAdapter extends ArrayAdapter<Media> {
public MediaAdapter(Context context, Media[] items) {
super(context, R.layout.mediaitemlist, items);
}
/* private view holder class */
private class ViewHolder {
TextView media_name;
TextView media_path;
TextView media_version;
TextView media_type;
ProgressBar pb;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
View view = convertView;
if (view == null) {
view = (View)LayoutInflater.from(getContext()).inflate(R.layout.mediaitemlist, null);
holder = new ViewHolder();
holder.media_name = (TextView) view
.findViewById(R.id.media_name);
holder.media_path = (TextView) view
.findViewById(R.id.media_path);
holder.media_type = (TextView) view
.findViewById(R.id.media_type);
holder.media_version = (TextView) view
.findViewById(R.id.media_version);
holder.pb = (ProgressBar)view.findViewById(R.id.itemprogressdl);
view.setTag(holder);
//Maybe the problem is here ???????????
getItem(position).setmProgressBar((ProgressBar)view.findViewById(R.id.itemprogressdl));
} else {
holder = (ViewHolder) view.getTag();
}
Media rowItem = (Media) getItem(position);
holder.media_name.setText(rowItem.get_Name());
holder.media_path.setText(rowItem.get_Path());
holder.media_type.setText(rowItem.get_TypeString());
holder.media_version.setText("" + rowItem.get_Version());
rowItem.setmProgressBar(holder.pb);
return view;
}
}
Here, the mediaitemlist Layout :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:background="#drawable/listitembackground" >
<TextView
android:id="#+id/media_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#android:color/black"
android:textSize="25sp" />
<TextView
android:id="#+id/media_path"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/media_name"
android:textColor="#android:color/black"
android:visibility="invisible" />
<TextView
android:id="#+id/media_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:textColor="#android:color/black" />
<TextView
android:id="#+id/media_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginRight="20dp"
android:layout_toLeftOf="#+id/media_version"
android:textColor="#android:color/black" />
<ProgressBar
android:id="#+id/itemprogressdl"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/media_name"
android:layout_below="#+id/media_name"
android:layout_toLeftOf="#+id/media_version"
android:max="100"
android:visibility="invisible"
android:indeterminate="true"/>
</RelativeLayout>
The progressBar is an attribute of a media class. One Media class have is own progress according to his place in the listView.
But, all the progressBar attributes are good, except the first of the listView. If I click on the second or over, I can see the progressBar progresses, but not with the first.
So, why the first progressBar doesn't work and the next work?
If you need more code,comments or other, ask me.
try moving this line
getItem(position).setmProgressBar((ProgressBar)view.findViewById(R.id.itemprogressdl));
out of the if..else condition.
Try this answer:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
View view = convertView;
Media rowItem = (Media) getItem(position);
if (view == null) {
view = (View)LayoutInflater.from(getContext()).inflate(R.layout.mediaitemlist, null);
holder = new ViewHolder();
holder.media_name = (TextView) view
.findViewById(R.id.media_name);
holder.media_path = (TextView) view
.findViewById(R.id.media_path);
holder.media_type = (TextView) view
.findViewById(R.id.media_type);
holder.media_version = (TextView) view
.findViewById(R.id.media_version);
holder.pb = (ProgressBar)view.findViewById(R.id.itemprogressdl);
view.setTag(holder);
//Maybe the problem is here ???????????
getItem(position).setmProgressBar((ProgressBar)view.findViewById(R.id.itemprogressdl));
} else {
holder = (ViewHolder) view.getTag();
rowItem.setmProgressBar(holder.pb);
}
holder.media_name.setText(rowItem.get_Name());
holder.media_path.setText(rowItem.get_Path());
holder.media_type.setText(rowItem.get_TypeString());
holder.media_version.setText("" + rowItem.get_Version());
return view;
}

change order of object in row of listview programmaticaly

currently i have:
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="15:22:33 \nApr 13 1999"
android:textColor="#FFFFFFFF"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dip"
android:background="#drawable/incoming_message_buble"
android:paddingLeft="10dip"
android:text="Hello bubbles!"
android:textColor="#android:color/primary_text_light" />
and it work fine.
here is adapter code:
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.activity_sms_row_layout, parent, false);
}
wrapper = (LinearLayout) row.findViewById(R.id.wrapper);
OneComment coment = getItem(position);
countryName = (TextView) row.findViewById(R.id.comment);
countryName.setText(coment.comment);
countryName.setBackgroundResource(coment.left ? R.drawable.incoming_message_buble : R.drawable.outgoing_message_buble);
wrapper.setGravity(coment.left ? Gravity.LEFT : Gravity.RIGHT);
return row;
}
i have to change order, for gravity left, i need shown textview comment first, and textView1 second
for gravity right, keep xml setting.
please advise.
I suggest using multiple layouts rather than constantly reorganizing each row's layout. Override these two methods:
#Override
public int getItemViewType(int position) {
return getItem(position).left ? 0 : 1;
}
#Override
public int getViewTypeCount() {
return 2;
}
And modify your getView():
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(getItemViewType == 0) {
// Use the left layout
} else {
// Use the right layout
}
}

Categories