首页 > 其他分享 >安卓-RecyclerView

安卓-RecyclerView

时间:2023-01-21 00:11:26浏览次数:33  
标签:ViewHolder int 安卓 viewitem RecyclerView public getLayoutPosition

RecyclerView是ListView的升级版,与ListView相比使用更方便效率更高

这里直接借鉴Android群英传的例子来进行说明

一、使用RecyclerView.Adapter进行管理RecyclerView的viewitem进行循环利用viewitem

1、我们新建一个类RecyclerAdapter来继承RecyclerView.Adapter并实现3个接口

public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)

 public void onBindViewHolder(@NonNull ViewHolder holder, int position)

public int getItemCount()

 

onCreateViewHolder用来创建ViewHolder对象,并将对应的view设置给ViewHolder;

onBindViewHolder用来设置当前传进来的holder管理的view

getItemCount返回当前的RecyclerView一共有多少个viewitem

注意:

1、当我们调试的时候会发现onCreateViewHolder只在初始化的时候会调用,在滑动或者增删操作的时候均不会再调用该函数

2、当我们在滑动或者增删操作的时候均会调用该函数

出现第一点的原因是因为RecyclerView可以克隆多个,只需要在初始化的时候调用一个ViewHolder即可

出现第二点的原因是因为viewitem是循环利用,所以当某个item即将出现或者出现的时候需要从cache中拿出一个viewitem来进行设置对应的view内容

 

二、重写RecyclerView.ViewHolder

重写ViewHolder并支持对应的点击监听事件

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public TextView textView;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = (TextView) itemView;
            textView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (itemClickListener != null) {
                itemClickListener.onItemClick(v, getLayoutPosition());
            }
        }
    }

如上所示,在点击viewitem的时候则会调用onClick

这里在使用getLayoutPosition的时候发现还有一个接口getAdapterPosition

在正常的点击事件中,这两个函数所返回的positon是一样的;那么他们不同的地方是什么呢?

具体区别就是adapter和layout的位置会有时间差(<16ms), 如果你改变了Adapter的数据然后刷新视图, layout需要过一段时间才会更新视图, 在这段时间里面, 这两个方法返回的position会不一样.

getLayoutPosition顾名思义为界面显示的位置

这里先做个实验,假设有3个item,然后点击第一个item,onClick的代码如下所示:

        public void onClick(View v) {
            if (mItemClickListener != null) {
                for (int i = 0; i < 3; ++i) {
                    int position = getLayoutPosition();
                    System.out.println("onclick:" + position + ", adapter:" + getAdapterPosition());
                    if (position > 0) {
                        mData.remove(position);
                        notifyDataSetChanged();
                    }
                }
            }
        }

该for是模拟某个viewitem被连续点击3次,该log如下所示,打印完这些log之后崩溃

onclick:1, adapter:1
onclick:1, adapter:-1
onclick:1, adapter:-1

为何getLayoutPosition一直返回1,而getAdapterPosition在删除之后界面虽然还没刷新但是已经返回-1了

要查看究竟我们可以看下这两个函数的实现

getLayoutPosition:

        public final int getLayoutPosition() {
            return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition;
        }

只是简单的判断当前的位置,没有判断当前viewitem所在的状态

getAdapterPosition:

        public final int getAdapterPosition() {
            if (mOwnerRecyclerView == null) {
                return NO_POSITION;
            }
            return mOwnerRecyclerView.getAdapterPositionFor(this);
        }


    int getAdapterPositionFor(ViewHolder viewHolder) {
        if (viewHolder.hasAnyOfTheFlags(ViewHolder.FLAG_INVALID
                | ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)
                || !viewHolder.isBound()) {
            return RecyclerView.NO_POSITION;
        }
        return mAdapterHelper.applyPendingUpdatesToPosition(viewHolder.mPosition);
    }

如上所示,会判断当前的viewholder是否被标记为删除的状态,如果标记为删除的状态则返回NO_POSITION 即-1

所以使用的时候可以根据自己的需要看是要用getLayoutPosition还是getAdapterPosition

 

标签:ViewHolder,int,安卓,viewitem,RecyclerView,public,getLayoutPosition
From: https://www.cnblogs.com/czwlinux/p/17063424.html

相关文章

  • 安卓 一加7t禁止google play服务
    禁用的命令adbshellpmdisable-usercom.google.android.gmsadbshellpmdisable-usercom.google.android.partnersetupadbshellpmdisable-usercom.google.andr......
  • 安卓包在真机上安装时的“风险提示”问题
    1)安卓包在真机上安装时的“风险提示”问题​2)iOS下AssetBundle的加载疑问3)特效用粒子系统,模拟器里出现花屏问题4)IL2CPP编译的Protobuf,反射类运行时报空这是第321篇UWA技......
  • 安卓 Jetpack学习笔记
    ViewModel需要注意的是,在使用ViewModel的过程中,千万不要将任何类型的Context或带有Context引用的对象传入ViewModel,这可能会引发内存泄漏。如果一定要在ViewModel中使......
  • Scrollview实现滑动停止监听,Scrollview嵌套Recyclerview获取滑动停止时当前可见positi
    某些场景或者框架限制的情况下,使用了Scrollview嵌套Recyclerview布局此时会有问题1、滑动时Recyclerview被禁用了滑动事件,无法监听滑动事件2、Recyclerview被重......
  • 安卓的通知管理
    最近,安卓13已经发布了。安装13显著的新特质仍然是聚焦与个人隐私保护和安全。通知栏消息一直是App和用户沟通的有效渠道。在Android13之前,App只需要使用NotificationMana......
  • Recyclerview列表视频自动播放方案
    列表中自动播放视频,常规方案是在每个xml中写入视频布局,然后在滑动时获取当前的下标,播放此下标的视频弊端:播放容易出错,需要精准控制好停止播放操作,并且适配器中容易触发......
  • 适合编程初学者的开源项目:小游戏2048(安卓Compose版)
    目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。2048游戏规则一共16个单元格,初始时由2或者4构成。1、手指向一个方向滑动,所有格子会向那个方向运动。2......
  • 漏洞免费实战部分-安卓应用漏洞学习case5
    前期回顾漏洞免费实战部分-安卓应用层getLastPathSegment函数问题漏洞实战部分2-安卓应用ZipEntry对象问题实战漏洞实战部分3-ContentProvider组件的openFile接口问题......
  • 安卓学习1--基础属性详解
    基础属性详解11.layout_width:组件的宽度232.layout_height:组件的高度453.id:为TextView设置一个组件id674.text:设置显示的文本内容895.textCo......
  • 安卓学习3--实现跑马灯效果的TextView
    实现跑马灯效果的TextView11.android:singleLine:内容单行显示232.android:focusable:是否可以获取焦点453.android:focusableinTouchMode:用于控制视图在触摸模式......