Android: изображението в списъчен изглед трепти, докато извиквате notifyDataSetChanged на някои устройства

както в заглавието, на някои устройства изображенията трептят, докато се извиква notifydatasetchanged.

Ето моя метод getView от моя подклас на BaseAdapter:

@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;
}

Изображението на holder.flag трепти за различен кратък период от време всеки път, когато щракна върху бутона за превключване. Това изглежда се случва само на някои устройства като Sony Xperia U или HTC Desire Z.

Ето моето оформление на реда:

<?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>

и моя клас AsyncIMageLoader:

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);
        }
    }
}}

Струва ми се, че convertView не съответства на позицията в метода getView. Има ли някакъв начин да получите convertView, който съответства на позицията на реда на listview? Или може би има друго решение?


person Marcin Szulc    schedule 25.09.2013    source източник


Отговори (1)


Трябва да отмените AsyncImageLoader от изглед, който е рециклиран.

Това, което се опитвате да постигнете, е наистина трудно изпълнимо. Можете да намерите много подробен пример тук: http://developer.android.com/training/displaying-bitmaps/display-bitmap.html.

Добър вариант, освен ако наистина искате да сте постигнали това в живота си, е да използвате библиотека.

Ето някои опции:

Вярвам, че Common's ware също е като библиотека. И със сигурност има дори други опции.

PS: Трябва да кажа, че предпочитам втория вариант, но като сътрудник на RoboSpice може да не съм толкова честен;)

person Snicolas    schedule 25.09.2013
comment
Благодаря за вашият отговор! Опитвах се да следвам developer.android.com/training/displaying-bitmaps / и просто копирах всички необходими методи в моя адаптер, но има един проблем с final AsyncDrawable asyncDrawable = new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);. Изглежда, че трябва да има поставен контейнер за изображение. - person Marcin Szulc; 25.09.2013
comment
Така или иначе ме насочи в правилната посока и сега изглежда работи! Благодаря! - person Marcin Szulc; 25.09.2013