在开始使用之前,首先,在build.gradle中设置依赖导入:
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha05'然后,Sync Now。
首先,废话不多说,先看一个例子,横向的RecyclerView实现: 适配器的实现。 import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView class HomeAdapter(val mList:ArrayList<String>, val mContext:Context) : RecyclerView.Adapter<HomeAdapter.MyViewHolder>(){ public fun removeData(position:Int) :Unit { mList.removeAt(position) notifyItemRemoved(position) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeAdapter.MyViewHolder { val contentView = LayoutInflater.from(mContext).inflate(R.layout.item_list, parent, false) val holder:MyViewHolder = MyViewHolder(contentView) return holder } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.tv.setText(mList.get(position)) } override fun getItemCount(): Int { return mList.size } class MyViewHolder(val view: View) : RecyclerView.ViewHolder(view){ val tv:TextView = view.findViewById(R.id.text_id) } } 我们主要的列表所在页面的xml代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> 子项的xml代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="match_parent"> <TextView android:id="@+id/text_id" android:layout_width="match_parent" android:layout_height="50dp" android:text="233" android:gravity="center" /> </LinearLayout> 主函数代码: import android.app.Activity import android.os.Bundle import android.view.View import android.view.ViewGroup import android.widget.LinearLayout import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import java.util.* import kotlin.collections.ArrayList class MainActivity : Activity(){ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) val data = ArrayList<String>() data.add("测试") data.add("再测") data.add("春绮美空") //设置列表 val list:RecyclerView = findViewById(R.id.recyclerview) val params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT) val linearLayoutManager = LinearLayoutManager(this) linearLayoutManager.orientation = LinearLayoutManager.HORIZONTAL list.layoutManager = linearLayoutManager list.layoutParams = params list.itemAnimator = DefaultItemAnimator() val adapter:HomeAdapter = HomeAdapter(data, this) list.adapter = adapter } } 我们适配器不用变,看一下纵向的列表实现: 主活动: import android.app.Activity import android.os.Bundle import android.view.View import android.view.ViewGroup import android.widget.LinearLayout import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import java.util.* import kotlin.collections.ArrayList class MainActivity : Activity(){ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) val data = ArrayList<String>() data.add("测试") data.add("再测") data.add("春绮美空") //设置列表 val list:RecyclerView = findViewById(R.id.recyclerview) val params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) list.layoutManager = LinearLayoutManager(this) list.layoutParams = params list.itemAnimator = DefaultItemAnimator() val adapter:HomeAdapter = HomeAdapter(data, this) list.adapter = adapter } } 主列表: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> 子项: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/text_id" android:layout_width="match_parent" android:layout_height="50dp" android:text="233" android:gravity="center" /> </LinearLayout>注意:子项的最外层布局需要根据是横向还是纵向而设置wrap_content。 总结,RecyclerView更相当与一个容器,里面每一项都作为一个子布局,被适配器放入这个容器中,因此,子项的最外层布局,会直接影响到它在列表中的展示布局,所以,才会出现一个子项占满容器的情况,你可以试试将子项的布局线性布局宽高全部设置为match_parent,列表就只会显示一项。 3. 结果 横向: 纵向: 4. 你应该也注意到了,这个列表没有分割线,RecyclerView并没有自带分割线,需要自己定义,虽然比较麻烦,但是可以私人定制啊。下面介绍一下分割线的实现。
首先,需要继承实现RecyclerView.Decoration,如果你有一点Canvas的基础,应该不难理解, import android.content.Context import android.content.res.TypedArray import android.graphics.Canvas import android.graphics.DrawFilter import android.graphics.Rect import android.graphics.drawable.Drawable import android.view.View import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import java.text.AttributedString class DividerItemDecoration : RecyclerView.ItemDecoration() { companion object { fun get():IntArray{ val res = IntArray(1) res[0] = android.R.attr.listDivider return res } var ATTRS = get() val HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL val VERTICAL_LIST = LinearLayoutManager.VERTICAL } private var mDivider: Drawable? = null private var mOrientation:Int = 0 /** * 初始化 */ public fun DividerItemDecoration(context: Context, orientation:Int){ val a:TypedArray = context.obtainStyledAttributes(ATTRS) mDivider = a.getDrawable(0) a.recycle() setOrientation(orientation) } /** * 设置布局 */ public fun setOrientation(orientation:Int){ if(orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST){ throw IllegalArgumentException("无效布局") } mOrientation = orientation } override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { if(mOrientation == VERTICAL_LIST){ drawVertical(c, parent) }else{ } } /** * 绘制纵向分割线 */ fun drawVertical(c:Canvas, parent:RecyclerView){ val left:Int = parent.paddingLeft val right:Int = parent.width - parent.paddingRight val childCount:Int = parent.childCount for(i in 0 until childCount){ val child: View = parent.getChildAt(i) val params:RecyclerView.LayoutParams = RecyclerView.LayoutParams(child.layoutParams) val top:Int = child.bottom + params.bottomMargin val bootom:Int = top + mDivider!!.intrinsicHeight mDivider!!.setBounds(left, top, right, bootom) mDivider!!.draw(c) } } /** * 绘制横向分割线 */ fun drawHorizontal(c:Canvas, parent: RecyclerView){ val top:Int = parent.paddingTop val bottom:Int = parent.height - parent.paddingBottom val childCount:Int = parent.childCount for(i in 0 until childCount){ val child:View = parent.getChildAt(i) val params:RecyclerView.LayoutParams = RecyclerView.LayoutParams(child.layoutParams) val left:Int = child.right + params.rightMargin val right:Int = left + mDivider!!.intrinsicWidth mDivider!!.setBounds(left, top, right, bottom) mDivider!!.draw(c) } } override fun getItemOffsets( outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State ) { super.getItemOffsets(outRect, view, parent, state) if(mOrientation == VERTICAL_LIST){ outRect.set(0, 0, 0, mDivider!!.intrinsicHeight) }else{ outRect.set(0 , 0 , mDivider!!.intrinsicWidth, 0) } } } 然后,在设置adapter之前,设置分割线。 val decoration:DividerItemDecoration = DividerItemDecoration() decoration.DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST) list.addItemDecoration(decoration) list.adapter = adapter效果:
那么,我们想要设置单击事件,可以直接设置吗?那肯定不行。233,高级的组件灵活性就是高,啥都得自己搞,开搞。我们给每一项设置单击事件。 修改适配器 import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView class HomeAdapter(val mList:ArrayList<String>, val mContext:Context) : RecyclerView.Adapter<HomeAdapter.MyViewHolder>(){ private var mOnItemClickListener:OnItemClickListener? = null public fun removeData(position:Int) :Unit { mList.removeAt(position) notifyItemRemoved(position) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeAdapter.MyViewHolder { val contentView = LayoutInflater.from(mContext).inflate(R.layout.item_list, parent, false) val holder:MyViewHolder = MyViewHolder(contentView) //设置单击事件,和我们的接口挂钩 contentView.setOnClickListener(object :View.OnClickListener{ override fun onClick(v: View?) { mOnItemClickListener!!.onItemClick(v!!, v.tag as Int)// as真好用 } }) return holder } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.tv.setText(mList.get(position)) holder.itemView.tag = position } override fun getItemCount(): Int { return mList.size } class MyViewHolder(val view: View) : RecyclerView.ViewHolder(view){ val tv:TextView = view.findViewById(R.id.text_id) } //我们的事件接口,可以在这里扩充 public interface OnItemClickListener{ //单击 fun onItemClick(view: View, position: Int) } //设置点击属性 public fun setOnItemClickListener(mOnItemClickListener: OnItemClickListener){ this.mOnItemClickListener = mOnItemClickListener } } 搞好之后,在主活动中定义单击事件: import android.app.Activity import android.os.Bundle import android.view.View import android.view.ViewGroup import android.widget.LinearLayout import android.widget.Toast import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import java.util.* import kotlin.collections.ArrayList class MainActivity : Activity(){ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) val data = ArrayList<String>() data.add("测试") data.add("再测") data.add("春绮美空") //设置列表 val list:RecyclerView = findViewById(R.id.recyclerview) val params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) list.layoutManager = LinearLayoutManager(this) list.layoutParams = params list.itemAnimator = DefaultItemAnimator() val adapter:HomeAdapter = HomeAdapter(data, this) val decoration:DividerItemDecoration = DividerItemDecoration() decoration.DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST) list.addItemDecoration(decoration) //设置单击事件 adapter.setOnItemClickListener(object :HomeAdapter.OnItemClickListener{ override fun onItemClick(view: View, position: Int) { Toast.makeText(this@MainActivity, "单击第${position+1}条", Toast.LENGTH_LONG).show() } }) list.adapter = adapter } } 效果如下 还有,下一篇,有帮助点个赞吧,拜托了,这对我真的很重要!!! 下一篇,Android初步进阶之RecyclerView使用(二)