本篇博文是在之前的基础之上进行了封装与抽象的。主要是思想是通过封装一个通用ViewHolder,来解耦和提高通用性。
如果你没看过我之前写的Adapter的封装与抽象,建议先看下,这样对看本片博文思路有帮助。下面有相关博文的链接。
首先是通用的ViewHolder,通过Adapter 每一个Item的convertView来实例化一个ViewHolder,然后根据控件的id得到相对应的控件,ViewHolder里面包括常用的一些控件常用的属性设置。
ViewHolder代码如下:
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.IdRes;
import android.support.annotation.StringRes;
import android.support.v7.widget.RecyclerView;
import android.text.util.Linkify;
import android.util.SparseArray;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RatingBar;
import android.widget.TextView;
import java.util.regex.Pattern;
/**
* 通用的ViewHolder
* 继承 RecyeclerView.ViewHolder 主要是为了通用性更强
*
* @author Jenly <jenly1314@gmail.com>
*
*/
public class ViewHolder extends RecyclerView.ViewHolder{
private SparseArray<View> views;
private View convertView;
public ViewHolder (View convertView){
super(convertView);
this.convertView = convertView;
views = new SparseArray<>();
}
public View getConvertView(){
return convertView;
}
private <T extends View> T findView(@IdRes int id){
return (T)convertView.findViewById(id);
}
public <T extends View> T getView(@IdRes int id){
View v = views.get(id);
if(v == null){
v = findView(id);
views.put(id,v);
}
return (T)v;
}
//---------------------- 控件常用设置
public View setBackgroundResource(@IdRes int id,int resId){
View v = getView(id);
v.setBackgroundResource(resId);
return v;
}
public View setBackground(@IdRes int id,Drawable drawable){
View v = getView(id);
v.setBackground(drawable);
return v;
}
public View setBackgroundColor(@IdRes int id,int color){
View v = getView(id);
v.setBackgroundColor(color);
return v;
}
public View setTag(@IdRes int id,Object tag){
View v = getView(id);
v.setTag(tag);
return v;
}
public View setTag(@IdRes int id,int key,Object tag){
View v = getView(id);
v.setTag(key,tag);
return v;
}
public View setVisibility(@IdRes int id,int visibility){
View v = getView(id);
v.setVisibility(visibility);
return v;
}
public View setVisibility(@IdRes int id,boolean isVisible){
View v = getView(id);
if(isVisible)
v.setVisibility(View.VISIBLE);
v.setVisibility(View.GONE);
return v;
}
public void setAlpha(@IdRes int id,float alpha){
View v = getView(id);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
v.setAlpha(alpha);
}else{
Animation anim = new AlphaAnimation(alpha,alpha);
anim.setFillAfter(true);
v.startAnimation(anim);
}
}
public TextView setCompoundDrawableLeft(@IdRes int id,Drawable drawable){
return setCompoundDrawables(id,drawable,null,null,null);
}
public TextView setCompoundDrawableTop(@IdRes int id,Drawable drawable){
return setCompoundDrawables(id,null,drawable,null,null);
}
public TextView setCompoundDrawableRight(@IdRes int id,Drawable drawable){
return setCompoundDrawables(id,null,null,drawable,null);
}
public TextView setCompoundDrawableBottom(@IdRes int id,Drawable drawable){
return setCompoundDrawables(id,null,null,null,drawable);
}
public TextView setCompoundDrawables(@IdRes int id,Drawable left,Drawable top,Drawable right,Drawable bottom){
TextView tv = getView(id);
tv.setCompoundDrawables(left, top, right, bottom);
return tv;
}
public TextView setCompoundDrawablePadding(@IdRes int id,int padding){
TextView tv = getView(id);
tv.setCompoundDrawablePadding(padding);
return tv;
}
public TextView setCompoundDrawablesWithIntrinsicBounds(@IdRes int id,Drawable left,Drawable top,Drawable right,Drawable bottom){
TextView tv = getView(id);
tv.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
return tv;
}
public TextView setCompoundDrawablesWithIntrinsicBounds(@IdRes int id,int left,int top,int right,int bottom){
TextView tv = getView(id);
tv.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
return tv;
}
public TextView setText(@IdRes int id,@StringRes int resId){
TextView tv = getView(id);
tv.setText(resId);
return tv;
}
public TextView setText(@IdRes int id,CharSequence text){
TextView tv = getView(id);
tv.setText(text);
return tv;
}
public TextView setTextColor(@IdRes int id,int color){
TextView tv = getView(id);
tv.setTextColor(color);
return tv;
}
public TextView setTextColor(@IdRes int id,ColorStateList colors){
TextView tv = getView(id);
tv.setTextColor(colors);
return tv;
}
public TextView setTypeface(@IdRes int id,Typeface tf){
TextView tv = getView(id);
tv.setTypeface(tf);
return tv;
}
public TextView setTypeface(@IdRes int id,Typeface tf, int style){
TextView tv = getView(id);
tv.setTypeface(tf,style);
return tv;
}
public TextView addLinks(@IdRes int id){
TextView tv = getView(id);
Linkify.addLinks(tv,Linkify.ALL);
return tv;
}
public TextView addLinks(@IdRes int id,int mask){
TextView tv = getView(id);
Linkify.addLinks(tv,mask);
return tv;
}
public TextView addLinks(@IdRes int id, Pattern pattern, String scheme){
TextView tv = getView(id);
Linkify.addLinks(tv,pattern,scheme);
return tv;
}
public ImageView setImageResource(@IdRes int id,int resId){
ImageView iv = getView(id);
iv.setImageResource(resId);
return iv;
}
public ImageView setImageBitmap(@IdRes int id,Bitmap bitmap){
ImageView iv = getView(id);
iv.setImageBitmap(bitmap);
return iv;
}
public ImageView setImageDrawable(@IdRes int id,Drawable drawable){
ImageView iv = getView(id);
iv.setImageDrawable(drawable);
return iv;
}
public Checkable setChecked(@IdRes int id,boolean isChecked){
Checkable checkable = getView(id);
checkable.setChecked(isChecked);
return checkable;
}
public boolean isChecked(@IdRes int id){
Checkable checkable = getView(id);
return checkable.isChecked();
}
public Checkable toggle(@IdRes int id){
Checkable checkable = getView(id);
checkable.toggle();
return checkable;
}
public ProgressBar setProgress(@IdRes int id,int progress){
ProgressBar progressBar = getView(id);
progressBar.setProgress(progress);
return progressBar;
}
public ProgressBar setMax(@IdRes int id,int max){
ProgressBar progressBar = getView(id);
progressBar.setMax(max);
return progressBar;
}
public RatingBar setRating(@IdRes int id,float rating){
RatingBar ratingBar = getView(id);
ratingBar.setRating(rating);
return ratingBar;
}
public RatingBar setRating(@IdRes int id,float rating,int max){
RatingBar ratingBar = getView(id);
ratingBar.setRating(rating);
ratingBar.setMax(max);
return ratingBar;
}
public RatingBar setNumStars(@IdRes int id,int numStars){
RatingBar ratingBar = getView(id);
ratingBar.setNumStars(numStars);
return ratingBar;
}
//---------------------- 监听事件
public void setOnClickListener(@IdRes int id, View.OnClickListener onClickListener){
getView(id).setOnClickListener(onClickListener);
}
public void setOnTouchListener(@IdRes int id, View.OnTouchListener onTouchListener){
getView(id).setOnTouchListener(onTouchListener);
}
public void setOnLongClickListener(@IdRes int id, View.OnLongClickListener onLongClickListener){
getView(id).setOnLongClickListener(onLongClickListener);
}
public void setOnKeyListener(@IdRes int id, View.OnKeyListener onKeyListener){
getView(id).setOnKeyListener(onKeyListener);
}
}
有了通用的ViewHolder,下面就是对之前的HolderAdapter和HolderRecyclerAdapter的扩展了。
ViewHoderAdapter代码如下:
/**
* 通用适配器
* 在HolderAdapter基础之上将H:ViewHolder具体化,通过通用的ViewHolder根据控件的id得到对应控件,来进行相关的数据绑定操作
* @author Jenly <jenly1314@gmail.com>
*
*/
public abstract class ViewHolderAdapter<T> extends HolderAdapter<T,ViewHolder> {
public ViewHolderAdapter(Context context, List<T> listData) {
super(context, listData);
}
@Override
public ViewHolder buildHolder(View convertView, T t, int position) {
return new ViewHolder(convertView);
}
}
ViewHolderRecyclerAdapter代码如下:
/**
* 通用适配器
* 在HolderRecyclerAdapter基础之上将H:ViewHolder具体化,通过通用的ViewHolder根据控件的id得到对应控件,来进行相关的数据绑定操作
* @author Jenly <jenly1314@gmail.com>
*
*/
public abstract class ViewHolderRecyclerAdapter<T> extends HolderRecyclerAdapter<T,ViewHolder> {
public ViewHolderRecyclerAdapter(Context context, List<T> listData) {
super(context, listData);
}
@Override
public ViewHolder buildHolder(View convertView, int viewType) {
return new ViewHolder(convertView);
}
}
这样在写Adapter时,只需继承ViewHolderAdapter或ViewHolderRecyclerAdapter,然后只管设置contervtView布局和绑定数据就可以了。妈妈再也不同担心重复的写自定义Adapter了。
示例:
public class TestAdapter extends ViewHolderAdapter<String> {
public TestAdapter(Context context, List<String> listData) {
super(context, listData);
}
@Override
public View buildConvertView(LayoutInflater layoutInflater, String s, int position) {
return inflate(R.layout.list_item);
}
@Override
public void bindViewDatas(ViewHolder holder, String s, int position) {
holder.setText(R.id.tv,s);
}
}
就这么简单的几句代码,妈妈再也不用担心我写自定义Adapter了。
所有最新源码已总结上传至github 欢迎Star或Fork。