0

У меня проблема со списком.Исчезающие изображения ListView

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

Они также могут быть отключены при нажатии. При щелчке я устанавливаю поле «active» структуры Notification на false и вызывает метод NotifyDataSetChanged. Но когда я просматриваю его вверх и вниз, некоторые изображения исчезают и могут снова появляться снова. Но не тогда, когда я не прокручиваю его.

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

Вот некоторые из моего кода:

Пользовательские ArrayAdapter

public class NotificationsArrayAdapter extends ArrayAdapter<Notification> { 
    private final Context context; 
    private final String[] message_strings; 
    private final Drawable[] images; 
    private final LayoutInflater layoutInflater; 
    private ArrayList<Notification> items; 

    public NotificationsArrayAdapter (Context context, Resources resources, ArrayList<Notification> items) { 
    super(context, R.layout.customer_notifications_list_item, items); 
    this.context = context; 
    this.items = items; 
    this.message_strings = new String[] {"message1", "message2", "message3", "message4"}; 

    this.images = new Drawable[] {ContextCompat.getDrawable(context, R.drawable.notifications_blue_circle), 
       ContextCompat.getDrawable(context, R.drawable.notifications_red_circle), 
       ContextCompat.getDrawable(context, R.drawable.notifications_grey_circle), 
       ContextCompat.getDrawable(context, R.drawable.notifications_green_circle) 
     }; 

     this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 

     if (v == null) { 
      v = layoutInflater.inflate(R.layout.customer_notifications_list_item, parent, false); 
     } 

     Notification item = getItem(position); 

     if (item != null) { 
      TextView textView = (TextView) v.findViewById(R.id.notifications_list_item_text); 
      ImageView imageView = (ImageView) v.findViewById(R.id.notifications_list_item_image); 

      if (textView != null) { 
       if (item.getActive()) { 
        textView.setTextColor(Color.parseColor("#FFFFFF")); 
       } 
       else { 
        textView.setTextColor(Color.parseColor("#BBBBBB")); 
       } 
       textView.setText(message_strings[item.getType()]); 
      } 

      if (imageView != null) { 
       if (item.getActive()) { 
        imageView.setImageDrawable(images[item.getType()]); 
       } 
       else { 
        imageView.setImageAlpha(0); 
       } 
      } 
     } 

    return v; 
    } 
} 

Фрагмент:

public class CustomerNotificationsFragment extends ListFragment { 

    public CustomerNotificationsFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_customer_notifications, container, false); 

     ArrayList<Notification> notifications = new ArrayList<Notification>(); 
     for (int i = 0; i < 20; ++i) { 
      notifications.add(new Notification(1, "blabal")); 
     } 

     NotificationsArrayAdapter notificationsArrayAdapter = new NotificationsArrayAdapter(getActivity(), getResources(), notifications); 
     setListAdapter(notificationsArrayAdapter); 

     return view; 
    } 

    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 
     super.onListItemClick(l, v, position, id); 

     Notification item = (Notification) this.getListAdapter().getItem(position); 
     item.setActive(false); 

     ((ArrayAdapter) getListAdapter()).notifyDataSetChanged(); 
    } 
} 

ответ

0

Виды в адаптере перерабатываются. Значение Вы заканчиваете с использованием элементов с imageAlpha = 0, даже если они удовлетворяют, если заявление здесь:

if (viewHolder.imageView != null) { 
    if (item.getActive()) { 
     viewHolder.imageView.setImageDrawable(images[item.getType()]); 
    } 
    else { 
     viewHolder.imageView.setImageAlpha(0); 
    } 
} 

Вы должны изменить критические свойства в обеих частях заявления, из-за переработки. Таким образом, это должно быть, как:

if (viewHolder.imageView != null) { 
     if (item.getActive()) { 
      viewHolder.imageView.setImageAlpha(255); 
      viewHolder.imageView.setImageDrawable(images[item.getType()]); 
     } 
     else { 
      viewHolder.imageView.setImageAlpha(0); 
     } 
} 

Вот изображение того, как список пунктов утилизации работ:

enter image description here

Источник: http://android.amberfog.com/?p=296 (Это также есть учебник о lisviews)

Я также рекомендую пойти с подходом viewHolder (быстрее и эффективнее), об этом говорят google (https://youtu.be/wDBM6wVEO70), и вы также можете использовать код Claud25.

Надеюсь, это поможет :)

+0

Спасибо, это помогло, но есть еще одна вещь: когда я проверяю элемент и начинаю прокручивать, появляется только одно изображение и исчезает, все остальные в порядке. Он исчезает только тогда, когда список находится ниже определенного положения. Вы знаете, что может быть? – Daniil

+0

все еще есть что-то не так с вашим ответом: setImageAlpha находится в диапазоне 0..255, поэтому его следует вызывать с аргументом 255. Если у кого-то будет такая же проблема, он вообще не увидит картинку. – Daniil

+0

О, ты прав! Там :) – Nikiole91

0
if (imageView != null) { 
      if (item.getActive()) { 
       imageView.setImageDrawable(images[item.getType()]); 
      } 
      else { 
       imageView.setImageAlpha(0); 
      } 
     } 

Это, вероятно, где ваша проблема. Я бы предложил установить точку останова на

imageView.setImageAlpha(0); 

, чтобы узнать, не срабатывает ли оно до исчезновения изображения.

Кроме того, я предполагаю, что ваш объект Notification не является объектом Android Notification? Я не мог найти метод getActive() в документации. Что делает этот метод?

+0

Уведомление - это мой собственный класс, который просто содержит некоторые значения.Active - это булева константа, из которой getAlpha() является геттером. – Daniil

+0

setAlpha запускается только для щелкнутого элемента. Проверено это путем ведения журнала. – Daniil

0

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

Ваш getView в пользовательском адаптере будет выглядеть примерно так.

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    ViewHolder viewHolder; 

    if(convertView == null){ 

     convertView = LayoutInflater.from(context).inflate(R.layout.customer_notifications_list_item, parent, false); 

     viewHolder = new ViewHolder(); 

     viewHolder.textView = (TextView) convertView.findViewById(R.id.notifications_list_item_text); 
     viewHolder.imageView = (TextView) convertView.findViewById(R.id.notifications_list_item_image); 

     convertView.setTag(viewHolder); 
    } 
    else { 
     viewHolder = (ViewHolder) convertView.getTag(); 
    } 

    Notification item = getItem(position); 

    if (item != null) { 

     if (viewHolder.textView != null) { 
      if (item.getActive()) { 
       viewHolder.textView.setTextColor(Color.parseColor("#FFFFFF")); 
      } 
      else { 
       viewHolder.textView.setTextColor(Color.parseColor("#BBBBBB")); 
      } 
      viewHolder.textView.setText(message_strings[item.getType()]); 
     } 

     if (viewHolder.imageView != null) { 
      if (item.getActive()) { 
       viewHolder.imageView.setImageDrawable(images[item.getType()]); 
      } 
      else { 
       viewHolder.imageView.setImageAlpha(0); 
      } 
     } 
    } 

    return convertView; 
} 

static class ViewHolder { 
    protected TextView textView; 
    protected ImageView imageView; 

} 
Смежные вопросы