
在项目中使用 androidx 库
项目中使用时并在 gradle.properties 文件中将以下两个 Android Gradle 插件标记设置为 true。
android.useAndroidX:该标记设置为 true 时,Android 插件会使用对应的 AndroidX 库,而非支持库。如果未指定,则该标记默认为 false。
android.enableJetifier:该标记设置为 true 时,Android 插件会通过重写其二进制文件来自动迁移现有的第三方库,以使用 AndroidX 依赖项。如果未指定,该标记默认为 false。
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
自动化转换到Androidx
点中项目文件夹右键Refactor->Migrate to Androidx
添加RecyclerView需要依赖
//recyclerview
implementation 'androidx.recyclerview:recyclerview:1.1.0'
// For control over item selection of both touch and mouse driven selection
implementation "androidx.recyclerview:recyclerview-selection:1.1.0-rc01"
//CardView
implementation 'androidx.cardview:cardview:1.0.0'
这里第二个依赖是关于itemView的触碰和选中事件,这里暂不展开
RecyclerView编写Adapter
基本的Adapter:
class RecyclerViewListAdapter(private val myDataSet: String) :
RecyclerView.Adapter<RecyclerViewListAdapter.MyViewHolder>() {
//自定义ViewHolder类,持有itemView的子View的引用
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val mTextView :TextView = itemView.findViewById(R.id.textView)
}
/**
* @param parent 参数就是RecyclerView本身
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.my_text_image_view, parent, false)
return MyViewHolder(itemView)
}
//返回总共的item数量
override fun getItemCount(): Int {
return 240
}
/**
* 用于ViewHolder持有的view和数据绑定
*/
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.mTextView.text=myDataSet
// var mImageView: ImageView = holder.itemView.findViewById<ImageView>(R.id.imageView)
}
多种视图类型的Adapter:
class RecyclerViewMultiItemAdapter(
private val context: Context,
private val mDataSet: String
) :
RecyclerView.Adapter<RecyclerViewMultiItemAdapter.MyViewHolder>() {
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val mTextView: TextView? = itemView.findViewById(R.id.textView)
//这里由于不同布局的子布局不同,所以要可以为空
val mImageView: ImageView? = itemView.findViewById(R.id.imageView)
val mCardView: CardView? = itemView.findViewById(R.id.card_view)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView: View = when (viewType) {
0 -> LayoutInflater.from(parent.context)
.inflate(R.layout.my_text_image_view, parent, false)
1 -> LayoutInflater.from(parent.context)
.inflate(R.layout.my_text_view, parent, false)
2 -> LayoutInflater.from(parent.context)
.inflate(R.layout.my_card_view, parent, false)
else -> LayoutInflater.from(parent.context)
.inflate(R.layout.my_card_view, parent, false)
}
return MyViewHolder(itemView)
}
override fun getItemCount(): Int {
return 50
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
//因为可能MyViewHolder持有的itemView子View为空,需要做if no null判断
//这里用了语法糖
holder.mTextView?.text = mDataSet
holder.mImageView?.let {
Glide.with(context)
.load("https://bkimg.cdn.bcebos.com/pic/faf2b2119313b07e9bf96b780bd7912397dd8c7d?x-bce-process=image/watermark,g_7,image_d2F0ZXIvYmFpa2U4MA==,xp_5,yp_5")
.into(it)
}
holder.mCardView?.let {
it.radius = 30f
}
}
/**
* 返回的int值作为onCreateViewHolder(parent: ViewGroup, viewType: Int)中的viewType
* 用作标签实现布局选择
*/
override fun getItemViewType(position: Int): Int {
var typeInt = 0
when (position % 3) {
0 -> typeInt = 0
1 -> typeInt = 1
2 -> typeInt = 2
}
return typeInt
}
}
RecyclerView添加LayoutManager和其他设置
class RecyclerViewListActivity : AppCompatActivity() {
private lateinit var viewManager: RecyclerView.LayoutManager
private lateinit var recyclerViewAdapter: RecyclerView.Adapter<*>
private lateinit var myDataSet: String
private lateinit var recyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recyclerview_list)
myDataSet = "koko"
//线性布局管理器
viewManager = LinearLayoutManager(this)
//格子布局管理器
// setGridLayoutManager()
//基本的布局Adapter
// recyclerViewAdapter = RecyclerViewListAdapter(myDataSet)
//多种布局Adapter
recyclerViewAdapter = RecyclerViewMultiItemAdapter(this,myDataSet)
recyclerView = findViewById<RecyclerView>(R.id.my_recycler_view).apply {
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
setHasFixedSize(true)
// use a linear layout manager
layoutManager = viewManager
// specify an viewAdapter (see also next example)
adapter = recyclerViewAdapter
}
//设置分割线
recyclerView.addItemDecoration(
DividerItemDecoration(
this,
DividerItemDecoration.VERTICAL
)
)
}
private fun setGridLayoutManager(){
val spanCount= 2
viewManager = GridLayoutManager(this,spanCount)
}
}
效果图:

总结:
RecyclerView的使用主要难点在于Adapter的编写,Adapter的编写难在对于数据的处理,这里是简单的模拟,用的简单的数据来复盘多布局的加载。
Demo参考: AndroidUIDemo
使用时参考README说明