android RecyclerView实现加载多种item的样式布局
在实际的应用中列表经常是图文并茂的形式展示,这也就需要在一个RecyclerView中加载不一样的模板文件。
首先准备需要加载的模板文件,这里准备了2个模板文件
item_multi_one.xml 文件
<?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/title" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="我的标题" /> </LinearLayout>
item_multi_third.xml 文件
<?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" android:background="#DF0303" > <ImageView android:id="@+id/photo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" android:layout_gravity="center_horizontal" /> <TextView android:id="@+id/title" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="图文并排" /> </LinearLayout>
activity_main.xml 文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" > <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent"> </androidx.recyclerview.widget.RecyclerView> </LinearLayout>
到这里基本的XML文件就准备齐全了
接下来看 自定义的 RvAdapter文件
package jz.app.myapplication.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import jz.app.myapplication.R; public class RvAdapter extends RecyclerView.Adapter { public interface OnItemClickListener{ void onItemClick(View view,int position); //void onItemLongClick(View view,int position); } private Context mContext; private ArrayList<Bean> mlist; public OnItemClickListener mOnItemClickListener; private static int VIEW_TYPE_1=1; private static int VIEW_TYPE_2=2; public RvAdapter(Context mContext,ArrayList mlist){ this.mContext=mContext; this.mlist = mlist; } public void setmOnItemClickListener(OnItemClickListener mOnItemClickListener){ this.mOnItemClickListener=mOnItemClickListener; } @Override public int getItemViewType(int position) { if(mlist.get(position).getType()==VIEW_TYPE_1){ return VIEW_TYPE_1; } return VIEW_TYPE_2; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { if(viewType == VIEW_TYPE_1){ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_one,parent,false); return new Holder1(view); } else{ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_third,parent,false); return new Holder2(view); } } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if(holder instanceof Holder1){ Holder1 holder1 = (Holder1) holder; holder1.Tvtitle.setText(mlist.get(position).getTitle()); }else{ Holder2 holder2 = (Holder2) holder; holder2.Tvtitle.setText(mlist.get(position).getTitle()); } if(mOnItemClickListener != null){ holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //Toast.makeText(mContext,position + "",Toast.LENGTH_LONG).show(); int pos = holder.getLayoutPosition(); mOnItemClickListener.onItemClick(holder.itemView,pos); } }); // holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { // @Override // public boolean onLongClick(View view) { // int pos = holder.getLayoutPosition(); // mOnItemClickListener.onItemLongClick(holder.itemView,pos); // return false; // } // }); } } @Override public int getItemCount() { return mlist.size(); } public class Holder1 extends RecyclerView.ViewHolder{ private TextView Tvtitle; public Holder1(@NonNull View itemView) { super(itemView); Tvtitle = (TextView) itemView.findViewById(R.id.title); } } public class Holder2 extends RecyclerView.ViewHolder{ private TextView Tvtitle; public Holder2(@NonNull View itemView) { super(itemView); Tvtitle =(TextView)itemView.findViewById(R.id.title); } } }
这里定义两个常量 VIEW_TYPE_1跟VIEW_TYPE_2 这两个是用来区分加载哪一个模板文件的。
在这里还需要实现一个方法
@Override public int getItemViewType(int position) { if(mlist.get(position).getType()==VIEW_TYPE_1){ return VIEW_TYPE_1; } return VIEW_TYPE_2; }
在传过来的数据里面定义好模板文件参数,在这个函数里面进行比较。
在 OnCreateViewHolder 这个函数进行模板加载
@NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { if(viewType == VIEW_TYPE_1){ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_one,parent,false); return new Holder1(view); } else{ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_third,parent,false); return new Holder2(view); } }
这里需要分别创建 Holder1 跟 Holder2分别继承自 RecyclerView.ViewHolder。
在 OnBindViewHolder函数里面 通过 instanceof 方法对不同的模板进行数据绑定。
if(holder instanceof Holder1){ Holder1 holder1 = (Holder1) holder; holder1.Tvtitle.setText(mlist.get(position).getTitle()); }else{ Holder2 holder2 = (Holder2) holder; holder2.Tvtitle.setText(mlist.get(position).getTitle()); }
另外 在上面的实例里面还是实现了 OnItemClickLinster 接口,这里实现了 onItemClick 方法。
public interface OnItemClickListener{ void onItemClick(View view,int position); //void onItemLongClick(View view,int position); }
现在来看 mainActivity.java 文件,一下文件包含了测试数据,拷贝可以直接运行效果。
package jz.app.myapplication; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import android.view.View; import android.widget.Toast; import java.util.ArrayList; import jz.app.myapplication.adapter.Bean; import jz.app.myapplication.adapter.RvAdapter; public class MainActivity extends AppCompatActivity { private RecyclerView rv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); rv = (RecyclerView) findViewById(R.id.rv); ArrayList<Bean> list = new ArrayList<>(); Bean a = new Bean(); a.setType(1); a.setTitle("标题1"); list.add(a); Bean b = new Bean(); b.setType(1); b.setTitle("模板1"); list.add(b); Bean c = new Bean(); c.setType(2); c.setTitle("模板2"); list.add(c); Bean e = new Bean(); e.setType(1); e.setTitle("加载了模板1"); list.add(e); Bean f = new Bean(); f.setType(1); f.setTitle("加载第一个模板 one"); list.add(f); Bean d = new Bean(); d.setType(2); d.setTitle("加载模板2"); list.add(d); Bean g = new Bean(); g.setType(1); g.setTitle("加载模板1"); list.add(g); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); rv.setLayoutManager(linearLayoutManager); RvAdapter myAdapter = new RvAdapter(this,list); myAdapter.setmOnItemClickListener(new RvAdapter.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Toast.makeText(MainActivity.this,"点击了位置:"+position ,Toast.LENGTH_LONG).show(); } // @Override // public void onItemLongClick(View view, int position) { // // Toast.makeText(MainActivity.this,"长按了"+position+",触了提示",Toast.LENGTH_LONG).show(); // } }); rv.setAdapter(myAdapter); } }