「RecyclerView中的位置」你真的会正确获取Item的位置么?

关于Position

咱们在运用运用 RecyclerView 的时分,总是不可避免的需求知道其 ItemView 的方位以完结各式各样的需求:

  • 设置点击作业:咱们需求Item地点的方位,获得View对应的相关数据信息,然后完结点击的交互操作。比如一个产品列表,点击产品谷歌空间的Item时,咱们只要知道对应Item的方位,才华拿到Item的数据信息(比如产品ID)然后跳转至正确的产品概略页面。
  • 翻滚列表至指源码精灵源码之家的Item方位:这种场景常被应用于Recycler阿里巴巴1688货源批发官网View的Item选中态发生变化时,翻滚RecyclerView的方位,使得当时选中的Ite谷歌m能被用阿里云盘户可见。此时咱们需知道Item相关于RecyclerView的方位,才有或许翻滚RecyclerView至正确的方位。

已然方位关于咱们日常开发这么重要,那么RecyclerView必定给咱们供应了获取方谷歌卫星地图位的API。没错,Rec开源我国yclerView是供应了获取方位的办法,还不止一种:

  • o开源代码网站githubnBindViewHolder(holder: ViewHolder, position: Int)谷歌安装器
  • getAdapterPosition
  • getBindingAdapterPosition
  • getAbsoluteAdapterPosition
  • get源码之家Layo源码编辑器手机版下载utPosition

你确认你知道他开源众包们的详细意义、运用场景以及他们之间的差异开源阅览app下载安装么?

onBindViewHo谷歌浏览器下载lder 中的 position 参数

一般咱们会在onBindViewHolder中经过po阿里云邮箱个人版stion参数绑定 data 和 View,像下面这样:

overridefunonBindViewHolder(holder:NumberHold谷歌三件套er,positio嵌套函数n:Int){
holder.tvNumber阿里.text="Position:$嵌套查询sql句子{list[position]}"
}

很显嵌套查询sql句子然,这么做没有任何问题(保命)。

可是假定在这儿运用position参数来处理点击作业就会有点不合适了,咱们在上述的代码中加一行代码:

overridefunonBindViewHolder(holder:NumberH嵌套结构older,position:Int){
holder.tvNumb开源众包er.text="源码编辑器手机版下载Position:${list[position]}"
holder.itemView.setOnClickListener{
Toast谷歌商店.makeText(it.conte阿里云盘xt,"谷歌点击了:${list[position]}",Toast.LENGTH_SHORT).show()
}
}

然后在页面中增加一个“-1”的按钮,功用源码编辑器也很简单:移除列表的第一项数据,代码如下:

funremoveFirstItem(){
list.removeAt(0)
notifyItemRemoved(0)
}

咱们来运转下看看作用:

「RecyclerView中的方位」你真的会正确获取Item的方位么?

能够看到,假定代开源众包码按照咱们预期那样,应该是点嵌套循环击哪个方位,就弹出那个方位的position的toast,可是当咱们源码是什么意思调用removeFirstItem办法移除列表的第一个item后,就源码精灵会呈现 item 和 position 对不上号的状况(点击了postion:1弹出的toast闪现点击了:2),这便是在onBindViewHolder中直接运用阿里巴巴position参数设置点击作业或许阿里拍卖引发的问题。谷歌商店

WHY?

其实原因很简单:运用notifyItem*()此类办法来删去开源阅览/增加/更改RecyclerV源码是什么意思iew的数据中的任何一条数谷歌商店据时,谷歌卫星地图RecyclerView并不会调用全部Item的onBindViewHolder办法更新item的方位,它只会更新notifyItem*()的方位,所以导致了闪现的数据和实在的数据 Position 对应不上的问题。

其实阿里供应链在官方开源矿工的注释中也额定强调了这点(注释很重要⚠️):

Note that unlike {@link android.widget.ListView}, RecyclerVie开源阅览app下载安装w will not call this method again if the position of the item changes in the data set unless the item itself is invalidated or the new position cannot be determined. For this reason, you should only u谷歌浏览器下载se thepositionparameter while acquiring the r阿里elated data item inside this method and should not keep a copy o嵌套if函数f it. If you nee嵌套d the position of an item l开源节流ater on (e.g. in a click list源码是什么意思ener), use {@link ViewHolder#getAdapterPosition()} which w谷歌商店ill have the updated adapter position.

怎样处理这个问题呢?其实源码的注释也给了处理办法了(嵌套查询sql句子注释很重要⚠️阿里旺旺),运用getAdapterPosition

getAdapterPosition

ViewHolder为咱们供应了 getAdapterP开源代码网站githubosition 办法来获取 ViewHolder 的方位阿里拍卖。该办法嵌套函数总是阿里巴巴1688货源批发官网回来 ViewHolder 最新的方位,也就意味着运用该办法,即使调用notifyItem*()此类办法来删去/增加/更改 Re嵌套查询sql句子cyclerView 的数据,该办法回来的方位也嵌套if函数能保证获取的Position是正确的。感兴趣的能够跟上面的写法比照一下看看作用 ~

作业处理了…么?

假定你看完我上一段的处理办法刻不容缓的打开了Android Studio去验证getAdapte阿里旺旺rPositio阿里巴巴股票n是否真的那么有效,那我先开源矿工要夸夸你,终究

纸上得来终觉浅,绝知此事要躬行。

所以你必定也知道了我要说什么了:getAdapter阿里云盘Position()谷歌地球嵌套路由抛弃了,官网对此也有阐明(官网很重要⚠️):

「RecyclerView中的方位」你真的会正确获取Item的方位么?

用我那糟糕的英开源众包语大致翻译一下,便是开源觉得这个办法在 Adapter 嵌套Adapter 的状况下会带来歧义,推荐你考虑运用getBindingAdapterPosition或许ge源码本钱tAbsoluteAdapterPosition这两个办法。

相信你刚看完阿里巴巴1688货源批发官网这段解说的时分,必定是像我相同更懵逼了:我原本只想知道为啥弃用getAdapterPo谷歌浏览器sition(),这家伙倒好,又给我整出来俩办法,还歧源码编辑器义,等等…什么是 Ad阿里拍卖apter 嵌套 Adapter?好开源阅览app下载安装家伙,现在 Adapter 还能够嵌套了么阿里云邮箱个人版

你甭说,还真能够。假定你刚好运用过阿里开源vLayout,就必定不会对 Adapter 嵌套 Adapter 的用法感到陌生。咱们都知道关于源码之家Androi源码之家d来说,杂乱的Feed流页面,咱们根柢都是经过RecyclerView的多款式布局来完结,经过重写A阿里巴巴1688货源批发官网dapter的getItemViewType来差异不同的款式,完结不同的UI逻辑,长久以来一直如此。

开源我国来如此,便对么?

这种长久以来的写法,最大的问题便是将不同款式类型的布局耦合在了同一个Adapter中,跟着事务的迭代,这个耦合的Adapter很有或许变得反常臃肿,并且这种写法要时间留意数据的处理要差异ViewType,给日后的保护带来极大的应战。有没有更好的做法呢?

嵌套函数于以上问题,阿里给出了vLayout库来处理,这儿就不打开讲了,由于——它中止保护了。谷歌大概是看到了开发者面对这种杂乱页面开发和保护时脸上的源码本钱苦楚面具阿里巴巴1688货源批发官网,所以他们推出了MergeAdapter这个玩意,简单来说,他就像一个容器,里面能够增加多个Adapter,然后将MergeAdapter设置为RecyclerV嵌套函数iew的Adapter,然后轻松完结多款式布局的效开源众包果。这便是谷歌官网所写的 Adapter 嵌套 Adapter状况:MergeAdapter 里 或许会包含了 多个开发者写的Adapter。

这种状况下,咱们假定持续嵌套if函数调用getAdapterPosition就会引发歧义了,由于程序或许并不知道你想要的是ViewHolde阿里供应链r的相对方位,仍是必定方位

相对方位 & 必定方位?阿里云getBindindAdapterPosition 与 getAbsoluteAdapterPositi嵌套路由on 的差异

此处的相对方位及必定方位的叫法,并非官方叫法,而是参看文件体系中的 相对路径 和 必定路径,提出的一种相似概念。咱们举例阐明什么是相对方位和必源码编辑器手机版下载定方位。如下图中的比如:MergeAdapter里包含了A Adapter 和 B Adapter,在页面的展现上,B 在 A 的后面,开源我国咱们想获取B中某一个元素b3的方位,此时的方位有两种:b3在B嵌套查询sql句子中的方位,我把他叫做相开源代码网站github对方位,以及b3在整个RecyclerView中地点的方位,我将其称之为必定方位。

「RecyclerView中的方位」你真的会正确获取Item的方位么?
官方供应的两个办法getB开源阅览indingAdapterPostiongetAbsoluteAdapterPosition便是用来获取ViewHolder的相对嵌套界说方位和必定方位的。

  • getBindingAdapterPosition将会回来该ViewHolder相谷歌关于它绑定的Adapter嵌套循环中的方位,即相对方位。
  • getAbsoluteAdapterPosition将会回来该ViewHolder相关于谷歌商店RecyclerView的方位,即必定方位。

回到咱们文章最初说到的两种典型的RecyclerVi谷歌卫星地图ew中运用Position的场景:

设置源码网站点击作业 & 记载、操作Recycler嵌套函数View的翻滚状况,关于前者,咱们往往运用getBindingAdapterPostion获取ViewHolder对应的数据项,完结点击操作。

override fun onBindViewHolder(holder: N谷歌卫星地图umberHolder, position: Int) {
   holder.tvNumber.text = "Position: ${list[position]}"
   holder.itemV嵌套函数iew.setOnClickListener {
     Toast.makeText(it谷歌.context, "点击了:${l开源节流是什么意思是什么ist[holder.bindingAdapterPosition]}", Toast.LENGTH_源码SHORT).show(源码交易网站源码)
    }
  }谷歌地图

至于后者,很明显,咱们应该运用getAbsoluteAdapterPosition来操作Recycler阿里巴巴1688货源批发官网View的翻滚。

当然,假定你的项目完全没有运用ConcatAdapter,那getBindingAdapterPos嵌套循环tion和getAbsoluteAdapterPosition关于你来说,没有任何差异,不过我仍推荐你按照不同的运用场景阿里旺旺选用不同的办法获取合适的方位参数,终究今后用不用Co开源我国ncatAdapte阿里巴巴r 谁又说的阿里巴巴清楚呢?

getLayoutPosition

那getLayoutPosition又是获取什么方位的呢?什么场景下咱们运用该api来获取方位呢?

getL谷歌商店ayoutPosition,望文生义,便是获取该ViewHolder在实践布局中的方位。源码编辑器手机版下载咱们都知道,Recycler嵌套结构View运用LayoutManager来办理数据集谷歌的实践。当开发者调阿里巴巴股票notifyData*()等办法告诉Recycler阿里云View改写U阿里云邮箱个人版I时,出于性能的考虑,Recycl开源代码网站githuberView的UI并不会立刻改写,和Data保持一致,而是经过LayoutManager慵懒更新相关布局——这个过程伴跟着时间上的等候,一般状况下,这个等候时间小于16ms。所以,从感官上讲,getLayoutPosition与ge开源阅览app下载安装tAbsoluteAdapterPosition十分相似:getAbsoluteAdapterPosition回来的是该ViewHolder相关于RecyclerV源码iew的必定方位,而getLayoutPosition回来的是该ViewHolder相关于RecyclerView实践布局的必开源软件定方位。

说详细点,便是adapter和layout的方位谷歌空间会有时间差(一般状况下<16ms), 假定你改变了Adapter的开源节流是什么意思是什么数据然后改写视图, layout需求过一段时间才阿里旺旺会更新视图, 在这段时间里面, 这两个办法回来的position会不相同。

源码是什么意思notifyDataS嵌套查询sql句子etChange嵌套路由d之后并不能立刻获取Adapter中的position, 要等布局完毕之后才嵌套界说华获取到.

而关于Layout的position, 在notifyItemInserted阿里巴巴之后, Layout不能立刻获取到新的开源是什么意思position, 由于布局还没更新(需求<16ms的时间改写视图), 所以只能获取到旧的, 可是Adapter中的position就能够立刻获取到最新的p谷歌安装器osition。

所以,关于上面的谷歌地图点击作业的场景,咱们在获取用户点击方位的时分,运用getLayoutPosition或许作用更好,这样,就能保证用户点击的始终是他看到的那个数据(消除16ms带来的时间差问题),代码能够改构成下面这样:

override fun onBindViewHolder(holder: NumberHolder, position: Int) {
   holder.tvNumber阿里云盘.text = "Position: ${list[position]}"
   holder.itemView.setOnClickListener {
     Toast.makeText(it.context, "点击了:${list[holder.layoutPosition]}", Toast.LENGTH_SHO源码交易网站源码RT).show()
    }
  }

总结

  • 源码注释很重要
  • 官网文档很重要

遇到这种办法不置可否,让人傻傻分不清楚的状况,作为API调用者的咱们,需求咱们做到的便是恰当的阅览源码注释,结合官方文档,正确理解他们各自所代表的意义以及或许带来的影响,合理运用他们。

发表评论

提供最优质的资源集合

立即查看 了解详情