Android RecyclerView适配器简单封装,使用方便、简洁

最近不是很忙写点东西,一来自己笔记,二来跟大家分享

我们在做项目的时候为了方便常常会引入一些开源的框架,但是本人觉得有些框架功能太多或者太过复杂,不利于自己项目维护或者杀鸡用牛刀。我本人还是比较热衷于使用系统原生的方式来实现,但也要适当的进行封装。下面讲我对RecyclerView的简单使用封装分享给大家。直接上代码吧!!

1、定义的adapter基类

package com.app.base.listview;

import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by pwe on 2019/3/6.
 */

public abstract class BaseAdapter extends RecyclerView.Adapter {
    private SparseArray layoutResIds;
    private List mData;

    public BaseAdapter(@Nullable List data, @LayoutRes int layoutResId) {
        this.mData = data == null ? new ArrayList() : data;
        if (layoutResId != 0) {
            addLayoutResId(-1,layoutResId);
        }
    }

    public BaseAdapter(@Nullable List data) {
        this(data,0);
    }

    protected void addLayoutResId(int viewType, @LayoutRes int layoutResId) {
        if (layoutResIds == null) {
            layoutResIds = new SparseArray<>();
        }
        layoutResIds.put(viewType, layoutResId);
    }

    @NonNull
    @Override
    public K onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        int layoutResId = getLayoutResId(viewType);
        if (layoutResId > 0){
            return createBaseViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(layoutResId, viewGroup, false));
        }
        return null;
    }

    private int getLayoutResId(int viewType){
        if (layoutResIds != null){
            int layoutResId = layoutResIds.get(viewType,0);
            if (layoutResId == 0){//get default
                layoutResId = layoutResIds.get(-1,0);
            }
            return layoutResId;
        }
        return 0;
    }

    private K createBaseViewHolder(View view) {
        Class temp = getClass();
        Class z = null;
        while (z == null && temp != null) {
            z = getInstancedGenericKClass(temp);
            temp = temp.getSuperclass();
        }
        K k = createGenericKInstance(z, view);
        return k != null ? k : (K) new ViewHolderImp(view);
    }

    private Class getInstancedGenericKClass(Class z) {
        Type type = z.getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            Type[] types = ((ParameterizedType) type).getActualTypeArguments();
            for (Type temp : types) {
                if (temp instanceof Class) {
                    Class tempClass = (Class) temp;
                    if (ViewHolder.class.isAssignableFrom(tempClass)) {
                        return tempClass;
                    }
                }
            }
        }
        return null;
    }

    private K createGenericKInstance(Class z, View view) {
        try {
            Constructor constructor;
            if (z.isMemberClass() && !Modifier.isStatic(z.getModifiers())) {
                constructor = z.getDeclaredConstructor(getClass(), View.class);
                constructor.setAccessible(true);
                return (K) constructor.newInstance(this, view);
            } else {
                constructor = z.getDeclaredConstructor(View.class);
                constructor.setAccessible(true);
                return (K) constructor.newInstance(view);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull K viewHolder, int position) {
        if (mData != null && position < mData.size()) {
            bindData(viewHolder,mData.get(position));
        }
    }

    protected abstract void bindData(K viewHolder, T item);

    @Override
    public int getItemCount() {
        return mData  == null? 0 : mData.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (mData != null && mData.size() > 0){
            T t = mData.get(position);
            if (t != null && t instanceof ItemEntity){
                return ((ItemEntity)t).getViewType();
            }
        }
        return super.getItemViewType(position);
    }
}

2、定义公用的ViewHolder。我们可以在这定义设置控件属性的方法。

package com.app.base.listview;

import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Created by pwe on 2019/3/6.
 */

public abstract class ViewHolder extends RecyclerView.ViewHolder{

    public ViewHolder(@NonNull View view){
        super(view);
    }

    public abstract  T getViewById(@IdRes int id);

    public abstract ViewHolder setText(@IdRes int id,String text);

    public abstract ViewHolder setTextColor(@IdRes int id, @ColorInt int color);

    public abstract ViewHolder setImageResource(@IdRes int id, @DrawableRes int imageResId);

    public abstract ViewHolder setVisible(@IdRes int id, boolean visible);

    public abstract ViewHolder setChecked(@IdRes int id, boolean checked);
}

 

package com.app.base.listview;

import android.support.annotation.DrawableRes;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.util.SparseArray;
import android.view.View;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * Created by pwe on 2019/3/6.
 */

final class ViewHolderImp extends ViewHolder {
    private final SparseArray views;

    public ViewHolderImp(@NonNull View view){
        super(view);
        this.views = new SparseArray<>();
    }

    @Override
    public  T getViewById(@IdRes int id) {
        View view = views.get(id);
        if (view == null) {
            view = itemView.findViewById(id);
            views.put(id, view);
        }
        return (T) view;
    }

    @Override
    public ViewHolder setText(int id, String text) {
        View view = getViewById(id);
        if (view != null && view instanceof TextView){
            ((TextView)view).setText(text);
        }
        return this;
    }

    @Override
    public ViewHolder setTextColor(int id, int color) {
        View view = getViewById(id);
        if (view != null && view instanceof TextView){
            ((TextView)view).setTextColor(color);
        }
        return this;
    }

    @Override
    public ViewHolder setImageResource(@IdRes int id, @DrawableRes int imageResId) {
        View view = getViewById(id);
        if (view != null && view instanceof ImageView){
            ((ImageView)view).setImageResource(imageResId);
        }
        return this;
    }

    @Override
    public ViewHolder setVisible(int id, boolean visible) {
        View view = getViewById(id);
        if (view != null) {
            view.setVisibility(visible ? View.VISIBLE : View.GONE);
        }
        return this;
    }

    @Override
    public ViewHolder setChecked(int id, boolean checked) {
        View view = getViewById(id);
        if (view != null && view instanceof Checkable) {
            ((Checkable) view).setChecked(checked);
        }
        return this;
    }
}

 

3、定义ItemEntity接口,用于扩展多item样式的情况viewtype

package com.app.base.listview;

/**
 * Created by pwe on 2019/3/7.
 */

public interface ItemEntity {

    int getViewType();
}

3、接下来使用示例,(1)、我们只要定义一个adapter继承BaseAdapter,若只是单一item样式情况,我们可以直接使用TestAdapter中的super(data,R.layout.item),多item样式情况如下图。(2)、多item样式情况下,我们的bean实体要实现ItemEntity接口,并设置不同的viewType。

package com.app.myapplication;

import android.view.View;

import com.app.base.listview.BaseAdapter;
import com.app.base.listview.ViewHolder;

import java.util.List;

/**
 * Created by pwe on 2019/3/6.
 */

public class TestAdapter extends BaseAdapter{

    public TestAdapter(List data) {
        super(data);
        addLayoutResId(0, R.layout.item_test);
        addLayoutResId(1, R.layout.item_test2);
    }

    @Override
    protected void bindData(ViewHolder holder, TestBean item) {
        if (holder.getItemViewType() == 0){
            //获取view
            holder.getViewById(R.id.text);
            //显示文本
            holder.setText(R.id.text,item.test);
            //显示图片
            holder.setImageResource(R.id.image,R.mipmap.ic_launcher);
            //设置条目点击事件
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });
        }else if(holder.getItemViewType() == 1){
            holder.setText(R.id.text2,item.test);
        }
    }
}

 

mRecycleView = findViewById(R.id.listview);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mRecycleView.setLayoutManager(layoutManager);
        List list = new ArrayList<>();
        for (int i = 0;i<10;i++){
            list.add(new TestBean(i,"haha"+i));
        }
        TestAdapter mdapter = new TestAdapter(list);
        mRecycleView.setAdapter(mdapter);

所有代码就是这么简单,这样封装以后就不用所有人都得每个列表页面定义一个ViewHolder了,直接定义一个adapter继承BaseAdapter就可以了,减少类减少代码,达到封装的效果!!!

你可能感兴趣的:(RecyclerView,android)