您好,欢迎访问代理记账网站
移动应用 微信公众号 联系我们

咨询热线 -

电话 15988168888

联系客服
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

【Android】Recyclerview学习

Recyclerview

  • 基本使用
    • 导包;
    • 设置布局控件
    • 设置item的数据类,添加adapter,设置item对应的类;
    • 设置recyclerView控件的adapter和layoutmanager。
  • RecyclerView相关
    • LayoutManager布局管理器
      • LinearLayoutManager线性布局管理器,
      • StaggeredGridLayoutManager错列网格布局管理器
      • GridLayoutManager网格布局管理器
    • Adapter类相关
      • inflate详解

基本使用

导包;

就一行代码,具体导入哪个版本自己看

设置布局控件

	<androidx.recyclerview.widget.RecyclerVIew
		android:id="@+id/recyclerView"
		android:layout_width="match_parent"
		android:layout_height="wrap_content">
	</androidx.recyclerview.widget.RecyclerVIew>
另外还需要对列表item里的显示内容进行单独的layout设置。
	<androidx.constaintlayout.widget.ConstraintLayout
		xmlns:android="http://schemas.android.com/apk/res/android"
		xmlns:app="http://schemas.android.com/apk/res-auto"
		xmlns:tools="http://schemas.android.com/tools"
		android:layout_width="match_parent"
		android:layout_height="100dp"
		tools:viewBindingIgnore="true">
		<TextView
	        android:id="@+id/tvNumber"
	        android:layout_width="28dp"
	        android:layout_height="28dp"
	        app:layout_constraintTop_toTopOf="parent"
	        app:layout_constraintBottom_toBottomOf="parent"
	        app:layout_constraintLeft_toLeftOf="parent"
	        android:layout_marginTop="3dp"
	        android:background="@drawable/search_default_medal"
	        android:scaleType="fitXY"
	        android:text="1"
	        android:textSize="13dp"
	        android:textColor="@color/white"
	        android:paddingTop="3dp"
	        android:gravity="center_horizontal"
	        />
	    <ImageView
	        android:id="@+id/ivIcon"
	        android:layout_width="60dp"
	        android:layout_height="46dp"
	        app:layout_constraintLeft_toRightOf="@+id/tvNumber"
	        app:layout_constraintTop_toTopOf="parent"
	        app:layout_constraintBottom_toBottomOf="parent"
	        android:laout_marginLeft="10dp"/>
		<TextView
	        android:id="@+id/tvTitle"
	        android:layout_width="0dp"
	        android:layout_height="wrap_content"
	        app:layout_constraintTop_toTopOf="@+id/ivIcon"
	        app:layout_constraintleft_toRightOf="@+id/ivIcon"
	        app:layout_constraintRight_toRightOf="parent"
	        android:layout_marginLeft="3dp"
	        android:layout_marginRight="3dp"
	        android:text=""
	        android:textSize="14dp"
	        android:textColor="@color/white"
	        android:lines="1"
	        android:ellipsize="end"
	        />
		<TextView
	        android:id="@+id/tvSource"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        app:layout_constraintBottom_toBottomOf="@+id/ivIcon"
	        app:layout_constraintLeft_toLeftOf="@+id/tvTitle"
	        android:text="1"
	        android:textSize="14dp"
	        android:textColor="@color/white"
	        android:lines="1"
	        />
		<ImageView
	        android:id="@+id/ivLabel"
	        android:layout_width="35dp"
	        android:layout_height="17dp"
	        android:paddingLeft="3dp"
	        android:paddingRight="3dp"
	        android:scaleType="fitXY"
	        app:layout_constraintLeft_toRightOf="@+id/tvSource"
	        app:layout_constraintEnd_toStartOf="@+id/tvHotNumber"
	        app:layout_constraintBottom_toBottomOf="@+id/tvSource"
	        app:layout_constraintTop_toTopOf="@+id/tvSource"
	        />
		<TextView
	        android:id="@+id/tvHotNumber"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        app:layout_constraintBottom_toBottomOf="@+id/ivIcon"
	        app:layout_constraintRight_toRightOf="parent"
	        android:gravity="right"
	        android:text="1"
	        android:textSize="14dp"
	        android:textColor="@color/white"
	        android:lines="1"
	        />
	</androidx.constaintlayout.widget.ConstraintLayout>

设置item的数据类,添加adapter,设置item对应的类;

	data class SearchHotBean{
		var articleId:String?,
		var jumpPage:String?,
		var jumpUrl:String ?,
		var hotValue:String?,
		var title:String?,
		var cover:String?,
		var articleSourceName:String?,
		var hotValueShowText:String?,
		var searchLabelIconUrl:String?,
		var bitmap:Bitmap?
	}

定义adapter,其中里面包含了一个承载列表item布局的viewHolder

	inner class ViewHolder(itemVIew:View):RecyclerView.ViewHolder(itemView){
		val tvNumber: TextView by lazy{itemView.findViewById<TextView>(R.id.tvNumber)}
		val ivIcon: ImageView by lazy{itemView.findViewById<ImageView>(R.id.ivIcon)}
		val tvTitle: TextView by lazy{itemView.findViewById<TextView>(R.id.tvTitle)}
		val tvSource: TextView by lazy{itemView.findViewById<TextView>(R.id.tvSource)}
		val ivLabel: ImageView by lazy{itemView.findViewById<ImageView>(R.id.ivLabel)}
		val tvHotNumber: TextView by lazy{itemView.findViewById<TextView>(R.id.tvHotNumber)}
	}

接下来就是adapter类

	class ListAdapter(private val list : List<SearchHotBean>,var context:Context):RecyclerView.Adapter<ListAdapter.ViewHolder>(){
		override fun onCreateViewHolder(patent: ViewGroup,viewType: Int): ViewHolder{
			val view=LayoutInflater.from(parent.context).inflate(R.layout.search_test_item,parent,false)
			retrun ViewHolder(view)
		}
		override fun onBindViewHolder(holder: ViewHolder,position: Int){
			//具体操作不写了,主要是对列表各项item赋值
		}
		override fun getItemCount(): Int=list.size
		inner class ViewHolder(itemView: View) RecyclerView.ViewHolder(itemView){
			val tvNumber: TextView by lazy{itemView.findViewById<TextView>(R.id.tvNumber)}
			val ivIcon: ImageView by lazy{itemView.findViewById<ImageView>(R.id.ivIcon)}
			val tvTitle: TextView by lazy{itemView.findViewById<TextView>(R.id.tvTitle)}
			val tvSource: TextView by lazy{itemView.findViewById<TextView>(R.id.tvSource)}
			val ivLabel: ImageView by lazy{itemView.findViewById<ImageView>(R.id.ivLabel)}
			val tvHotNumber: TextView by lazy{itemView.findViewById<TextView>(R.id.tvHotNumber)}
		}
	}

设置recyclerView控件的adapter和layoutmanager。

	//在使用前定义adapter和layoutmanager即可。这里的binding.recyclerView主要是使用了ViewBinding的视图绑定方式
	var conManager=LinearLayoutManager(this)
	binding.recyclerView.layoutManager=conManager
	fun setAdapter(){
		val adapter=HotListAdapter(dataArray,context=this.getContext())
		binding.recycleView.adapter=adapter
	}

RecyclerView相关

LayoutManager布局管理器

LinearLayoutManager线性布局管理器,

共有三种构造方法
第一种构造方法
内部调用了第二种构造方法,

	public LinearLayoutManager(Context context){
		this(context,RecyclerView.DEFAULT_ORIENTATION,false);
	}

第二种构造方法

	/**
	*context 上下文,初始化时,构造方法内部加载资源
	*orientation 方向,默认为垂直,
	*reverseLayout 是否倒序,true时从最后一个item开始倒序加载,false相反。整体依靠下方,意思是当列表项总数高度小于屏幕展示高度且为铺满控件的高度,则显示在控件布局的下方。
	*/
	public LinearLayoutManager(Context context,@RecyclerView.Orientation int orientation,boolean reverseLayout){
		setOrientation(orientation);
		setReverseLayout(reverseLayout);
	}

第三种构造方法
使用的频率不多,主要是自定义属性的使用,根据优先级选择在不同的时机,根据需求来使用不同的样式。这部分只是稍微看了下自定义View构造函数这篇博客,以后如果实际中运用到时再去复习!!

	/**
	*attrs 属性值的合集,
	*defStyleAttr 这是当前Theme中的包含的一个指向style的引用.当我们没有给自定义View设置declare-styleable资源集合时,默认从这个集合里面查找布局文件中配置属性值.传入0表示不向该defStyleAttr中查找默认值.
	*defStyleRes 这个也是一个指向Style的资源ID,但是仅在defStyleAttr为0或者defStyleAttr不为0但Theme中没有为defStyleAttr属性赋值时起作用.
	*/
	public LinearLayoutManager(Context context,AttributeSet attrs,int defStyleAttr,int defStyleRes){
		Properties properties=getProperties(context,attrs,defStyleAttr,defStyleRes);
		setOrientation(properties.orientation);
		setReverseLayout(properties.reverseLayout);
		//When stack from bottom is set to true, the list fills its content starting from the bottom of the view.
		//设置为true时,RecycelrView会自动滑倒尾部,直到最后一条数据完整展示,不会影响内部的顺序,默认展示末尾的item
		setStackFromEnd(properties.stackFromEnd);
	}

StaggeredGridLayoutManager错列网格布局管理器

第一种

	//两个属性也不赘述
	public StaggeredGridLayoutManager(int spanCount,int orientation){
		mOrientation=orientation;
		setSpanCount(spanCount);
		mLayoutState=new LayoutState();
		createOrientationHelpers();
	}

第二种

	public StaggeredGridLayoutManager(Context context,AttributeSet attrs,int defStyleAttr,int defStyleRes){
		Properties properties=getProperties(context,attrs,defStyleAttr,defStyleRes);
		setOrientation(properties.orientation);
		setSpanCount(properties.spanCount);
		setReverseLayout(properties.reverseLayout);
		mLayoutState=new LayoutState();
		createOrientationHelpers();
	}

GridLayoutManager网格布局管理器

前两种布局管理器的综合,结合了LinearLayoutManager的反转和StaggeredGridLayoutManager的多列特点。也有三种构造方法
第一种

	/**
	*context ...不赘述
	*spanCount ,默认为垂直时显示列数
	*/
	public GridLayoutManager(Context context,int spanCount){
		super(context);
		setSaanCount(spanCount);
	}

第二种

	/*
	*context
	*spanCount 列数
	*orientation 方向
	*reverseLayout 是否反转
	*/
	public GridLayoutManager(Context context,int spanCount,@RecyclerView.orientation int orientation,boolean reverseLayout){
		super(context,orientation,reverseLayout);
		setSpanCount(spanCount);
	}

第三种
自定义属性,也不赘述

	public GridLayoutManager(Context context,AttributeSet attrs,int defStyleAttr,int defStyleRes){
		super(context,attrs,defStyleAttr,defStyleRes);
		Properties properties=getProperties(context,attrs,defStyleAttr,defStyleRes);
		setSpanCount(properties.spanCount);
	}

Adapter类相关

RecyclerView.Adapter<HotListAdapter.ViewHolder>
重写方法onCreateViewHolder,onBindVIewHolder,getItemCount

	//ViewHolder是自定义的内部类,用于绑定对应item的XML布局的各种控件
	override fun onCreateViewHolder(parent:ViewGroup,viewTyper:Int):ViewHolder{
		val view=LayoutInflater.from(parent.context).inflate(R.layout.xxx,parent,false)
		return ViewHolder(view)
	}

inflate详解

这里仔细看一下这行代码

//from是获得实例的方法。
val view=LayoutInflater.from(parent.context).inflate(R.layout.xxx,parent,false)

其中的inflate方法当时在设计出iten表项后,各个构造方法对item展示有很大的差异,所以也单独拿出来分析源码

	public View inflate(@LayoutRes int resource,@Nullable ViewGroup root){
		return inflate(resource,root,root≠null);
	}
	
	public View inflate(XmlPullParser parser,@Nullable ViewGroup root){
		return inflate(parser,root,root≠null);
	}
	/**
	*直接看第三个方法
	*resource 想要添加的布局
	*root 想要添加的布局的父布局
	*attachToRoot 是否直接添加到第二个参数的布局上面,true表示layout文件填充的View直接添加到parent,false表示创建的view会以其他方式添加进parent
	*/
	public View inflate(@LayoutRes int resource,@Nullable ViewGroup root,boolean attachToRoot){
		final Resources res=getContext().getResources();
		if(DEBUG){
			Log.d(TAG,"INFLATING from resource:\""+res.getResourceName(resource)+"\"("+Integer.toHexString(resource)+")");
		}
		View view=tryInflatePrecompiled(resource,res,root,attachRoot);
		if(view≠null){
			return view;
		}
		XmlResourceParser parser=res.getLayout(resource);
		try{
			return inflate(parser,root,attachToRoot);
		}finally{
			parser.close();
		}
	}

分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进