您的位置:首页 > 移动开发 > Android开发

Android RecyclerView与泛型 简单实现多布局

2017-04-18 14:08 330 查看
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添加或者删除的时候出现的动画效果,官方提供一个默认的实现类。如果想要使我们的RecyclerV
4000
iew在添加、删除数据的时候有炫酷的动画,可以实现这个抽象类。

使用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.ge
153e9
tPackageName());
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谢谢!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: