消失的图像 ListView
Disappearing images ListView
我的列表视图有问题。
在我的应用程序中有一个 ListFragment
,其中包含通知列表,这些通知基本上是文本和图像。
它们也可能在单击时被禁用。单击时,我将结构 Notification
的字段 'active' 设置为 false 并调用 NotifyDataSetChanged
方法。但是当我上下滚动它时,一些图像消失并可能再次出现。但不是当我不滚动它时。
所有图片都在资源中,我从未设置列表项的可见性。
这是我的一些代码:
自定义数组适配器
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();
}
}
if (imageView != null) {
if (item.getActive()) {
imageView.setImageDrawable(images[item.getType()]);
}
else {
imageView.setImageAlpha(0);
}
}
这可能就是您的问题所在。我建议在
上设置一个断点
imageView.setImageAlpha(0);
看看它是否在图像消失之前被触发。
此外,我假设您的 Notification 对象不是 Android Notification 对象?我在文档中找不到 getActive() 方法。这个方法有什么作用?
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;
}
适配器中的视图被回收。这意味着您结束使用 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://android.amberfog.com/?p=296(里面还有lisviews的教程)
我还推荐使用 viewHolder 方法(更快更高效),有一个 google 讨论它 (https://youtu.be/wDBM6wVEO70),您也可以使用 Claud25 提供的代码。
希望对您有所帮助:)
我的列表视图有问题。
在我的应用程序中有一个 ListFragment
,其中包含通知列表,这些通知基本上是文本和图像。
它们也可能在单击时被禁用。单击时,我将结构 Notification
的字段 'active' 设置为 false 并调用 NotifyDataSetChanged
方法。但是当我上下滚动它时,一些图像消失并可能再次出现。但不是当我不滚动它时。
所有图片都在资源中,我从未设置列表项的可见性。
这是我的一些代码:
自定义数组适配器
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();
}
}
if (imageView != null) {
if (item.getActive()) {
imageView.setImageDrawable(images[item.getType()]);
}
else {
imageView.setImageAlpha(0);
}
}
这可能就是您的问题所在。我建议在
上设置一个断点imageView.setImageAlpha(0);
看看它是否在图像消失之前被触发。
此外,我假设您的 Notification 对象不是 Android Notification 对象?我在文档中找不到 getActive() 方法。这个方法有什么作用?
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;
}
适配器中的视图被回收。这意味着您结束使用 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://android.amberfog.com/?p=296(里面还有lisviews的教程)
我还推荐使用 viewHolder 方法(更快更高效),有一个 google 讨论它 (https://youtu.be/wDBM6wVEO70),您也可以使用 Claud25 提供的代码。
希望对您有所帮助:)