• 高灵活低耦合Adapter快速开发攻略


    Android开发中经常需要使用Adapter。

    传统方法是自定义一个Adapter并继承AndroidSDK内的BaseAdapter,

    这种方式代码量大,耦合度高,灵活性差(各种监听事件需要对View单独写,或者自定义一个比较统一的方法);

    而ZBLibrary中的BaseViewAdapter不仅预处理了通用方法(getCount,getItem等) 以及 Item复用逻辑,

    而且将对Item的处理代码单独写在一个BaseView(提供了大量常用方法)的子类,

    所以使用继承BaseViewAdapter的新方式能大幅精简代码,并且带来高灵活性和低耦合度。

    比如这个界面

    传统方式实现的CommonAdapter代码如下

      1 package com.example.quickadapter;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 
      6 import zuo.biao.library.ui.WebViewActivity;
      7 import zuo.biao.library.util.ImageLoaderUtil;
      8 import android.app.Activity;
      9 import android.view.LayoutInflater;
     10 import android.view.View;
     11 import android.view.View.OnClickListener;
     12 import android.view.ViewGroup;
     13 import android.widget.BaseAdapter;
     14 import android.widget.ImageView;
     15 import android.widget.TextView;
     16 
     17 public class CommonAdapter extends BaseAdapter {
     18 
     19     private Activity context;
     20     private List<User> list;
     21     private LayoutInflater inflater;
     22     public CommonAdapter(Activity context, List<User> list) {
     23         this.context = context;
     24         this.list = new ArrayList<>(list);
     25         this.inflater = context.getLayoutInflater();
     26     }
     27 
     28     @Override
     29     public int getCount() {
     30         return list.size();
     31     }
     32 
     33     @Override
     34     public User getItem(int position) {
     35         return list.get(position);
     36     }
     37 
     38     @Override
     39     public long getItemId(int position) {
     40         return position;
     41     }
     42 
     43     public synchronized void refresh(List<User> list) {
     44         if (list != null && list.size() > 0) {
     45             this.list = new ArrayList<>(list);
     46         }
     47         notifyDataSetChanged();
     48     }
     49 
     50     @Override
     51     public View getView(final int position, View convertView, ViewGroup parent) {
     52         ViewHolder holder = convertView == null ? null : (ViewHolder) convertView.getTag();
     53         if (holder == null) {
     54             convertView = inflater.inflate(R.layout.user_item, parent, false);
     55             holder = new ViewHolder();
     56 
     57             holder.ivUserItemHead = (ImageView) convertView.findViewById(R.id.ivUserItemHead);
     58             holder.ivUserItemStar = (ImageView) convertView.findViewById(R.id.ivUserItemStar);
     59 
     60             holder.tvUserItemSex = (TextView) convertView.findViewById(R.id.tvUserItemSex);
     61 
     62             holder.tvUserItemName = (TextView) convertView.findViewById(R.id.tvUserItemName);
     63             holder.tvUserItemId = (TextView) convertView.findViewById(R.id.tvUserItemId);
     64             holder.tvUserItemNumber = (TextView) convertView.findViewById(R.id.tvUserItemNumber);
     65 
     66             convertView.setTag(holder);
     67         }
     68 
     69         final User user = getItem(position);
     70 
     71         ImageLoaderUtil.loadImage(holder.ivUserItemHead, user.getHead(), ImageLoaderUtil.TYPE_OVAL);
     72         holder.ivUserItemStar.setImageResource(user.getStarred() ? R.drawable.star_light : R.drawable.star);
     73 
     74         holder.tvUserItemSex.setBackgroundResource(user.getSex() == User.SEX_FEMAIL ? R.drawable.circle_pink : R.drawable.circle_blue);
     75         holder.tvUserItemSex.setText(user.getSex() == User.SEX_FEMAIL ?  "女" : "男");
     76         holder.tvUserItemSex.setTextColor(context.getResources().getColor(user.getSex() == User.SEX_FEMAIL ? R.color.pink : R.color.blue));
     77         
     78         holder.tvUserItemName.setText("" + user.getName());
     79         holder.tvUserItemId.setText("ID:" + user.getId());
     80         holder.tvUserItemNumber.setText("Phone:" + user.getPhone());
     81 
     82         holder.ivUserItemHead.setOnClickListener(new OnClickListener() {
     83 
     84             @Override
     85             public void onClick(View v) {
     86                 context.startActivity(WebViewActivity.createIntent(context, user.getName(), user.getHead()));
     87             }
     88         });
     89 
     90         holder.ivUserItemStar.setOnClickListener(new OnClickListener() {
     91 
     92             @Override
     93             public void onClick(View v) {
     94                 user.setStarred(! user.getStarred());
     95                 list.set(position, user);
     96                 refresh(null);
     97             }
     98         });
     99 
    100         holder.tvUserItemSex.setOnClickListener(new OnClickListener() {
    101 
    102             @Override
    103             public void onClick(View v) {
    104                 user.setSex(user.getSex() == User.SEX_FEMAIL ? User.SEX_MAIL : User.SEX_FEMAIL);
    105                 list.set(position, user);
    106                 refresh(null);
    107             }
    108         });
    109 
    110         return convertView;
    111     }
    112 
    113     class ViewHolder {
    114         public ImageView ivUserItemHead;
    115         public ImageView ivUserItemStar;
    116 
    117         public TextView tvUserItemSex;
    118 
    119         public TextView tvUserItemName;
    120         public TextView tvUserItemId;
    121         public TextView tvUserItemNumber;
    122     }
    123 }

    继承BaseViewAdapter的新方式实现的QuickAdapter代码如下

      1 package com.example.quickadapter;
      2 
      3 import java.util.List;
      4 
      5 import zuo.biao.library.base.BaseView;
      6 import zuo.biao.library.base.BaseViewAdapter;
      7 import zuo.biao.library.ui.WebViewActivity;
      8 import zuo.biao.library.util.ImageLoaderUtil;
      9 import zuo.biao.library.util.StringUtil;
     10 import android.annotation.SuppressLint;
     11 import android.app.Activity;
     12 import android.content.res.Resources;
     13 import android.view.LayoutInflater;
     14 import android.view.View;
     15 import android.view.View.OnClickListener;
     16 import android.view.ViewGroup;
     17 import android.widget.ImageView;
     18 import android.widget.TextView;
     19 
     20 import com.example.quickadapter.QuickAdapter.UserView;
     21 
     22 public class QuickAdapter extends BaseViewAdapter<User, UserView> {
     23 
     24     public QuickAdapter(Activity context, List<User> list) {
     25         super(context, list);
     26     }
     27 
     28     @Override
     29     public UserView createView(int position, View convertView, ViewGroup parent) {
     30         return new UserView(context, resources);
     31     }
     32 
     33     public class UserView extends BaseView<User> implements OnClickListener {
     34         public UserView(Activity context, Resources resources) {
     35             super(context, resources);
     36         }
     37 
     38         public ImageView ivUserViewHead;
     39         public ImageView ivUserViewStar;
     40         
     41         public TextView tvUserViewSex;
     42 
     43         public TextView tvUserViewName;
     44         public TextView tvUserViewId;
     45         public TextView tvUserViewNumber;
     46         @SuppressLint("InflateParams")
     47         @Override
     48         public View createView(LayoutInflater inflater) {
     49             convertView = inflater.inflate(R.layout.user_view, null);
     50 
     51             ivUserViewHead = findViewById(R.id.ivUserViewHead, this);
     52             ivUserViewStar = findViewById(R.id.ivUserViewStar, this);
     53 
     54             tvUserViewSex = findViewById(R.id.tvUserViewSex, this);
     55             
     56             tvUserViewName = findViewById(R.id.tvUserViewName);
     57             tvUserViewId = findViewById(R.id.tvUserViewId);
     58             tvUserViewNumber = findViewById(R.id.tvUserViewNumber);
     59 
     60             return convertView;
     61         }
     62 
     63         @Override
     64         public void setView(User data){
     65             if (data == null) {
     66                 return;
     67             }
     68             this.data = data;
     69 
     70             ImageLoaderUtil.loadImage(ivUserViewHead, data.getHead(), ImageLoaderUtil.TYPE_OVAL);
     71             ivUserViewStar.setImageResource(data.getStarred() ? R.drawable.star_light : R.drawable.star);
     72             
     73             tvUserViewSex.setBackgroundResource(data.getSex() == User.SEX_FEMAIL ? R.drawable.circle_pink : R.drawable.circle_blue);
     74             tvUserViewSex.setText(data.getSex() == User.SEX_FEMAIL ?  "女" : "男");
     75             tvUserViewSex.setTextColor(getColor(data.getSex() == User.SEX_FEMAIL ? R.color.pink : R.color.blue));
     76             
     77             tvUserViewName.setText(StringUtil.getTrimedString(data.getName()));
     78             tvUserViewId.setText("ID:" + data.getId());
     79             tvUserViewNumber.setText("Phone:" + StringUtil.getNoBlankString(data.getPhone()));
     80         }
     81 
     82         @Override
     83         public void onClick(View v) {
     84             if (data == null) {
     85                 return;
     86             }
     87             switch (v.getId()) {
     88             case R.id.ivUserViewHead:
     89                 toActivity(WebViewActivity.createIntent(context, data.getName(), data.getHead()));
     90                 break;
     91             case R.id.ivUserViewStar:
     92                 data.setStarred(! data.getStarred());
     93                 setView(data);
     94                 break;
     95             case R.id.tvUserViewSex:
     96                 data.setSex(data.getSex() == User.SEX_FEMAIL ? User.SEX_MAIL : User.SEX_FEMAIL);
     97                 setView(data);
     98                 break;
     99             default:
    100                 break;
    101             }        
    102         }
    103     }
    104 }

    看下ZBLibrary中的BaseView,里面有大量常用的 且 AndroidSDK内的BaseAdapter没有提供的 方法。

    package zuo.biao.library.base;
    
    import zuo.biao.library.util.CommonUtil;
    import zuo.biao.library.util.Log;
    import android.app.Activity;
    import android.content.Intent;
    import android.content.res.Resources;
    import android.graphics.drawable.Drawable;
    import android.support.annotation.NonNull;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.View.OnLongClickListener;
    import android.view.View.OnTouchListener;
    
    /**基础自定义View
     * @author Lemon
     * @param <T> 数据模型(model/JavaBean)类
     * @see #onDestroy
     * @use extends BaseView<T>, 具体参考.DemoView
     */
    public abstract class BaseView<T> {
        private static final String TAG = "BaseView";
    
        /**
         * 传入的Activity,可在子类直接使用
         */
        protected Activity context;
        protected Resources resources;
        public BaseView(Activity context, Resources resources) {
            this.context = context;
            this.resources = resources == null ? context.getResources() : resources;
        }
    
        /**数据改变回调接口
         * (Object) getData() - 改变的数据
         */
        public interface OnDataChangedListener {
            void onDataChanged();
        }
    
        public OnDataChangedListener onDataChangedListener;//数据改变回调监听类的实例
        /**设置数据改变事件监听类
         * @param l
         */
        public void setOnDataChangedListener(OnDataChangedListener l) {
            onDataChangedListener = l;
        }
    
        public OnTouchListener onTouchListener;//接触View回调监听类的实例
        /**设置接触View事件监听类
         * @param l
         */
        public void setOnTouchListener(OnTouchListener l) {
            onTouchListener = l;
        }
    
        public OnClickListener onClickListener;//点击View回调监听类的实例
        /**设置点击View事件监听类
         * @param l
         */
        public void setOnClickListener(OnClickListener l) {
            onClickListener = l;
        }
    
        public OnLongClickListener onLongClickListener;//长按View回调监听类的实例
        /**设置长按View事件监听类
         * @param l
         */
        public void setOnLongClickListener(OnLongClickListener l) {
            onLongClickListener = l;
        }
    
    
    
        /**
         * 子类整个视图,可在子类直接使用
         * @must createView方法内对其赋值且不能为null
         */
        protected View convertView = null;
    
        /**通过id查找并获取控件,使用时不需要强转
         * @param id
         * @return 
         */
        @SuppressWarnings("unchecked")
        public <V extends View> V findViewById(int id) {
            return (V) convertView.findViewById(id);
        }
        /**通过id查找并获取控件,并setOnClickListener
         * @param id
         * @param l
         * @return
         */
        public <V extends View> V findViewById(int id, OnClickListener l) {
            V v = findViewById(id);
            v.setOnClickListener(l);
            return v;
        }
        /**创建一个新的View
         * @return
         */
        public abstract View createView(@NonNull LayoutInflater inflater);
    
        /**获取convertView的宽度
         * @warn 只能在createView后使用
         * @return
         */
        public int getWidth() {
            return convertView.getWidth();
        }
        /**获取convertView的高度
         * @warn 只能在createView后使用
         * @return
         */
        public int getHeight() {
            return convertView.getHeight();
        }
    
        /**
         * data在列表中的位置
         * @must 只使用setView(int position, T data)方法来设置position,保证position与data对应正确
         */
        protected int position = 0;
        /**获取data在列表中的位置
         */
        public int getPosition() {
            return position;
        }
    
        protected T data = null;
        /**获取数据
         * @return
         */
        public T getData() {
            return data;
        }
    
        /**设置并显示内容
         * @warn 只能在createView后使用
         * @param position - data在列表中的位置
         * @param data - 传入的数据
         */
        public void setView(int position, T data) {
            this.position = position;
            setView(data);
        }
        /**设置并显示内容
         * @warn 只能在createView后使用
         * @param data - 传入的数据
         */
        public abstract void setView(T data);
    
        /**获取可见性
         * @warn 只能在createView后使用
         * @return 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);
         */
        public int getVisibility() {
            return convertView.getVisibility();
        }
        /**设置可见性
         * @warn 只能在createView后使用
         * @param visibility - 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);
         */
        public void setVisibility(int visibility) {
            convertView.setVisibility(visibility);
        }
    
    
        /**设置背景
         * @warn 只能在createView后使用
         * @param resId
         */
        public void setBackground(int resId) {
            if (resId > 0 && convertView != null) {
                try {
                    convertView.setBackgroundResource(resId);
                } catch (Exception e) {
                    Log.e(TAG, "setBackground   try { convertView.setBackgroundResource(resId);" +
                            " 
     >> } catch (Exception e) { 
    " + e.getMessage());
                }
            }
        }
    
    
        //resources方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        public String getString(int id) {
            return resources.getString(id);
        }
        public int getColor(int id) {
            return resources.getColor(id);
        }
        public Drawable getDrawable(int id) {
            return resources.getDrawable(id);
        }
        public float getDimension(int id) {
            return resources.getDimension(id);
        }
        //resources方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    
    
        //show short toast 方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        /**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
         * @param stringResId
         */
        public void showShortToast(int stringResId) {
            CommonUtil.showShortToast(context, stringResId);
        }
        /**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
         * @param string
         */
        public void showShortToast(String string) {
            CommonUtil.showShortToast(context, string);
        }
        //show short toast 方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    
    
        //启动新Activity方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
        /**打开新的Activity,向左滑入效果
         * @param intent
         */
        public void toActivity(final Intent intent) {
            CommonUtil.toActivity(context, intent);
        }
        /**打开新的Activity
         * @param intent
         * @param showAnimation
         */
        public void toActivity(final Intent intent, final boolean showAnimation) {
            CommonUtil.toActivity(context, intent, showAnimation);
        }
        /**打开新的Activity,向左滑入效果
         * @param intent
         * @param requestCode
         */
        public void toActivity(final Intent intent, final int requestCode) {
            CommonUtil.toActivity(context, intent, requestCode);
        }
        /**打开新的Activity
         * @param intent
         * @param requestCode
         * @param showAnimation
         */
        public void toActivity(final Intent intent, final int requestCode, final boolean showAnimation) {
            CommonUtil.toActivity(context, intent, requestCode, showAnimation);
        }
        //启动新Activity方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    
        /**销毁并回收内存,建议在对应的View占用大量内存时使用
         * @warn 只能在UI线程中调用
         */
        public void onDestroy() {
            if (convertView != null) {
                try {
                    convertView.destroyDrawingCache();
                } catch (Exception e) {
                    Log.w(TAG, "onDestroy  try { convertView.destroyDrawingCache();" +
                            " >> } catch (Exception e) {
    " + e.getMessage());
                }
                convertView = null;
            }
            
            onDataChangedListener = null;
            onTouchListener = null;
            onClickListener = null;
            onLongClickListener = null;
            
            data = null;
            position = 0;
            
            context = null;
        }
    
    }

    本示例工程QuickAdapter

    下载地址

    http://files.cnblogs.com/files/tommylemon/QuickAdapter.zip

    下载试用

    QuickAdapter.apk

    用到的开源库ZBLibrary(欢迎Star,欢迎Fork)

     

    下载地址

    https://github.com/TommyLemon/Android-ZBLibrary

    下载试用

    ZBLibraryDemoApp.apk

     

     

  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/tommylemon/p/5618599.html
Copyright © 2020-2023  润新知