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 мигает в течение короткого периода времени каждый раз, когда я нажимаю toggleButton. Это происходит только на некоторых устройствах, таких как 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, который соответствует позиции строки списка? Или может есть другое решение?


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


Ответы (1)


Вы должны отменить AsyncImageLoader из представления, которое было переработано.

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

Хорошим вариантом, кроме тех случаев, когда вы действительно хотите добиться этого в своей жизни, является использование библиотеки.

Вот несколько вариантов:

Я также считаю, что общая продукция является такой же библиотекой. И наверняка есть еще другие варианты.

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