RecyclerView高级使用详解(多套布局,加载更多,监听)

    xiaoxiao2021-08-28  77

    原文/番茄And鸡蛋(简书作者) 原文链接:http://www.jianshu.com/p/7385e2bbb365 著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

    效果图

    实现原理

    1.多套布局

    利用RecyclerView的特性==》必须实现的ViewHolder类,在定义RecyclerView.Adapter时,在内部实现多个ViewHolder的类,根据不同需求的布局,获取到View后,分别在不同的ViewHolder中进行管理,处理数据时自动判断加载哪个布局。

    2.加载更多

    给RecyclerView设置滑动监听OnScrollListener,并重写里面的onScrollStateChanged和onScrolled方法,在RecyclerView的Item监听滑动到底部时,加载动画,并为Item添加数据,刷新适配器显示。

    3.点击事件

    在Adapter内部定义回调接口,onBindViewHolder中为需要设置监听的某个 view或者整条Item返回数据给调用者。

    在Activity中找到该RecyclerView后,需要设置如下属性

    public class MainActivity extends AppCompatActivity { private RecyclerView myRecyclerView; private LinearLayoutManager mLayoutManager; private MyRecyclerAdapter adapter; private boolean isLoading; private Handler handler = new Handler(); private List<Info> mEntity = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myRecyclerView = (RecyclerView) findViewById(R.id.myRecycler); mLayoutManager = new LinearLayoutManager(this); myRecyclerView.setLayoutManager(mLayoutManager); setMyAdapter(); loading(); }

    这里我为RecyclerView 设置了一个setLayoutManager的参数传入了LinearLayoutManager 的一个对象,这个参数是设置RecyclerView应该以什么样的形态出现,有三种形式:

    LinearLayoutManager==》普通列表型Item布局 GridLayoutManager==》Grid图片浏览型Item布局 StaggredGridLayoutManager==》瀑布流型Item布局 这里主要演示LinearLayoutManager,在XML中写好自己需要的布局。代码就不一一展示了,如图效果中一样,共三种布局。这里就有一个新型的进度条显示的Xml介绍给大家,我用于最底部的加载更多显示。

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:wheel="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="40dp" android:gravity="center" android:orientation="horizontal"> <com.pnikosis.materialishprogress.ProgressWheel android:layout_marginRight="10dp" android:id="@+id/rcv_load_more" android:layout_width="30dp" android:layout_height="30dp" android:layout_gravity="center" wheel:matProg_barColor="#039ae4" wheel:matProg_progressIndeterminate="true" /> <TextView android:layout_width="wrap_content" android:layout_height="30dp" android:gravity="center" android:text="正在加载更多..." android:textColor="@android:color/darker_gray" /> </LinearLayout>

    创建Adapter

    public class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener { public final static int TYPE_FOOTER = 2;//加载更多的布局,进度条显示 public final static int TYPE_NORMAL = 1;//Item的第一种布局 public final static int TYPE_NORTWO = 3;//Item的第二种布局 private Context mContext; private List<Info> mEntity; private MyRecyclerAdapter.OnRecyclerViewItemClickListener mOnItemClickListener = null; public interface OnRecyclerViewItemClickListener { void onItemClick(View view, int position); } public MyRecyclerAdapter(Context mContext) { this.mContext = mContext; } //构造函数,用于接收Context和传进来的数据 public MyRecyclerAdapter(Context mContext, List<Info> mEntity_WenTiList) { this.mContext = mContext; this.mEntity = mEntity_WenTiList; } //这里的监听是为了接收外面传递点击事件的数据 public void onClick(View v) { if (mOnItemClickListener != null) { //注意这里使用getTag方法获取数据 mOnItemClickListener.onItemClick(v, (int) v.getTag()); } } //自定义的Item响应事件需要接收OnRecyclerViewItemClickListener接口的函数 public void setOnItemClickListener(MyRecyclerAdapter.OnRecyclerViewItemClickListener listener) { this.mOnItemClickListener = listener; } //重写getItemViewType方法,接收不同的position信息,根据自己数据,判断来返回给onCreateViewHolder,选择加载的View布局 @Override public int getItemViewType(int position) { if (mEntity.get(position) == null) { //这个Null是在第一波数据完结时,添加进来的,作为判断加载更多的条件 return TYPE_FOOTER; } else if (position == 3 || position == 5 || position == 9 || position == 13 || position == 14 || position == 19) { return TYPE_NORTWO; } else { return TYPE_NORMAL; } } //根据不同的需求返回View布局 @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { RecyclerView.ViewHolder vh; View view; switch (viewType) { default: case TYPE_NORMAL: view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_wenti_recycler, parent, false); vh = new MyRecyclerAdapter.WenTiHolder(view); return vh; case TYPE_NORTWO: view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_image_recycler, parent, false); vh = new MyRecyclerAdapter.TwoHolder(view); return vh; case TYPE_FOOTER: view = LayoutInflater.from(parent.getContext()).inflate( R.layout.recyclerview_footer, parent, false); vh = new FooterViewHolder(view); return vh; } } //这里需要注意的是因为接收的ViewHolder 有三种不同的类型,所以应该分开来处理。 @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { if (holder instanceof FooterViewHolder) { ((FooterViewHolder) holder).rcvLoadMore.spin(); return; } if (holder instanceof WenTiHolder) { WenTiHolder newHolder = (WenTiHolder) holder; //给整条Item添加点击事件,因为是自定义的,可以写多种点击事件,或者点击限制等。 newHolder.itemView.setTag(position); newHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //接收到点击事件后,返回给外部数据回调 mOnItemClickListener.onItemClick(v, position); } }); } if (holder instanceof TwoHolder) { TwoHolder newHolder = (TwoHolder) holder; newHolder.itemView.setTag(position); newHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mOnItemClickListener.onItemClick(v, position); } }); } } //获取数据长度Item的个数 @Override public int getItemCount() { if (mEntity != null) { return mEntity.size(); } else { return 0; } } /** * 第一种布局 */ class WenTiHolder extends RecyclerView.ViewHolder { public WenTiHolder(View itemView) { super(itemView); } } /** * 第二种布局 */ class TwoHolder extends RecyclerView.ViewHolder { public TwoHolder(View itemView) { super(itemView); } } /** * 底部加载更多 */ class FooterViewHolder extends RecyclerView.ViewHolder { private ProgressWheel rcvLoadMore; public FooterViewHolder(View itemView) { super(itemView); rcvLoadMore = (ProgressWheel) itemView.findViewById(R.id.rcv_load_more); } } }

    三,绑定适配器设置加载更多

    public List<Info> iniData() { Info info = new Info(); for (int i = 0; i < 10; i++) { info.setBq(i + 1 + ""); info.setContext("aa"); info.setTime("14:11"); info.setTitle("bjnsdkjas"); mEntity.add(info); } mEntity.add(null); return mEntity; } //添加适配器设置 private void setMyAdapter(){ adapter = new MyRecyclerAdapter(this, iniData()); adapter.setOnItemClickListener(new MyRecyclerAdapter.OnRecyclerViewItemClickListener() { @Override public void onItemClick(View view, int position) { } }); myRecyclerView.setAdapter(adapter); } //加载更多,每次10条 private void loading() { myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int lastVisibleItemPosition = mLayoutManager.findLastVisibleItemPosition(); if (lastVisibleItemPosition + 1 == adapter.getItemCount()) { if (!isLoading) { isLoading = true; handler.postDelayed(new Runnable() { @Override public void run() { mEntity.remove(mEntity.size() - 1); iniData(); adapter.notifyDataSetChanged(); isLoading = false; } }, 3000); } } } }); }

    原文/番茄And鸡蛋(简书作者)原文链接:http://www.jianshu.com/p/7385e2bbb365著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

    转载请注明原文地址: https://ju.6miu.com/read-677288.html

    最新回复(0)