BaseAdapter的封装和实现

1、Adapter
/**
 * Created by xuyangsheng on 2017/3/26.
 * Author : xuyangsheng
 * Time : 2017/3/26 22:45
 * Name :
 * OverView :
 * Usage :  打造超级 BaseAdapter
 */
public abstract class CommonBaseAdapter< Textends BaseAdapter {
    private Context  mContext ;
    private List< TmDatas ;

    public  CommonBaseAdapter(Context context ,List< T> datas) {
        this. mContext = context ;
        this. mDatas = datas ;
    }

    @Override
    public int  getCount() {
        return  mDatas.size() ;
    }

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

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

    @Override
    public View  getView( int position View convertView ViewGroup parent) {
        CommonViewHolder  holder = CommonViewHolder. getInstance( mContext R.layout. listview_item position convertView parent) ;
        convert( holder , mDatas.get(position)) ;
        return  holder.getConvertView() ;
    }
    /**
     *  填充 holder 里面控件的数据
      @param  holder
      @param  bean
      */
    public abstract void  convert(CommonViewHolder holder , bean) ;
}

实现Adapter:
/**
 * Created by xuyangsheng on 2017/3/26.
 * Author : xuyangsheng
 * Time : 2017/3/26 22:50
 * Name :
 * OverView :
 * Usage :
 */

public class CommonAdapter  extends CommonBaseAdapter<Bean> {
    public  CommonAdapter(Context context List<Bean> datas) {
        super(context datas) ;
    }

    @Override
    public void  convert(CommonViewHolder holder , final Bean bean) {
        holder.setText(R.id. title bean.getTitle())
                .setText(R.id. desc bean.getDesc())
                .setText(R.id. time bean.getTime())
                .setText(R.id. phone bean.getPhone()) ;

        holder.setImageResource(R.id. timeMake R.mipmap. ic_launcher) ;

        // 这个当布局里面有 checkbox 的时候,复用问题的解决
        final CheckBox  cb = holder.getView(R.id. checkbox) ;
        cb.setChecked(bean.isCheck()) ;
        cb.setOnClickListener( new View.OnClickListener() {
            @Override
            public void  onClick(View v) {
                bean.setCheck( cb.isChecked()) ;
            }
        }) ;

    }
}

2、超级ViewHolder
/**
 * Created by xuyangsheng on 2017/3/26.
 * Author : xuyangsheng
 * Time : 2017/3/26 22:42
 * Name :
 * OverView :  打造超级 Viewholder
 * Usage :
 */

public class CommonViewHolder {
    private int  mPosition ;
    /*
     *  用于存储 holder 里面的各个 view ,此集合比 map 效率高 , key 必须为 Integer
     */
    private SparseArray<View>  mViews ;
    /**
     *  复用的 view
     */
    private View  convertView ;

    private  CommonViewHolder(Context context , int position , int layoutId ViewGroup parent) {
        this. mPosition = position ;
        mViews new SparseArray<View>() ;
        convertView = LayoutInflater. from(context).inflate(layoutId parent ,false) ;
        convertView.setTag( this) ;
    }

    public static CommonViewHolder  getInstance(Context context ,int layoutId ,int position View convertView ViewGroup parent) {
        if (convertView ==  null) {
            return new CommonViewHolder(context position layoutId parent) ;
       else {
            CommonViewHolder  holder = (CommonViewHolder) convertView.getTag() ;
            holder. mPosition = position ;
            return  holder ;
        }

    }

    /**
     *  通过 resourceId 获取 item 里面的 view
     *  @param  resourceId  控件的 id
     *  @return
      */
    @SuppressWarnings( "unchecked")
    public < extends View>  getView( int resourceId) {
        View  view mViews.get(resourceId) ;
        if ( view ==  null) {
            view convertView.findViewById(resourceId) ;
            mViews.put(resourceId view) ;
        }
        return ( Tview ;
    }

    /**
     *  textview 类型填充内容
      @param  resourceId
      @param  text
      @return  CommonViewHolder
     */
    public CommonViewHolder  setText( int resourceId ,CharSequence text ) {
        ((TextView) getView(resourceId)).setText(text) ;
        return this;
    }
    public CommonViewHolder  setText( int resourceId ,int resid ) {
        ((TextView) getView(resourceId)).setText(resid) ;
        return this;
    }
    /**
     *  ImageView 设置 Bitmap
     *  @param  resourceId
      @param  bm
      @return
      */
    public CommonViewHolder  setBitmap( int resourceId ,Bitmap bm) {
        ((ImageView)getView(resourceId)).setImageBitmap(bm) ;
        return  this;
    }
    public CommonViewHolder  setImageDrawable( int resourceId ,Drawable drawable) {
        ((ImageView)getView(resourceId)).setImageDrawable(drawable) ;
        return  this;
    }
    public CommonViewHolder  setImageResource( int resourceId ,int resId) {
        ((ImageView)getView(resourceId)).setImageResource(resId) ;
        return  this;
    }


    public View  getConvertView() {
        return  convertView ;
    }
    /**
     *  获取当前 item 的位置
      @return
      */
    public int  getPosition() {
        return  mPosition ;
    }
}

3、Bean

/**
 * Created by xuyangsheng on 2017/3/26.
 * Author : xuyangsheng
 * Time : 2017/3/26 22:52
 * Name :
 * OverView :
 * Usage :
 */

public class Bean {

    private String  title ;
    private String  desc ;
    private String  phone ;
    private String  time ;

    public  Bean(String pTitle String pDesc String pPhone String pTime) {
        title = pTitle ;
        desc = pDesc ;
        phone = pPhone ;
        time = pTime ;
    }

    // 这个当布局里面有 checkbox 的时候,复用问题的解决
    private boolean  isCheck ;
    // 略去 get/set ...

    public String  getTitle() {
        return  title ;
    }

    public void  setTitle(String pTitle) {
        title = pTitle ;
    }

    public String  getDesc() {
        return  desc ;
    }

    public void  setDesc(String pDesc) {
        desc = pDesc ;
    }

    public String  getPhone() {
        return  phone ;
    }

    public void  setPhone(String pPhone) {
        phone = pPhone ;
    }

    public String  getTime() {
        return  time ;
    }

    public void  setTime(String pTime) {
        time = pTime ;
    }

    public boolean  isCheck() {
        return  isCheck ;
    }

    public void  setCheck( boolean pCheck) {
        isCheck = pCheck ;
    }

}

4、测试用例
public class MainActivity  extends Activity {
    private ListView  listView ;
    private List<Bean>  mDatas ;
    private CommonAdapter  commonAdapter ;

    @Override
    protected void  onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState) ;
        setContentView(R.layout. activity_main) ;

        initDatas() ;
        initView() ;
        regisetListener() ;
    }

    @SuppressWarnings( "deprecation")
    private void  initDatas() {
        mDatas new ArrayList<Bean>() ;
        for ( int  20 ++) {
            mDatas.add( new Bean( "Android  适配器 i "android  新的征程,新的探索,新的追求! " "1231212112" i , new Date().toLocaleString())) ;
        }
    }

    private void  initView() {
        listView = (ListView) findViewById(R.id. listview) ;
        commonAdapter new CommonAdapter( this,  mDatas) ;
        listView.setAdapter( commonAdapter) ;
    }

    private void  regisetListener() {
        listView.setOnItemClickListener( new AdapterView.OnItemClickListener() {

            @Override
            public void  onItemClick(AdapterView<?> parent View view ,
                                    int position , long id) {
                Bean  bean mDatas.get(position) ;
                Toast. makeText(MainActivity. this,  bean.getTitle() Toast. LENGTH_SHORT).show() ;
            }
        }) ;
    }
}
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通过封装BaseAdapter和RecyclerView.Adapter得到的通用的,简易的Adapter。项目地址:https://github.com/tianzhijiexian/CommonAdapter 效果图:已解决的问题 提升item的独立性,完美支持item被多处复用 item会根据type来做自动复用 支持多种类型的item 一个item仅会调用一次setViews(),避免重复建立监听器 一个item仅会触发一次绑定视图的操作,提示效率 支持dataBinding和其他第三方注入框架 提供了getView()方法来简化findViewById 支持通过item的构造方法来传入Activity对象 支持通过item的构造方法来传入item中事件的回调 提供了getConvertedData(data, type)方法来对item传入的数据做转换,方便拆包和提升item的复用性 支持viewpager的正常加载模式和懒加载 支持快速将listview的适配器切换为recyclerView的适配器 viewpager的notifyDataSetChanged可以正常更新界面 支持recyclerView的添加头部和底部 支持适配器的数据自动绑定,只用操作数据便可,adapter会自动notify界面零、重要接口adapter的item必须实现此接口,接口源码如下:public interface AdapterItem<T> {     /**      * @return item布局文件的layoutId      */     @LayoutRes     int getLayoutResId();     /**      * 初始化views      */     void bindViews(final View root);     /**      * 设置view的参数      */     void setViews();     /**      * 根据数据来设置item的内部views      *      * @param model    数据list内部的model      * @param position 当前adapter调用item的位置      */     void handleData(T model, int position); }例子:public class TextItem implements AdapterItem<DemoModel> {     @Override     public int getLayoutResId() {         return R.layout.demo_item_text;     }     TextView textView;     @Override     public void bindViews(View root) {         textView = (TextView) root.findViewById(R.id.textView);     }     @Override     public void setViews() { }     @Override     public void handleData(DemoModel model, int position) {         textView.setText(model.content);     } }一、ListView GridView的通用适配器——CommonAdapter只需继承CommonAdapter便可实现适配器:listView.setAdapter(new CommonAdapter<DemoModel>(data, 1) {     public AdapterItem<DemoModel> createItem(Object type) {         return new TextItem();     } });二、RecyclerView的通用适配器——CommonRcvAdapter通过继承CommonRcvAdapter来实现适配器:mAdapter = new CommonRcvAdapter<DemoModel>(data) {  public AdapterItem createItem(Object type) {         return new TextItem();   } };三、ViewPager的通用适配器——CommonPagerAdapter通过继承CommonPagerAdapter来实现适配器:viewPager.setAdapter(new CommonPagerAdapter<DemoModel>() {     public AdapterItem createItem(Object type) {         return new TextItem();     } });设计思路1. Adapter如果用adapter常规写法,你会发现代码量很大,可读性低。如果adapter中有多个类型的Item,我们还得在getView()中写很多if-else语句,很乱。 而现在我让adapter的代码量减少到一个8行的内部类,如果你需要更换item只需要动一行代码,真正实现了可插拔化。最关键的是item现在作为了一个独立的对象,可以方便的进行复用。2. AdapterItem和原来方式最为不同的一点就是我把adapter的item作为了一个实体,这种方式借鉴了RecyclerView中ViewHolder的设计。把item作为实体的好处有很多,比如复用啊,封装啊,其余的就不细说了。3. 分层在使用过程中,我发现如果adapter放在view层,那就会影响到view层的独立性。此外adapter中经常有很多数据处理的操作,比如通过type选择item,数据的拆包、转换等操作。于是我还是推荐把adapter放在mvp的p层,或者是mvvm的m层。通过在实际的项目中使用来看,放在m或p层的效果较好,view的复用也比较好做。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值