高靈活低耦合Adapter快速開發攻略

来源:http://www.cnblogs.com/tommylemon/archive/2016/06/26/5618599.html
-Advertisement-
Play Games

Android開發中經常需要使用Adapter。 傳統方法是自定義一個Adapter並繼承AndroidSDK內的BaseAdapter, 這種方式代碼量大,耦合度高,靈活性差(各種監聽事件需要對View單獨寫,或者自定義一個比較統一的方法); 而ZBLibrary中的BaseViewAdapter ...


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);" +
                        " \n >> } catch (Exception e) { \n" + 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) {\n" + 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

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • × 目錄 [1]定義 [2]應用場景 [3]轉為布爾[4]實例方法 前面的話 布爾值Boolean類型可能是三種包裝對象Number、String和Boolean中最簡單的一種。Number和String對象擁有大量的實例屬性和方法,Boolean卻很少。從某種意義上說,為電腦設計程式就是與布爾值 ...
  • 1、HTML5不支持或不贊成使用的標簽 <acronym>——定義只取首字母的縮寫,HTML5 不支持。使用<abbr>定義縮寫代替,其中title 屬性可用於在滑鼠指針移動到元素上時顯示出縮寫的完整版本,堅持寫上title,這樣對瀏覽器和搜索引擎都比較友好。 <applet>——定義嵌入的 app ...
  • 在不同瀏覽器查看代碼效果可謂是家常便飯,所以用不同快捷鍵打開相應瀏覽器可以大大提高工作效率。工欲善其事,必先利其器啊,沒設置看文章吧,非常簡單。 ...
  • CSS樣式規範 1.類選擇器 2.標簽選擇器 3.id選擇器 4.CSS樣式的子選擇器 類選擇器 1.必背的固定結構,成為CSS樣式標記。所有的樣式都可以寫成CSS樣式的標記中 <style type="text/css"> </style> 2. type=“text/css” 意思是聲明這個標記 ...
  • 通過javascript進行UTF 8編碼 javascript的字元集: javascript程式是使用 字元集編寫的。 是`ASCII Latin 1 ECMAScript3 Unicode2.1 ECMAScript5 Unicode3`及後續版本。所以,我們編寫出來的javascript程式 ...
  • 關於這三個移動端的事件,詳細的資料網上一搜一大片,我就不浪費時間了 1.移動端長按事件 說明:通過定時器模擬長按事件,這個例子基於jQuery,【ele】是要長按的元素; 2.移動端上下左右滑動事件 說明:具體原理一搜一堆,這裡的具體例子,拷貝就能用;我的學習方式是,不管什麼原理之類的,先要做的就是 ...
  • 原生JS選擇器有getElementById、getElementsByName、getElementsByTagName和getElementsByClassName這四個,下麵我就一個一個介紹這四個選擇器的用法。 1.getElementById(通過ID獲取元素) 用法:document.ge ...
  • ARC
    ARC是什麼 ARC是iOS 5推出的新功能,全稱叫 ARC(Automatic Reference Counting)。簡單地說,就是代碼中自動加入了retain/release,原先需要手動添加的用來處理記憶體管理的引用計數的代碼可以自動地由編譯器完成了。 該機能在 iOS 5/ Mac OS X ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...