最近不是很忙写点东西,一来自己笔记,二来跟大家分享
我们在做项目的时候为了方便常常会引入一些开源的框架,但是本人觉得有些框架功能太多或者太过复杂,不利于自己项目维护或者杀鸡用牛刀。我本人还是比较热衷于使用系统原生的方式来实现,但也要适当的进行封装。下面讲我对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就可以了,减少类减少代码,达到封装的效果!!!