Android: when notifydatasetchanged is called on some devices, the image in listview flashes
As the title shows, on some devices, the image flashes when notifydatasetchanged is called
This is the getview method in my baseadapter subclass:
@Override
public View getView(int position, View convertView, ViewGroup arg2) {
String infService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li = (LayoutInflater)context.getSystemService(infService);
View v = arg1;
final ViewHolder holder;
if(v == null)
{
v = li.inflate(R.layout.row_history_settings, arg2, false);
holder = new ViewHolder();
holder.flag = (ImageView) v.findViewById(R.id.row_history_settings_image_flag);
holder.currency = (TextView) v.findViewById(R.id.row_history_settings_text_currency);
holder.tb = (ToggleButton) v.findViewById(R.id.row_history_settings_tb);
v.setTag(holder);
}
else
{
holder = (ViewHolder) v.getTag();
}
Account account = accounts.get(arg0);
int resID = enabled == true ? Utils.getFlagResIdForCurrency(account.currency()) : Utils.getFlagInactiveResIdForCurrency(account.currency());
if(resID != holder.resId)
{
holder.resId = resID;
holder.flag.setTag(resID);
new AsyncImageLoader(holder.flag, context).execute();
}
holder.currency.setText(account.currency());
if(currency!=null)
{
holder.tb.setChecked(currency.equals(account.currency()));
holder.tb.setEnabled(true);
}
else
{
holder.tb.setChecked(false);
holder.tb.setEnabled(false);
}
holder.tb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
currency = holder.currency.getText().toString();
notifyDataSetChanged();
}
});
Utils.enableDisableView(v, enabled);
return v;
}
Each time you click togglebutton, the holder.flag image flashes for a different short time. This seems to only happen on devices such as Sony Xperia u or HTC Desire Z
This is my row 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="@dimen/row_list_standard_height"
android:background="@drawable/list_item_background"
android:gravity="center_vertical"
android:orientation="horizontal" >
<ImageView
android:id="@+id/row_history_settings_image_flag"
android:layout_width="@dimen/row_list_flag_width"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:adjustViewBounds="true"
android:contentDescription="@string/none"
android:src="@drawable/flag_pln" />
<com.aliorbank.components.customfont.CustomFontTextView
android:id="@+id/row_history_settings_text_currency"
style="@style/textViewUniversalRobotoLightBlack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="left|center_vertical"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/row_history_settings_image_flag"
android:text="@string/universal_currency_pln"
android:textSize="@dimen/font_size_big" />
<ToggleButton
android:id="@+id/row_history_settings_tb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:background="@drawable/btn_radio_standard"
android:checked="true"
android:text="@string/none"
android:textOff="@string/none"
android:textOn="@string/none" />
</RelativeLayout>
And my asyncimageloader class:
public class AsyncImageLoader extends AsyncTask<Object, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private Context context;
private int resId;
public AsyncImageLoader(ImageView imv, Context context)
{
imageViewReference = new WeakReference<ImageView>(imv);
this.context = context;
this.resId = (Integer)imv.getTag();
}
@Override
protected Bitmap doInBackground(Object... arg0) {
return BitmapFactory.decodeResource(context.getResources(), resId);
}
@Override
protected void onPostExecute(Bitmap result) {
if (imageViewReference != null && result != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(result);
}
}
}}
In my opinion, the convertview does not correspond to the position in the getview method. Is there a way to obtain the convertview corresponding to the row position of the listview? Or maybe there's another solution?
resolvent:
You should cancel asyncimageloader. Exe from the recycled view
The goal you want to achieve is really difficult. You can find a very detailed example here: http://developer.android.com/training/displaying-bitmaps/display-bitmap.html.
Unless you really want to achieve this goal in your life, a good choice is to use a library
Here are some options:
>Volleyball and its networkimageview > robospice UI spicelist module
I think ordinary goods are like this lib. Of course, there are even other options
PS: I must say I prefer the second option, but as a contributor to robospice, I may not be so fair;)