Android RecyclerView与泛型 简单实现多布局
来源:互联网 发布:网站搜索排名优化 编辑:程序博客网 时间:2024/06/05 07:43
RecyclerView简介:
谷歌在support v7中,加入了新的控件——RecyclerView,该控件整合了ListView、GridView的特点,而且最大的优点是可以很方便实现瀑布流效果,多布局控制效果等等,因此RecyclerView受到越来越多的开发者重视。
引入RecyclerView
由于该控件并不在Andorid SDK中的,而是在support v7包中,因此我们要手动添加该控件。
在build.gradle中添加如下依赖:
dependencies { ... compile 'com.android.support:appcompat-v7:23.1.1' //Toolbar compile 'com.android.support:recyclerview-v7:23.1.1' //RecyclerView}
几个重要的类:
- RecyclerView.Adapter:抽象类,为RecyclerView提供数据,一般根据不同的业务需求来编写具体的实现类。
- RecyclerView.LayoutManager:抽象类,主要用于测量RecyclerView的子Item,以及根据不同的布局方式来实现Item的布局效果,v7包自带的实现类有:LinearLayoutManager、StaggeredGridLayoutManager、GridLayoutManager。
- RecyclerView.ItemDecoration:抽象类,这个主要用于不同的Item之间添加分割线(可选)。官方没有实现类,所以如果要添加分割线,我们需要手动实现这个抽象类。
- RecyclerView.ItemAnimator:抽象类,这个主要用于当一个item添加或者删除的时候出现的动画效果,官方提供一个默认的实现类。如果想要使我们的RecyclerView在添加、删除数据的时候有炫酷的动画,可以实现这个抽象类。
使用RecyclerView的主要步骤:
- 引入RecyclerView
- 添加XML布局
- 封装Adapter适配器
- 封装RecyclerView.ViewHolder类
- 实现多布局展示
- 各布局控件监听
注:在此主要实现三种不同布局加载,RecyclerView监听及子布局监听
MyAdapter类代码:
package com.example.administrator.foundationdemo.recyclerview;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.View;import android.view.ViewGroup;import com.example.administrator.foundationdemo.R;import java.util.List;/** * Created by "sinlov" on 2017/4/12. */public abstract class MyAdapter extends RecyclerView.Adapter<MyViewHolder> { private int mLayoutId; private Context mContext; private List<Data> mDataSet; /** * 构造器,接受数据集 * @param data */ public MyAdapter(Context context,List<Data> data){ mContext = context; mDataSet = data; } /** * onCreateViewHolder:创建ViewHolder, * 该方法会在RecyclerView需要展示一个item的时候回调。 * 重写该方法时,应该使ViewHolder加载item view的布局。 * 这个能发避免了不必要的findViewById操作,提高了性能。 * * @param parent * @param viewType * @return */ @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //加载布局文件 switch (viewType){ case ViewItems.TEMPLATE_1: break; case ViewItems.TEMPLATE_2: mLayoutId = R.layout.activity_recycler_view_recyclerview_item_my; break; case ViewItems.TEMPLATE_3: break; case ViewItems.TEMPLATE_4: break; case ViewItems.TEMPLATE_5: mLayoutId = R.layout.activity_recycler_view_recyclerview_item_ordinary_notification_1; break; case ViewItems.TEMPLATE_6: mLayoutId = R.layout.activity_recycler_view_recyclerview_item_ordinary_notification_2; break; } MyViewHolder holder = MyViewHolder.get(mContext,null,parent,mLayoutId); setListener(parent, holder); return holder; } /** * onBindeViewHolder:该方法在RecyclerView在特定位置展示数据时候回调,顾名思义,把数据绑定、填充到相应的item view中 * * @param holder * @param position */ @Override public void onBindViewHolder(MyViewHolder holder, int position) { //将数据填充到具体的view中 convert(holder,mDataSet.get(position)); } public abstract void convert(MyViewHolder holder, Data t); /** * 通过重写getItemViewType(int position)方法来告诉onCreateViewHolder(...)每个条目对应的布局 * @param position * @return */ @Override public int getItemViewType(int position) { return mDataSet.get(position).getViewType(); } /** * getItemCount:返回数据的数量 * @return */ @Override public int getItemCount() { return mDataSet.size(); } /** * java回调机制,依赖于子Item View的onClickListener及onLongClickListener。 * @param <T> //数据类 */ public interface OnItemClickListener<T>{ //RecyclerView监听 void onItemClick(ViewGroup parent, View view, T t, int position); } public interface OnItemLongClickListener<T>{ //长按监听 boolean onItemLongClick(ViewGroup parent, View view, T t, int position); } private OnItemClickListener mOnItemClickListener; private OnItemLongClickListener mOnItemLongClickListener; public void setOnItemClickListener(OnItemClickListener mOnItemClickListener){ this.mOnItemClickListener = mOnItemClickListener; } public void setOnItemLongClickListener(OnItemLongClickListener mOnItemLongClickListener) { this.mOnItemLongClickListener = mOnItemLongClickListener; } protected void setListener(final ViewGroup parent, final MyViewHolder holder){ //判断是否设置了监听器 if(mOnItemClickListener != null) { //为ItemView设置监听器 holder.getConvertView().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = holder.getLayoutPosition(); mOnItemClickListener.onItemClick(parent, v, mDataSet.get(position), position); } }); } if(mOnItemLongClickListener != null){ holder.getConvertView().setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (mOnItemLongClickListener != null) { int position = holder.getLayoutPosition(); return mOnItemLongClickListener.onItemLongClick(parent, v, mDataSet.get(position), position); //返回true 表示消耗了事件 事件不会继续传递 } return false; } }); } }}
MyViewHolder类代码:
package com.example.administrator.foundationdemo.recyclerview;import android.content.Context;import android.graphics.Bitmap;import android.graphics.drawable.Drawable;import android.support.v7.widget.RecyclerView;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;/** * Created by "sinlov" on 2017/4/13. */public class MyViewHolder extends RecyclerView.ViewHolder { private SparseArray<View> mViews; private View mConvertView; private Context mContext; private int mLayoutId; public MyViewHolder(Context context, View itemView, ViewGroup parent) { super(itemView); //由于itemView是item的布局文件,我们需要的是里面的textView,因此利用itemView.findViewById获 //取里面的View实例,后面通过onBindViewHolder方法能直接填充数据到每一个View了 mContext = context; mConvertView = itemView; //运用泛型,适配所有的View,多布局,不用写多个RecyclerView.ViewHolder。 mViews = new SparseArray<View>(); mConvertView.setTag(this); } //缓存 public static MyViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId){ if(null==convertView){ View itemView = LayoutInflater.from(context).inflate(layoutId, parent, false); MyViewHolder holder = new MyViewHolder(context, itemView, parent); holder.mLayoutId = layoutId; return holder; }else { MyViewHolder holder = (MyViewHolder) convertView.getTag(); return holder; } } /** * 通过viewId获取控件 * * @param viewId * @return */ public <T extends View> T getView(int viewId) { View view = mViews.get(viewId); if (view == null) { view = mConvertView.findViewById(viewId); mViews.put(viewId, view); } return (T) view; } public View getConvertView() { return mConvertView; } /** * 设置TextView的值 * * @param viewId * @param text * @return */ public MyViewHolder setText(int viewId, String text) { TextView tv = getView(viewId); tv.setText(text); return this; } public MyViewHolder setImageResource(int viewId, int resId) { ImageView view = getView(viewId); view.setImageResource(resId); return this; } public MyViewHolder setImageBitmap(int viewId, Bitmap bitmap) { ImageView view = getView(viewId); view.setImageBitmap(bitmap); return this; } public MyViewHolder setImageDrawable(int viewId, Drawable drawable) { ImageView view = getView(viewId); view.setImageDrawable(drawable); return this; } public MyViewHolder setBackgroundColor(int viewId, int color) { View view = getView(viewId); view.setBackgroundColor(color); return this; } public MyViewHolder setBackgroundRes(int viewId, int backgroundRes) { View view = getView(viewId); view.setBackgroundResource(backgroundRes); return this; } public MyViewHolder setTextColor(int viewId, int textColor) { TextView view = getView(viewId); view.setTextColor(textColor); return this; } public MyViewHolder setTextColorRes(int viewId, int textColorRes) { TextView view = getView(viewId); view.setTextColor(mContext.getResources().getColor(textColorRes)); return this; } public int getDrawableId(String drawableName){ int resId = mContext.getResources().getIdentifier(drawableName,"drawable",mContext.getPackageName()); return resId; }}
RecyclerViewActivity类代码:
package com.example.administrator.foundationdemo.recyclerview;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import com.example.administrator.foundationdemo.R;import java.util.ArrayList;import java.util.List;public class RecyclerViewActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private MyAdapter mAdapter; private List<Data> mData; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recycler_view); initData(); initRecyclerView(); } private void initData() { mData = new ArrayList<Data>(); mData.add(new Data(1,"枫阳","recycler_my","FLY346422332","recycler_two")); mData.add(new Data(4,"相册","recycler_photo")); mData.add(new Data(5,"收藏","recycler_collect")); mData.add(new Data(4, "钱包", "recycler_money")); mData.add(new Data(5, "卡包", "recycler_card")); mData.add(new Data(4, "表情", "recycler_expression")); mData.add(new Data(4, "设置", "recycler_install")); } private void initRecyclerView() { //1 实例化RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview); //2 为RecyclerView创建布局管理器,这里使用的是LinearLayoutManager,表示里面的Item排列是线性排列 mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); handlerRecyclerView(); //3 设置数据适配器 mRecyclerView.setAdapter(mAdapter); } private void handlerRecyclerView() { mAdapter = new MyAdapter(this, mData) { @Override public void convert(MyViewHolder holder, Data data) { switch (data.getViewType()){ case ViewItems.TEMPLATE_2: handlerTemplate2(holder,data); break; case ViewItems.TEMPLATE_5: handlerTemplate5(holder,data); break; case ViewItems.TEMPLATE_6: handlerTemplate6(holder,data); break; default: Log.d("FLY","错误了"); break; } } }; mAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() { @Override public void onItemClick(ViewGroup parent, View view, Object o, int position) { Data data = (Data) o; Toast.makeText(RecyclerViewActivity.this, data.getName() + ": " + position, Toast.LENGTH_SHORT).show(); } }); } private void handlerTemplate2(MyViewHolder holder, Data data){ ImageView photo = holder.getView(R.id.recyclerview_item_my_photo); photo.setImageResource(holder.getDrawableId(data.getLogo())); TextView name = holder.getView(R.id.recyclerview_item_my_name); name.setText(data.getName()); TextView number = holder.getView(R.id.recyclerview_item_my_number); number.setText("微信号: " + data.getNotificationText()); ImageView two = holder.getView(R.id.recyclerview_item_my_two); two.setImageResource(holder.getDrawableId(data.getNotificationImg())); two.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(RecyclerViewActivity.this,"two 000000 ",Toast.LENGTH_SHORT).show(); } }); } private void handlerTemplate5(MyViewHolder holder, Data data){ ImageView photo = holder.getView(R.id.recyclerview_item_ordinary_1_img); photo.setImageResource(holder.getDrawableId(data.getLogo())); TextView name = holder.getView(R.id.recyclerview_item_ordinary_1_text); name.setText(data.getName()); if (null!= data.getNotificationText() ){ TextView number = holder.getView(R.id.recyclerview_item_notification_1_img); number.setVisibility(View.VISIBLE); number.setText(data.getNotificationText()); } if (null != data.getNotificationImg()){ ImageView two = holder.getView(R.id.recyclerview_item_notification_1_text); two.setVisibility(View.VISIBLE); two.setImageResource(holder.getDrawableId(data.getNotificationImg())); } } private void handlerTemplate6(MyViewHolder holder, Data data){ ImageView photo = holder.getView(R.id.recyclerview_item_ordinary_2_img); photo.setImageResource(holder.getDrawableId(data.getLogo())); TextView name = holder.getView(R.id.recyclerview_item_ordinary_2_text); name.setText(data.getName()); if (null!= data.getNotificationText() ){ TextView number = holder.getView(R.id.recyclerview_item_notification_2_img); number.setVisibility(View.VISIBLE); number.setText(data.getNotificationText()); } if (null != data.getNotificationImg()){ ImageView two = holder.getView(R.id.recyclerview_item_notification_2_text); two.setVisibility(View.VISIBLE); two.setImageResource(holder.getDrawableId(data.getNotificationImg())); } }}
Deta数据类代码:
package com.example.administrator.foundationdemo.recyclerview;/** * Created by "sinlov" on 2017/4/13. */public class Data { private int viewType; private String name; private String logo; private String notificationText; private String notificationImg; public Data(){ } public Data(int viewType, String name, String logo) { this.viewType = viewType; this.name = name; this.logo = logo; } public Data(int viewType, String name, String logo, String notificationText, String notificationImg) { this.viewType = viewType; this.name = name; this.logo = logo; this.notificationText = notificationText; this.notificationImg = notificationImg; } public int getViewType() { return viewType; } public void setViewType(int viewType) { this.viewType = viewType; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLogo() { return logo; } public void setLogo(String logo) { this.logo = logo; } public String getNotificationText() { return notificationText; } public void setNotificationText(String notificationText) { this.notificationText = notificationText; } public String getNotificationImg() { return notificationImg; } public void setNotificationImg(String notificationImg) { this.notificationImg = notificationImg; }}
ViewItems类代码:
package com.example.administrator.foundationdemo.recyclerview;/** * Created by HooRang on 2017/2/22. */public class ViewItems { /*分别对应R.layout.activity_recycler_view_recyclerview_item_x*/ //chat public static final int TEMPLATE_1 = 0x0; //my public static final int TEMPLATE_2 = 0x1; public static final int TEMPLATE_3 = 0x2; //ordinary public static final int TEMPLATE_4 = 0x3; //ordinary_notification_1 public static final int TEMPLATE_5 = 0x4; //ordinary_notification_2 public static final int TEMPLATE_6 = 0x5;}
activity_recycler_view 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:toolbar="http://schemas.android.com/apk/res-auto" style="@style/MatchMatch" android:background="#d2caca" tools:context="com.example.administrator.foundationdemo.recyclerview.RecyclerViewActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" style="@style/MatchMatch"/></LinearLayout>
activity_recycler_view_recyclerview_item_my XML布局代码:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:background="#fcfcfc" android:layout_marginTop ="25dp" android:layout_width="match_parent" android:layout_height="65dp"> <RelativeLayout android:id="@+id/recyclerview_item_my_relative" android:layout_width="0dp" android:background="@null" android:layout_height="match_parent" android:layout_weight="5"> <ImageView android:id="@+id/recyclerview_item_my_photo" android:layout_width="50dp" android:layout_height="50dp" android:background="@null" android:layout_centerVertical="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginLeft="20dp" android:layout_marginStart="20dp" android:src="@mipmap/ic_launcher" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="15sp" android:textStyle="bold" android:text="测试" android:id="@+id/recyclerview_item_my_name" android:layout_alignTop="@+id/recyclerview_item_my_photo" android:layout_toRightOf="@+id/recyclerview_item_my_photo" android:layout_toEndOf="@+id/recyclerview_item_my_photo" android:layout_marginLeft="20dp" android:layout_marginStart="20dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="10sp" android:text="测试" android:id="@+id/recyclerview_item_my_number" android:layout_marginTop ="5dp" android:layout_below="@id/recyclerview_item_my_name" android:layout_alignLeft="@id/recyclerview_item_my_name" android:layout_alignStart="@id/recyclerview_item_my_name" /> </RelativeLayout> <RelativeLayout android:background="@null" android:id="@+id/recyclerview_item_my_two_relative" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="0.8"> <ImageView android:id="@+id/recyclerview_item_my_two" android:background="@null" android:src="@mipmap/ic_launcher" style="@style/WrapWrap" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> </RelativeLayout></LinearLayout>
activity_recycler_view_recyclerview_item_ordinary_notification_1 XML布局代码:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginTop ="25dp" android:background="#fcfcfc" android:orientation="vertical"> <ImageView android:id="@+id/recyclerview_item_ordinary_1_img" style="@style/WrapWrap" android:background="@null" android:layout_centerVertical="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginLeft="25dp" android:layout_marginStart="25dp" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/recyclerview_item_ordinary_1_text" style="@style/WrapWrap" android:textSize="15sp" android:text="测试" android:background="@null" android:layout_centerVertical="true" android:layout_toRightOf="@id/recyclerview_item_ordinary_1_img" android:layout_toEndOf="@id/recyclerview_item_ordinary_1_img" android:layout_marginLeft="25dp" android:layout_marginStart="25dp" /> <ImageView android:visibility="gone" android:layout_width="35dp" android:layout_height="35dp" android:id="@+id/recyclerview_item_notification_1_img" android:background="@null" android:src="@mipmap/ic_launcher" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_marginRight="25dp" android:layout_marginEnd="25dp" /> <TextView android:id="@+id/recyclerview_item_notification_1_text" style="@style/WrapWrap" android:textSize="10sp" android:visibility="gone" android:text="测试" android:background="@null" android:layout_centerVertical="true" android:layout_toLeftOf="@id/recyclerview_item_notification_1_img" android:layout_toStartOf="@id/recyclerview_item_notification_1_img" android:layout_marginRight="25dp" android:layout_marginEnd="25dp" /></RelativeLayout>
activity_recycler_view_recyclerview_item_ordinary_notification_2 XML布局代码:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#fcfcfc" android:orientation="vertical"> <TextView android:background="#d2caca" android:layout_width="match_parent" android:layout_height="1.5dp" android:layout_marginLeft="25dp" android:layout_marginRight="25dp" android:id="@+id/textView_null" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="@null" android:layout_below="@+id/textView_null" android:layout_alignParentLeft="true" android:layout_alignParentStart="true"> <ImageView android:id="@+id/recyclerview_item_ordinary_2_img" style="@style/WrapWrap" android:background="@null" android:layout_centerVertical="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginLeft="25dp" android:layout_marginStart="25dp" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/recyclerview_item_ordinary_2_text" style="@style/WrapWrap" android:textSize="15sp" android:text="测试" android:background="@null" android:layout_centerVertical="true" android:layout_toRightOf="@id/recyclerview_item_ordinary_2_img" android:layout_toEndOf="@id/recyclerview_item_ordinary_2_img" android:layout_marginLeft="25dp" android:layout_marginStart="25dp" /> <ImageView android:visibility="gone" android:layout_width="35dp" android:layout_height="35dp" android:id="@+id/recyclerview_item_notification_2_img" android:background="@null" android:src="@mipmap/ic_launcher" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_marginRight="25dp" android:layout_marginEnd="25dp" /> <TextView android:visibility="gone" android:id="@+id/recyclerview_item_notification_2_text" style="@style/WrapWrap" android:textSize="10sp" android:text="测试" android:background="@null" android:layout_centerVertical="true" android:layout_toLeftOf="@id/recyclerview_item_notification_2_img" android:layout_toStartOf="@id/recyclerview_item_notification_2_img" android:layout_marginRight="25dp" android:layout_marginEnd="25dp" /> </RelativeLayout></RelativeLayout>
希望对你们有帮助,O(∩_∩)O谢谢!!!
0 0
- Android RecyclerView与泛型 简单实现多布局
- Android RecyclerView加载不同布局简单实现
- 一个简单的RecyclerView多布局实现
- RecyclerView多布局的简单实现
- RecyclerView多布局的简单实现
- Android RecyclerView 多布局与混排
- Android RecyclerView 多布局与混排
- RecyclerView实现多布局
- 实现RecyclerView多布局
- RecyclerView多布局实现
- RecyclerView多布局实现
- Android recyclerView 多布局
- Android 使用RecyclerView实现多列布局及其优劣
- Android简单的实现RecyclerView
- Android 流式布局-FlexboxLayout与RecyclerView
- RecyclerView实现复杂布局
- Android RecyclerView 详解(五) RecyclerView多布局的使用
- RecyclerView多布局与Item点击事件
- LeetcodeUnique Paths
- ArcGIS Engine实现图层间空间选择的优化策略
- FBX SDK
- Eclipse写代码快捷(更新ing)
- NGINX高性能Web服务器详解(读书笔记)
- Android RecyclerView与泛型 简单实现多布局
- Arena777 Live Casino Unlimited Rebate 0.5%(arena777, arena777 casino malaysia, live casino, Rebate B
- APP测试学习之造轮子--基于MINA框架的NIO2
- android 源码编译详解【一】:服务器硬件配置及机型推荐-2016/06
- 使用Java注解来简化你的代码
- 有趣的机器学习:最简明入门指南
- 常用命令速查备忘
- Mac系统终端命令行不执行命令 总出现command not found解决方法
- 让你系统的了解shell