写点什么

什么?这个天天使用的 API 竟然被废弃了?,android 组件化和模块化区别

用户头像
Android架构
关注
发布于: 刚刚

接下来创建两个非常简单的 Adapter,一个 TitleAdapter 和一个 BodyAdapter,待会我们会用 MergeAdapter 将这两个 Adapter 合并到一起。TitleAdapter 代码如下:


class?TitleAdapter(val?items:?List<String>)?:?RecyclerView.Adapter<TitleAdapter.ViewHolder>()?{


inner?class?ViewHolder(view:?View)?:?RecyclerView.ViewHolder(view)?{


val?text:?TextView?=?view.findViewById(R.id.text)


}


override?fun?onCreateViewHolder(parent:?ViewGroup,?viewType:?Int):?ViewHolder?{


val?view?=?LayoutInflater.from(parent.context).inflate(R.layout.item_view,?parent,?false)


val?holder?=?ViewHolder(view)


return?holder


}


override?fun?getItemCount()?=?items.size


override?fun?onBindViewHolder(holder:?ViewHolder,?position:?Int)?{


holder.text.text?=?items[position]


}


}


这是一个 Adapter 最简单的实现,没有任何逻辑在里面,只是为了显示一行文字。item_view 是个只包含一个 TextView 控件的简单布局,这里就不展示其中的代码了。然后 BodyAdapter 的代码如下:


class?BodyAdapter(val?items:?List<String>)?:?RecyclerView.Adapter<BodyAdapter.ViewHolder>()?{


inner?class?ViewHolder(view:?View)?:?RecyclerView.ViewHolder(view)?{


val?text:?TextView?=?view.findViewById(R.id.text)


}


override?fun?onCreateViewHolder(parent:?ViewGroup,?viewType:?Int):?ViewHolder?{


val?view?=?LayoutInflater.from(parent.context).inflate(R.layout.item_view,?parent,?false)


val?holder?=?ViewHolder(view)


return?holder


}


override?fun?getItemCount()?=?items.size


override?fun?onBindViewHolder(holder:?ViewHolder,?position:?Int)?{


holder.text.text?=?items[position]


}


}


基本上就是复制过来的代码,和 TitleAdapter 没有什么区别。然后我们在 MainActivity 当中就可以这样使用了:


class?MainActivity?:?AppCompatActivity()?{


override?fun?onCreate(savedInstanceState:?Bundle?)?{


super.onCreate(savedInstanceState)


setContentView(R.layout.activity_main)


val?titleItems?=?generateTitleItems()


val?titleAdapter?=?TitleAdapter(titleItems)


val?bodyItems?=?generateBodyItems()


val?bodyAdapter?=?BodyAdapter(bodyItems)


val?mergeAdapter?=?MergeAdapter(titleAdapter,?bodyAdapter)


recyclerView.layoutManager?=?LinearLayoutManager(this)


recyclerView.adapter?=?mergeAdapter


}


private?fun?generateTitleItems():?List<String>?{


val?list?=?ArrayList<String>()


repeat(5)?{?index?->


list.add("Title?$index")


}


return?list


}


private?fun?generateBodyItems():?List<String>?{


val?list?=?ArrayList<String>()


repeat(20)?{?index?->


list.add("Body?$index")


}


return?list


}


}


可以看到,这里我编写了 generateTitleItems()和 generateBodyItems()这两个方法,分别用于给两个 Adapter 生成数据集。然后创建了 TitleAdapter 和 BodyAdapter 的实例,并使用 MergeAdapter 将它们合并到一起。合并的方式很简单,就是将你要合并的所有 Adapter 的实例都传入到 MergeAdapter 的构造方法当中即可。最后,将 MergeAdapter 设置到 RecyclerView 当中,整个过程结束。是不是非常简单?几乎和之前 RecyclerView 的用法没有任何区别。现在运行一下程序,效果如下图所示:



可以看到,TitleAdapter 和 BodyAdapter 中的数据是合并到一起显示的,同时也就说明,我们的 MergeAdapter 已经成功生效了。到这里为止都还算很好理解,但是接下来,我要给大家一个灵魂拷问了。如果这时,我想要监听 BodyAdapter 中元素的点击事件,那么调用 getAdapterPosition()方法,获得的到底是 BodyAdapter 中元素的点击位置,还是合并之后元素的点击位置呢?你会发现,这个时候 getAdapterPosition()方法已经会造成歧义了,这也就是开篇那段英文所描述的问题。而解决办法当然也很简单,Google 废弃了 getAdapterPosition()方法,但是却又提供了 getBindingAdapterPosition()和 getAbsoluteAdapterPosition()这两个方法。从名字上就可以看出来了,一个是用于获取元素位于当前绑定 Adapter 的位置,一个是用于获取元素位于 Adapter 中的绝对位置。如果觉得我上面的解释还不够清楚,通过下面的示例看一下你立马就能明白了。我们修改 BodyAdapter 中的代码,在里面加入监听当前元素点击事件的代码,如下所示:


class?BodyAdapter(val?items:?List<String>)?:?RecyclerView.Adapter<BodyAdapter.ViewHolder>()?{


override?fun?onCreateViewHolder(parent:?ViewGroup,?viewType:?Int):?ViewHolder?{


val?view?=?LayoutInflater.from(parent.context).inflate(R.layout.item_view,?parent,?false)


val?holder?=?ViewHolder(view)


holder.itemView.setOnClickListener?{


val?position?=?holder.bindingAdapterPosition


Toast.makeText(parent.context,?"You?c


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


licked?body?item?$position",?Toast.LENGTH_SHORT).show()


}


return?holder


}


...


}

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
什么?这个天天使用的API竟然被废弃了?,android组件化和模块化区别