问题
I have a customized SimpleCursorAdapter that gets information from a database. If one value is 1 I color the background of an ImageView, if it's 0 I don't color it. When the ListView is loaded everything is correct but then if I scroll the items in the list are get the image colored wrong.
============Just loaded============ After one scroll up and down====
I know about ListView recycling and that when one item is out of the screen it's resources are released, but I don't get why when they get back to the screen are loaded wrong. I got it working simply setting the ImageView color to transparent when I don't want it colored: is this workaround the only way to make it work right?
This is my relevant code:
RecipeCursorAdapter.java
public class RecipeCursorAdaptor extends SimpleCursorAdapter {
private final Context mContext;
private final int mLayout;
private final Cursor mCursor;
private final LayoutInflater mLayoutInflater;
public CustomCursorAdaptor(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.mLayout = layout;
this.mContext = context;
this.mCursor = c;
this.mLayoutInflater = LayoutInflater.from(mContext);
}
private final class ViewHolder {
TextView txt_title;
TextView txt_time;
TextView txt_difficulty;
ImageView img_color;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (mCursor.moveToPosition(position)) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = mLayoutInflater.inflate(mLayout, null);
viewHolder = new ViewHolder();
viewHolder.img_color = (ImageView) convertView.findViewById(R.id.ricettaColore);
viewHolder.txt_title = (TextView) convertView.findViewById(R.id.ricettaTitolo);
viewHolder.txt_time = (TextView) convertView.findViewById(R.id.ricettaTempo);
viewHolder.txt_difficulty = (TextView) convertView.findViewById(R.id.ricettaDifficolta);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
String title = mCursor.getString(1);
String time = mCursor.getString(2);
String difficulty = mCursor.getString(3);
int vegetarian = mCursor.getInt(4);
viewHolder.txt_title.setText(title);
viewHolder.txt_time.setText(time);
viewHolder.txt_difficulty.setText(difficulty);
if(vegetarian == 1)
viewHolder.img_color.setBackgroundColor(0xff669900);
/* Adding these two lines it works properly
else
viewHolder.img_color.setBackgroundColor(0x00000000);
*/
}
return convertView;
}
list_ricette.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
android:id="@+id/ricettaColore"
android:layout_width="5dip"
android:layout_height="45dip"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:contentDescription="Ricetta vegetariana" />
<TextView
android:id="@+id/ricettaTitolo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_toRightOf="@+id/ricettaColore"
android:scrollHorizontally="false"
android:singleLine="true"
android:text="Titolo Ricetta"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/ricettaDifficolta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/ricettaTitolo"
android:layout_below="@+id/ricettaTitolo"
android:scrollHorizontally="false"
android:singleLine="true"
android:text="Difficoltà"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#A1A1A1" />
<TextView
android:id="@+id/ricettaTempo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/ricettaDifficolta"
android:layout_alignParentRight="true"
android:layout_below="@+id/ricettaTitolo"
android:gravity="right"
android:text="Tempo"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#A1A1A1" />
回答1:
You'll want to make your ViewHolder class static and create a static int array inside that view holder class. In the getView you should set that array with your value from the database and also use that array to set the row like you want it.
This is how I managed to keep checkboxes correct in an ExpandableListView:
static class ViewHolder {
CheckBox check;
static boolean[][] bool = new boolean[parentCounter][childCounter];
public static void setChecked(int parent, int child, boolean value) {
bool[parent][child] = value;
}
public static boolean getChecked(int parent, int child) {
return bool[parent][child];
}
}
It's the same concept.
来源:https://stackoverflow.com/questions/15900534/cursoradapter-autoupdates-images