带有自定义适配器的 Android ListView 有视觉故障
Posted
技术标签:
【中文标题】带有自定义适配器的 Android ListView 有视觉故障【英文标题】:Android ListView with Custom Adapter Has Visual Glitch 【发布时间】:2020-01-31 16:41:41 【问题描述】:我是 android 编程新手,正在尝试弄清楚如何优化我的 ListView 适配器。我编写了一个自定义适配器来将 CardViews 添加到我的 ListView:
public class CardAdapter extends BaseAdapter
private final ArrayList<CardView> cards = new ArrayList<CardView>();
private Context context;
public CardAdapter( Context context )
this.context = context;
public void add( CardView view )
cards.add( view );
@Override
public int getCount()
return cards.size();
@Override
public int getViewTypeCount()
return getCount();
@Override
public int getItemViewType(int position)
return position;
@Override
public Object getItem(int i)
if( i >= cards.size() || i < 0 )
return null;
return cards.get( i );
@Override
public long getItemId(int i)
return cards.get(i).getId();
@Override
public View getView(int position, View view, ViewGroup viewGroup)
if( view == null )
view = (CardView) getItem( position );
return view;
MainActivity 类似于:
public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView list = findViewById(R.id.notesList);
CardAdapter adapter = new CardAdapter(getBaseContext());
adapter.add( makeCard() );
// repeat making cards however many times...
list.setAdapter(adapter);
private CardView makeCard()
CardView card = new CardView(this);
// Do some things to customize the CardView
return card;
现在看来,Android 正在尝试回收视图,但做得很糟糕。最初页面看起来不错,但是当我开始滚动时,卡片开始在屏幕上移动,间距发生变化,卡片开始重叠等等。。
请注意,我只滚动了几秒钟,这不是逐渐变化的,卡片有点像在屏幕上“跳跃”。到目前为止,我想出的唯一解决方案是将我的 getView
更改为:
@Override
public View getView(int position, View view, ViewGroup viewGroup)
return (CardView) getItem(position);
这很有效,但即使加载大约 10 个项目也很慢,而且滚动滞后。
【问题讨论】:
请发布适配器 xml 文件。 @Chintan 我不确定你在问什么,你的意思是 activity_main.xml 吗? 您的activity_main.xml 和您的卡片xml 可能有助于找到问题,但我会先尝试RecyclerView。 @RicardoA。是的,我稍后会在 recyclerview 上试一试。卡片是通过代码创建的,没有对应的 XML,这会导致什么问题吗? Activity_main 只是一个包含列表视图的线性布局。 不,那些代码可能没问题,问题应该是您的适配器或只是 ListView 本身的实现。正如 ghazanfar ali 试图解释的那样,RecyclerView 是专门为解决这种情况而创建的。而且 ListView 已经过时了,所以你真的应该换成 RecylerView,即使它不能解决问题,但在使用最新技术时更容易找到帮助,因为大多数人都在使用它。 【参考方案1】:请使用 RecyclerView,它使用视图持有者模式来解决所有这些滞后问题
【讨论】:
【参考方案2】:将您的实现从 ListView 更改为 RecyclerView。
RecyclerView 是作为继承者添加到 android studio 中的 ViewGroup 的 GridView 和 ListView。这是对他们两个的改进,并且 可以在最新的 v-7 支持包中找到。它已创建 可以构建任何带有 XML 布局的列表作为项目 它可以在提高效率的同时进行大量定制 列表视图和网格视图。这种改进是通过回收 用户不可见的视图。例如,如果一个 用户向下滚动到项目 4 和 5 可见的位置; 项目 1、2 和 3 将从内存中清除以减少内存 消费。
来自GeeksforGeeks。 Ps:链接有很多解释、教程和代码...
RecyclerView 是专门为解决您遇到的问题而创建的。它比 ListView 有很多改进,比如更少的内存消耗、更少的滞后、更好的滚动...
【讨论】:
【参考方案3】:好吧,太简单了
首先记住你必须传递你想在适配器中使用的东西,但现在你只需将一个(this)传递给这个适配器。 为您的构造函数使用下面的代码。
有良好的编码。
private final ArrayList<CardView> cards = new ArrayList<CardView>();
private Context context;
public CardAdapter( Context context , ArrayList<CardView> cards)
this.context = context;
this.cards =cards
【讨论】:
他稍后会添加卡片,使用空列表启动适配器绝对没有问题。以上是关于带有自定义适配器的 Android ListView 有视觉故障的主要内容,如果未能解决你的问题,请参考以下文章
带有过滤器 Android 的自定义 Listview 适配器
Android ListView 和带有 ViewHolder 的自定义适配器