更新适配器项目,在 getview() 上添加动态可绘制对象以显示错误的数据



我有一个列出我的项目的自定义适配器。 在每个项目中,我检查数据库并用颜色画一些圆圈。

正如您在代码中看到的,我检查convertView==null是否定义了新的 viewHolder 并绘制我的项目。 但是当我非常快速地滚动列表视图时,每个绘制的数据(不是标题和文本)都显示错误!
如何在不显示错误数据的情况下管理动态视图创建?!

更新

这是我的尝试:

  1. 我使用 ui-thread 更新我的列表,但结果相同,数据绘制出错。
  2. 第二秒内,我尝试使用我的对象加载所有数据,这样就无需在适配器中检查 db。 但它的问题仍然存在...
  3. 最后,我创建了HashMap<key,LinearLayout>并使用其项目的 id 缓存每个绘制的布局。因此,如果在我从 HashMap 加载其视图之前绘制它,并且每个动态布局将只创建一次。但它仍然在快速滚动时显示错误数据!真的不知道下一步该怎么做!

    @Override public View getView(final int position, View convertView, ViewGroup parent) {

        final ViewHolder viewHolder;
        final MenuStructureCase item = getItem(position);
            if (convertView == null) {
                viewHolder = new ViewHolder();
                convertView = this.mInflater.inflate(R.layout.fragment_menu_item, null);
                viewHolder.menu_title = (TextView) convertView.findViewById(R.id.menu_title);
                viewHolder.tag_list_in_menu_linear_layout = (LinearLayout) convertView.findViewById(R.id.tag_list_in_menu_linear_layout);
                viewHolder.menu_delete = (ImageButton) convertView.findViewById(R.id.image_button_delete);
                importMenuTags(viewHolder, getItem(position), viewHolder.tag_list_in_menu_linear_layout);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            viewHolder.menu_title.setText(item.getTitle());
    
        }
        return convertView;
    }
    

这是importMenuTags():

   private void importMenuTags(ViewHolder viewHolder, MenuStructureCase item, LinearLayout layout) {

        List<String> tags = db.getMenuTags(item.getTitle());  //this present list of string that contain my tags
        for (String tag : tags) {
            Drawable drawable = getContext().getResources().getDrawable(R.drawable.color_shape);
            drawable.setColorFilter(Color.parseColor(each_tag_color), PorterDuff.Mode.SRC_ATOP);
            RelativeLayout rl = new RelativeLayout(getContext());
            LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            lparams.setMargins(15, 15, 15, 15);
            lparams.width = 50;
            lparams.height = 50;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                rl.setBackground(drawable);
            } else {
                rl.setBackgroundDrawable(drawable);
            }
            rl.setLayoutParams(lparams);
            layout.addView(rl);
        }
    }
您必须

在初始化之前从数据库中选择数据adapter。因此

getItem(position) 

将返回已经"就绪"的项目对象。

不应将值设置为在内部Views

if (convertView == null) {
    ...
}

此代码仅用于viewHolder初始化。如果null convertView则创建一个新标记或将其读取为标记。设置viewHolder初始化后必须执行的值,实际上是设置标题的位置。但是为了提高性能,您不应该在 getView 的每一步都从 db 中选择值。您必须准备好所有内容(已选择)。

你可以这样做:

首先在适配器类中创建方法

public void updateNewData(List<MenuStructureCase> newList){
   this.currentList = newList;
   notifyDataSetChanged();
}

现在,每当您想要更新列表视图时,请调用上述方法。

如何使用自定义适配器的对象进行调用:

mAdapter.updateNewData(YourNewListHere);

希望这对您有所帮助。

  1. 呈现数据需要时间,并且可能是导致快速滚动时出现问题的原因。

  2. 您可以重新滚动(如Gmail:使用拉取刷新),以便一次在列表视图中处理较少的数据量。

  3. 使用回收器视图而不是列表视图以获得更好的性能

  4. 列表视图在滚动时重新创建视图。

也许您可以解释更多关于您的问题,然后我们可以相应地提供输入。

最新更新