【问题标题】:Android ListView with Custom Adapter Has Visual Glitch带有自定义适配器的 Android ListView 有视觉故障
【发布时间】: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,即使它不能解决问题,但在使用最新技术时更容易找到帮助,因为大多数人都在使用它。

标签: android listview optimization android-listview android-cardview


【解决方案1】:

请使用 RecyclerView,它使用视图持有者模式来解决所有这些滞后问题

【讨论】:

    【解决方案2】:

    将您的实现从 ListView 更改为 RecyclerView。

    RecyclerView 是作为继承者添加到 android studio 中的 ViewGroup 的 GridView 和 ListView。这是对他们两个的改进,并且 可以在最新的 v-7 支持包中找到。它已创建 可以构建任何带有 XML 布局的列表作为项目 它可以在提高效率的同时进行大量定制 列表视图和网格视图。这种改进是通过回收 用户不可见的视图。例如,如果一个 用户向下滚动到项目 4 和 5 可见的位置; 项目 1、2 和 3 将从内存中清除以减少内存 消费。

    来自GeeksforGeeksPs:链接有很多解释、教程和代码...

    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
      }
      

      【讨论】:

      • 他稍后会添加卡片,使用空列表启动适配器绝对没有问题。
      猜你喜欢
      • 1970-01-01
      • 2015-08-22
      • 1970-01-01
      • 2013-05-21
      • 2014-09-06
      • 1970-01-01
      • 2020-02-12
      • 1970-01-01
      • 2012-01-04
      相关资源
      最近更新 更多