zoukankan      html  css  js  c++  java
  • 高灵活低耦合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

     

     

  • 相关阅读:
    找“水王”
    用户体验评价
    学习进度12
    个人冲刺10
    学习进度13
    学习进度11
    个人冲刺9
    myeclipse中js报错
    安卓调用三个系统app(打电话,发短息,打开网页)
    关系图绘制详解
  • 原文地址:https://www.cnblogs.com/tommylemon/p/5618599.html
Copyright © 2011-2022 走看看