Android Adapter 通用适配器

以前的适配器

一目十行随便扫描一下.不想看的此处可以直接跳过

public class ScanBarItemAdapter extends BaseCommonAdapter<HashMap<String, String>>
{
    private Viewholder viewHolder;

    public ScanBarItemAdapter(Activity activity)
    {
        super(activity);
    }

    @Override
    protected View getLayoutView(int position, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            viewHolder = new Viewholder();
            convertView = LayoutInflater.from(activity).inflate(R.layout.desk_ly_scan_bar_item, parent, false);
            viewHolder.tvCommonName = convertView.findViewById(R.id.tvCommonName);
            viewHolder.tvConsistency = convertView.findViewById(R.id.tvConsistency);
            viewHolder.tvPosition = convertView.findViewById(R.id.tvPosition);
            viewHolder.tvModel = convertView.findViewById(R.id.tvModel);
            viewHolder.tvVolumn = convertView.findViewById(R.id.tvVolumn);
            convertView.setTag(viewHolder);
        }
        else
        {
            viewHolder = (Viewholder) convertView.getTag();
        }

        viewHolder.tvCommonName.setText(item.get(position).get(Constant.CommonName));
        viewHolder.tvConsistency.setText(item.get(position).get(Constant.Consistency));
        viewHolder.tvPosition.setText(item.get(position).get(Constant.Position));
        viewHolder.tvModel.setText(item.get(position).get(Constant.Model));
        viewHolder.tvVolumn.setText(item.get(position).get(Constant.Volumn));
        return convertView;
    }


    private class Viewholder
    {
        TextView tvCommonName;
        TextView tvConsistency;
        TextView tvPosition;
        TextView tvModel;
        TextView tvVolumn;
    }

}

通过我们的瞄一眼,可以看出我们及时对已上的适配器进行泛型封装但是我们还是逃不过需要在每一个适配器中些VIewHolder类若是一个大型的项目,可能我们的精力大部分用在写适配器上面,我们需要大量重复viewHolder.tvCommonName.setText,viewHolder.tvCommonName.setText…等等等,写我自己都想吐, 那有没有一种办法,让我们不在为每一个适配器写一个Viewholder类呢,有,当然有.下面我们就来看看通用的ViewHolder类

ViewHolder


import androidx.annotation.NonNull;
	
public class ViewHolder
{
    private final SparseArray<View> sparseArray;
    private View mConvertView;

    private ViewHolder(Context context, ViewGroup parent, int layoutId)
    {
        this.sparseArray=new SparseArray<>();
        mConvertView= LayoutInflater.from(context).inflate(layoutId,parent,false);
        mConvertView.setTag(this);
    }


    public static ViewHolder get(Context context,int position, View convertView, ViewGroup parent, int layoutId)
    {
        if (convertView == null)
        {
            return new ViewHolder(context,parent,layoutId);
        }
        return (ViewHolder) convertView.getTag();
    }


    public <T extends View> T getView(@NonNull int viewId)
    {
        View view=sparseArray.get(viewId);
        if (view == null)
        {
            view = mConvertView.findViewById(viewId);
            sparseArray.put(viewId,view);
        }
        return (T) view;
    }


    public View getConvertView()
    {
        return mConvertView;
    }

}


在ViewHolder中的这段代码等同于以前的这段代码(红线标注的地方)
在这里插入图片描述
红线中间的效果我们用ViewHolder中的getView代替

用法

我们可以再封装一个通用BaseCommonAdapter类

public abstract class BaseCommonAdapter<T> extends BaseAdapter
{
    protected ArrayList<T> item=new ArrayList<>();
    protected Activity activity;
    protected int layoutId;

    public BaseCommonAdapter(Activity activity,int layoutId)
    {
        this.activity=activity;
        this.layoutId=layoutId;
    }
    @Override
    public int getCount()
    {
        return item.size();
    }

    @Override
    public T getItem(int position)
    {
        return item.get(position);
    }

    @Override
    public long getItemId(int position)
    {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ViewHolder viewHolder=ViewHolder.get(activity,position,convertView,parent,layoutId);


        convert(viewHolder,getItem(position));


        return viewHolder.getConvertView();
    }


    protected abstract  void convert(ViewHolder viewHolder, T item);

    public void setItem(ArrayList<T> item)
    {
        if (item != null && item.size() > 0)
        {
            this.item.clear();
            this.item.addAll(item);
        }
    }
}


因为在getView()方法中,我们每次都需要重新ViewHolder viewHolder=ViewHolder.get(activity,position,convertView,parent,layoutId);以及return部分,所以我们直接在BaseCommonAdapter中写死, 利用构造方法把需要加载的布局ID传递进来,所以我们直接在定义一个convert抽象方法就可以了,然后在我们的adapter中进行实现

自己的adapter

public class BoxSpinnerAdapter extends BaseCommonAdapter<ArrayList<String>>
{
    public BoxSpinnerAdapter(Activity activity, int layoutId)
    {
        super(activity,layoutId);
    }



    @Override
    protected void convert(ViewHolder viewHolder, ArrayList<String> item)
    {
        TextView tvId=viewHolder.getView(R.id.tvId);
        tvId.setText(item.get(0));
        TextView tvName=viewHolder.getView(R.id.tvName);
        tvName.setText(item.get(1));
    }

用法是不是很简单呢
我们再看看activity中的怎么调用这个适配器

 BoxSpinnerAdapter adapter = new BoxSpinnerAdapter(getMyActivity(),R.layout.desk_rk_item_box);
                adapter.setItem(boxArray);
                mBinding.spinBox.setAdapter(adapter);

是不是瞬间减少了好多重复代码

终极封装

从上面看,我们还是需要写很多为控件设置属性的代码

在这里插入图片描述
在Adapter中我们常用的控件无非就是TextView ,ImageView, Button,这一部分我们可以再次封装
我们只需要在ViewHolder中添加一下方法即可

public class ViewHolder
{
//.........
//.........
//省略无关紧要代码
//.........
//.........


/**
     * 设置TextView文本
     * @param viewId 控件id
     * @param text
     * @return
     */
    public ViewHolder setText(int viewId,String text)
    {
        TextView view =getView(viewId);
        view.setText(text);
        return this;
    }

    /**
     * 设置字体颜色
     * @param viewId
     * @param colorId
     * @return
     */
    public ViewHolder setTextColor(int viewId,@ColorInt int colorId)
    {
        TextView view =getView(viewId);
        view.setTextColor(colorId);
        return this;
    }

    public ViewHolder setOnclickListener(int viewId,View.OnClickListener listener)
    {
        Button view=getView(viewId);
        view.setOnClickListener(listener);
        return this;
    }

    public ViewHolder setImagerDrawable(int viewId,@DrawableRes int drawableId)
    {
        ImageView view=getView(viewId);
        view.setImageResource(drawableId);
        return this;
    }

}

完整代码–>拿来即用

ViewHolder类

import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;

public class ViewHolder
{

    private final SparseArray<View> sparseArray;
    private View mConvertView;

    private ViewHolder(Context context, ViewGroup parent, int layoutId)
    {
        this.sparseArray=new SparseArray<>();
        mConvertView= LayoutInflater.from(context).inflate(layoutId,parent,false);
        mConvertView.setTag(this);
    }


    /**
     * 获取ViewHolder 如果convertView为空则重新实例化一个ViewHolder赋值给convertView,否则从已有的convertView中获取ViewHolder
     * @param context 上下文
     * @param position 位置
     * @param convertView convertView
     * @param parent 父布局控件
     * @param layoutId 布局id
     * @return
     */
    public static ViewHolder get(Context context,int position, View convertView, ViewGroup parent, int layoutId)
    {
        if (convertView == null)
        {
            return new ViewHolder(context,parent,layoutId);
        }
        return (ViewHolder) convertView.getTag();
    }

    /**
     * 获取控件
     * @param viewId 控件的Id
     * @param <T>
     * @return
     */
    public <T extends View> T getView(@NonNull int viewId)
    {
        View view=sparseArray.get(viewId);
        if (view == null)
        {
            view = mConvertView.findViewById(viewId);
            sparseArray.put(viewId,view);
        }
        return (T) view;
    }


    /**
     *  获取convertView
     * @return
     */
    public View getConvertView()
    {
        return mConvertView;
    }

    /**
     * 设置TextView文本
     * @param viewId 控件id
     * @param text
     * @return
     */
    public ViewHolder setText(int viewId,String text)
    {
        TextView view =getView(viewId);
        view.setText(text);
        return this;
    }

    /**
     * 设置字体颜色
     * @param viewId
     * @param colorId
     * @return
     */
    public ViewHolder setTextColor(int viewId,@ColorInt int colorId)
    {
        TextView view =getView(viewId);
        view.setTextColor(colorId);
        return this;
    }

    public ViewHolder setOnclickListener(int viewId,View.OnClickListener listener)
    {
        Button view=getView(viewId);
        view.setOnClickListener(listener);
        return this;
    }

    public ViewHolder setImagerDrawable(int viewId,@DrawableRes int drawableId)
    {
        ImageView view=getView(viewId);
        view.setImageResource(drawableId);
        return this;
    }


}

BaseCommonAdapter类

import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import java.util.ArrayList;

public abstract class BaseCommonAdapter<T> extends BaseAdapter
{
    protected ArrayList<T> item=new ArrayList<>();
    protected Activity activity;
    protected int layoutId;

    public BaseCommonAdapter(Activity activity,int layoutId)
    {
        this.activity=activity;
        this.layoutId=layoutId;
    }
    @Override
    public int getCount()
    {
        return item.size();
    }

    @Override
    public T getItem(int position)
    {
        return item.get(position);
    }

    @Override
    public long getItemId(int position)
    {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ViewHolder viewHolder=ViewHolder.get(activity,position,convertView,parent,layoutId);


        convert(viewHolder,getItem(position));


        return viewHolder.getConvertView();
    }


    protected abstract  void convert(ViewHolder viewHolder, T item);

    public void setItem(ArrayList<T> item)
    {
        if (item != null && item.size() > 0)
        {
            this.item.clear();
            this.item.addAll(item);
        }
    }
}

欢迎大家在评论区赐教. . . 谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~搬~运~工~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值