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}

几个重要的类:

  1. RecyclerView.Adapter:抽象类,为RecyclerView提供数据,一般根据不同的业务需求来编写具体的实现类。
  2. RecyclerView.LayoutManager:抽象类,主要用于测量RecyclerView的子Item,以及根据不同的布局方式来实现Item的布局效果,v7包自带的实现类有:LinearLayoutManager、StaggeredGridLayoutManager、GridLayoutManager。
  3. RecyclerView.ItemDecoration:抽象类,这个主要用于不同的Item之间添加分割线(可选)。官方没有实现类,所以如果要添加分割线,我们需要手动实现这个抽象类。
  4. RecyclerView.ItemAnimator:抽象类,这个主要用于当一个item添加或者删除的时候出现的动画效果,官方提供一个默认的实现类。如果想要使我们的RecyclerView在添加、删除数据的时候有炫酷的动画,可以实现这个抽象类。

使用RecyclerView的主要步骤:

  1. 引入RecyclerView
  2. 添加XML布局
  3. 封装Adapter适配器
  4. 封装RecyclerView.ViewHolder类
  5. 实现多布局展示
  6. 各布局控件监听

注:在此主要实现三种不同布局加载,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
原创粉丝点击