Recyclerview使用
700 Words|Read in about 4 Min|本文总阅读量次
RecyclerView,一个强大的控件,既支持纵向滚动,又支持横向滚动。 应用场景非常广泛,简单说ListView可以做的它可以做,ListView不支持的横向它也可以做。
Recyclerview使用
对于其不仅可以实现和ListView同样的效果
本文主要是一个RecyclerView的开篇,主要针对RecyclerView空间的使用。至于RecyclerView的观察者模式和缓冲机制,后续会在源码分析持续更新。
RecyclerView的使用说明
笔者对于RecyclerView的记忆主要是一个口诀,一类继承,四个方法。
对于口诀使用的类就是Adapter
1)一类继承
里面MyViewHolder继承 RecyclerView.ViewHolder,并实现RecyclerView.ViewHolder的构造,一般用于findviewbyid绑定控件
而MyAdapter继承RecyclerView.Adpter<MyAdapter.MyViewHolder>
2)四个方法
一个构造
一般为有参构造,用于传递参数进来,初始化控件信息
举例MyAdapter(List< SettingItem > list)
三个继承
1)通过viewType来实现加载不同的布局
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
2)将数据和控件绑定,会在每个子项被滚动到屏幕内时执行,position从0开始
public void onBindViewHolder(ViewHolder holder, int position)
3)多少个item数
public int getItemCount()
3)外部使用
设置完成之后,在Activity的使用也很简单,如下所示外部设置
1)RecyclerView获取他的对象 RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
2)LayoutManager用于指定RecyclerView的布局方式,设置layoutManager 的展示方式设置为竖直方向 LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager .setOrientation(LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager);
3)设置适配器 MyAdapter adapter = new MyAdapter(fruitList); recyclerView.setAdapter(adapter);
RecyclerView的demo
1)settings
效果图如下
拆解demo
首先是Adapter
1//构造内部类,并使用kotlin的构造函数,继承内部Holder类
2private inner class SimpleAdapter constructor(list :List<SettingItem>) : RecyclerView.Adapter<SimpleAdapter.Holder>() {
3 private var mSettingItem: List<SettingItem>? = null
4 //*一个继承* Holder继承RecyclerView.ViewHolder,并且初始化构造
5 inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView){
6 var textView : TextView? = null
7 var imageView : ImageView? = null
8
9 //Hoder构造器初始化
10 init {
11 textView = itemView.findViewById(R.id.settingname)
12 imageView = itemView.findViewById(R.id.settinginfo)
13 imageView?.setOnClickListener(View.OnClickListener {
14 Log.d(TAG, "->onclicked imageview")
15 //可以直接通过getposition获取到postion的值
16 Toast.makeText(context!!, "onclicked imageview pos = $position", Toast.LENGTH_LONG).show()
17 })
18 itemView?.setOnClickListener(View.OnClickListener {
19 Log.d(TAG, "->onclicked item")
20 Toast.makeText(context!!, "onclicked item pos = $position", Toast.LENGTH_LONG).show()
21 })
22 }
23
24 }
25 //*一个构造*SimpleAdapter构造器初始化,将list传递进来
26 init {
27 mSettingItem = list
28 }
29 //*三个方法*加载唯一布局
30 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
31 var view: View = LayoutInflater.from(parent.context).inflate(R.layout.item_settings, parent, false)
32 var viewHolder: Holder = Holder(view)
33 return viewHolder
34 }
35 //*三个方法*将数据和控件绑定,数据来源于SimpleAdapter构造器
36 override fun onBindViewHolder(holder: Holder, position: Int) {
37 var settingItem = mSettingItem?.get(position)
38 holder.textView?.text = settingItem?.getName()
39 settingItem?.getInfo()?.let { holder.imageView?.setImageResource(it) }
40
41 }
42 //*三个方法*设置多少个item数为list长度
43 override fun getItemCount(): Int {
44 return mSettingItem?.let { it.size } ?: run { 0 }
45 }
46 }
接着拆解外部使用
1//1)RecyclerView获取他的对象
2recyclerView = findViewById(R.id.moresettings)
3//2)LayoutManager用于指定RecyclerView的布局方式,展示方式设置为竖直方向
4var ll: LinearLayoutManager = LinearLayoutManager(this)
5ll.orientation = LinearLayoutManager.VERTICAL
6recyclerView?.layoutManager = ll
7//3)设置适配器
8recyclerView?.adapter = SimpleAdapter(mList)
拆解之后就感觉使用会很简单
2)wifiSettings
效果图如下
拆解demo
首先是Adapter
1//构造内部类,并使用kotlin的构造函数,具体的逻辑代码省略部分,因为此demo有多个viewholder,所以不继承使用父类即可
2private inner class WifiAdapter internal constructor(context: Context) :
3 RecyclerView.Adapter<RecyclerView.ViewHolder>() {
4 private val inflater: LayoutInflater = LayoutInflater.from(context)
5 //*三个方法*增加一个方法来判断viewholder类型,总共有itemCount个item
6 //范围从0---itemCount-1,其中下标为0,表示为viewType为2
7 //下标为1---itemCount-2表示viewType为1
8 //下标为其他itemCount-1表示viewType为0
9 override fun getItemViewType(position: Int): Int {
10 return when (position) {
11 0 -> 2
12 itemCount - 1 -> 1
13 else -> 0
14 }
15 }
16 //*三个方法*加载布局,这里默认有三个布局,根据上面的getItemViewType的返回值viewtype来判断
17 //viewType为0 ,布局就是数据布局,这里代表wifi
18 //viewType为1 ,布局就是数据布局的下面布局,这里代表手动添加wifi
19 //viewType为2 ,布局就是数据布局的上面布局,这里代表关闭/打开wifi
20 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
21 return when (viewType) {
22 0 ->
23 ItemViewHolder(inflater.inflate(R.layout.item_access_point_2, parent, false))
24 1 ->
25 ManualViewHolder(
26 inflater.inflate(
27 R.layout.item_access_point_manual,
28 parent,
29 false
30 )
31 )
32 2 -> {
33 val holder = WifiSwitchViewHolder(
34 inflater.inflate(
35 R.layout.item_wifi_switch,
36 parent,
37 false
38 )
39 )
40 ...
41 }
42 else ->
43 ItemViewHolder(inflater.inflate(R.layout.item_access_point_2, parent, false))
44 }
45 }
46 //*三个方法*将数据和控件绑定,数据来源于scans
47 override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
48 if (holder is ItemViewHolder) {
49 scans?.get(position - 1)?.let { scan ->
50 holder.bind(scan)
51 }
52 }
53 }
54 //*三个方法*设置多少个item数,wifi打开为scans.size + 2,wifi关闭为1
55 override fun getItemCount(): Int {
56 val isWifiEnabled = wifiSwitch?.isChecked == true
57 return if (isWifiEnabled) (scans?.size ?: 0) + 2 else 1
58 }
59 //*一个继承* ManualViewHolder继承RecyclerView.ViewHolder,并且初始化构造
60 internal inner class ManualViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
61 init {
62 itemView.setOnClickListener {
63 handleAddManual()
64 }
65 }
66 }
67 //*一个继承* WifiSwitchViewHolder继承RecyclerView.ViewHolder
68 internal inner class WifiSwitchViewHolder(itemView: View) :
69 RecyclerView.ViewHolder(itemView)
70 //*一个继承* ItemViewHolder继承RecyclerView.ViewHolder,并且初始化构造
71 internal inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
72 private val icon: ImageView = itemView.findViewById(R.id.icon)
73 private val ssid: TextView = itemView.findViewById(R.id.ssid)
74 private val status: TextView = itemView.findViewById(R.id.status)
75 private val info: ImageView = itemView.findViewById(R.id.info)
76
77 init {
78 itemView.setOnClickListener { handleOnItemClick(scans!![this@ItemViewHolder.layoutPosition - 1]) }
79 info.setOnClickListener { handleOpenWifiInfo(scans!![this@ItemViewHolder.layoutPosition - 1]) }
80 }
81 }
82 }
接着拆解外部使用
1private var adapter: WifiAdapter? = nul
2adapter = context?.let { WifiAdapter(it) }
3//1)RecyclerView获取他的对象
4val list =findViewById<RecyclerView>(R.id.wifi_list)
5//2)设置展示方式,这里将item之间添加横线,默认方向为竖向
6list.addItemDecoration(
7 DividerItemDecoration.Builder(list.context)
8 .setPadding(resources.getDimensionPixelSize(R.dimen.dp_40))
9 .setDividerColor(ContextCompat.getColor(list.context, R.color.dividerLight))
10 .setDividerWidth(resources.getDimensionPixelSize(R.dimen.dp_1))
11 .build()
12)
13//4)设置适配器
14list.adapter = adapter
整理wifisettings.kt
主要流程如下
1.布局加载
2.数据加载
3.notify更新
总结
RecyclerView的使用已经完结,主要针对具体demo分析如何去快速的上手使用,由于RecyclerView的功能非常强大,其他功能各位宝宝可以自行探索。
猜你喜欢
参考
[1] Frank-Zhu, RecyclerView使用详解(二), 2015.