消失的图像ListView

时间:2016-01-28 15:14:29

标签: android listview android-arrayadapter android-listfragment

我的列表视图有问题。

在我的应用程序中有一个ListFragment,其中包含基本上是文本和图像的通知列表。

单击时,它们也可能被禁用。点击后,我将struct Notification的字段'active'设置为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();
    }
}

3 个答案:

答案 0 :(得分:0)

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

这可能就是你的问题所在。我建议在

上设置一个断点
imageView.setImageAlpha(0);

在图像消失之前查看它是否被触发。

另外,我假设您的Notification对象不是Android Notification对象?我无法在文档中找到getActive()方法。这种方法有什么作用?

答案 1 :(得分: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;

}

答案 2 :(得分:0)

适配器中的视图将被回收。意味着你使用imageAlpha = 0的项目结束,即使它们满足if语句:

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

以下是列表项目回收如何运作的图像:

http://romannurik.github.io/AndroidAssetStudio/index.html

来源:enter image description here(它还有关于lisviews的教程)

我还建议使用viewHolder方法(更快,更高效),谷歌有关它的讨论(http://android.amberfog.com/?p=296),你也可以使用Claud25提供的代码。

希望有所帮助:)