Android通用搜索頁的分析與封裝

前言

之前寫過一篇文章是關於搜索框的封裝( Android通用的搜索框),當時只是對搜索欄部分進行簡單的封裝,把搜索邏輯、頁面和數據處理封裝了一下,而搜索頁的處理(包括數據源,控件等)還需要手動的去創建和修改,用起來還是比較麻煩,最近不太忙,剛好需要用到這部分內容,於是又進一步的封裝了一下.(文章只適用於數據量不太大的本地搜索,例如通訊錄,城市列表,本地訂單等)

還是先看一下效果圖吧

這裏寫圖片描述

主要看一下封裝的實現.


分析與實現

先看一下之前寫的搜索頁代碼(沒看過( Android通用的搜索框)的童鞋,可以先大概看一下)

public class MainActivity extends AppCompatActivity {
    /**
     * TAG
     */
    private static final String TAG = "MainActivity";
    /**
     * 通用搜索框
     */
    private CommolySearchView<SearchBean> mCommolySearchView;
    /**
     * 數據顯示listview
     */
    private ListView mListView;
    /**
     * 數據源
     */
    private List<SearchBean> mDatas;
    /**
     * 適配器
     */
    private SearchAdapter adapter;
    //===========================三國部分===========================//
    /**
     * 三國通用搜索框
     */
    private CommolySearchView<SanGuoBean> mSGCommolySearchView;
    /**
     * 三國數據源
     */
    private List<SanGuoBean> mSGDatas;
    /**
     * 三國適配器
     */
    private SGAdapter sgAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        initData();
//        initView();
        initDataI();
        initViewI();
    }

    /**
     * 初始化數據
     */
    private void initData() {
        mDatas = new ArrayList<SearchBean>();
        SearchBean bean1 = new SearchBean();
        bean1.setSearchName("小明");
        bean1.setSearchDescribe("一年級二班");
        ...
        mDatas.add(bean1);
        ...
        mDatas.add(bean7);
    }

    /**
     * 初始化控件
     */
    private void initView() {
        mCommolySearchView = (CommolySearchView) findViewById(R.id.csv_show);
        mListView = (ListView) findViewById(R.id.lv_show);
        adapter = new SearchAdapter(this, mDatas);
        mListView.setAdapter(adapter);
        // 設置數據源
        mCommolySearchView.setDatas(mDatas);
        // 設置適配器
        mCommolySearchView.setAdapter(adapter);
        // 設置篩選數據
        mCommolySearchView.setSearchDataListener(new CommolySearchView.SearchDatas<SearchBean>() {

            @Override
            public List<SearchBean> filterDatas(List<SearchBean> datas, List<SearchBean> filterdatas, String inputstr) {
                Log.e(TAG, "filterDatas: " + inputstr);
                for (int i = 0; i < datas.size(); i++) {
                    // 篩選條件
                    if ((datas.get(i).getSearchName()).contains(inputstr) || datas.get(i).getSearchDescribe().contains(inputstr)) {
                        filterdatas.add(datas.get(i));
                    }
                }
                return filterdatas;
            }
        });
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Toast.makeText(MainActivity.this, "當前點擊的是" + mCommolySearchView.getFilterDatas().get(i).getSearchName(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * 初始化數據
     */
    private void initDataI() {
        mSGDatas = new ArrayList<SanGuoBean>();
        SanGuoBean sgbean1 = new SanGuoBean();
        sgbean1.setSgName("劉備");
        sgbean1.setSgPetName("玄德");
        sgbean1.setSgHeadBp(R.drawable.lb);
        sgbean1.setSgDescribe("劉備(161年-223年6月10日),字玄德,東漢末年幽州涿郡涿縣(今河北省涿州市)人");
        ... 
        mSGDatas.add(sgbean1);
        ...
        mSGDatas.add(sgbean7);

    }

    /**
     * 初始化控件
     */
    private void initViewI() {
        mSGCommolySearchView = (CommolySearchView) findViewById(R.id.csv_show);
        mListView = (ListView) findViewById(R.id.lv_show);
        sgAdapter = new SGAdapter(this, mSGDatas);
        mListView.setAdapter(sgAdapter);
        // 設置數據源
        mSGCommolySearchView.setDatas(mSGDatas);
        // 設置適配器
        mSGCommolySearchView.setAdapter(sgAdapter);
        // 設置篩選數據
        mSGCommolySearchView.setSearchDataListener(new CommolySearchView.SearchDatas<SanGuoBean>() {
            @Override
            public List<SanGuoBean> filterDatas(List<SanGuoBean> datas, List<SanGuoBean> filterdatas, String inputstr) {
                for (int i = 0; i < datas.size(); i++) {
                    // 篩選條件
                    if ((datas.get(i).getSgDescribe()).contains(inputstr) || datas.get(i).getSgName().contains(inputstr) || datas.get(i).getSgPetName().contains(inputstr)) {
                        filterdatas.add(datas.get(i));
                    }
                }
                return filterdatas;
            }
        });
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
              // 點擊操作
              ...
            }
        });

    }

}

爲了節省篇幅,省略了一些初始化數據的內容.

分析一下那些地方是需要進行優化和封裝的.
一)可以看到當搜索不同內容時,需要創建不同的List來接收不同類型的數據源

    /**
     * 數據源1
     */
    private List<SearchBean> mDatas;
    /**
     * 三國數據源(數據源2)
     */
    private List<SanGuoBean> mSGDatas;

二)通用搜索欄的實現中爲了通用性,使用了泛型,所以每次定義CommolySearchView時需要傳入一個泛型,來規定引用類型

    /**
     * 數據源1的搜索欄
     */
    private CommolySearchView<SearchBean> mCommolySearchView;
     /**
     * 三國數據源通用搜索框(數據源2)
     */
    private CommolySearchView<SanGuoBean> mSGCommolySearchView;

三)當然使用listview時,不同的數據源對應着不同的適配器

    /**
     * 數據源1適配器
     */
    private SearchAdapter adapter;
    /**
     * 三國適配器(數據源2適配器)
     */
    private SGAdapter sgAdapter;

針對這三點,來分析一下
先來看第一點,關於不同數據源的問題.看到這個問題,腦海裏第一個想到的就是使用泛型,不過要如何設計和使用呢.直接在搜索頁定義一個list< T > 來接收不同的數據源並規定引用類型?顯然不合適.最好是有一箇中介. 這裏定義一個CommonSearchBean來傳遞和使用不同類型的數據源

package com.example.junweiliu.commonlysearchview.bean;

import java.io.Serializable;
import java.util.List;

/**
 * Created by junweiliu on 17/3/29.
 * 封裝的搜索bean用於傳遞和使用不同類型的數據源
 */
public class CommonSearchBean<T> implements Serializable {
    /**
     * 數據源
     */
    private List<T> list;
    /**
     * 搜索類型  1代表搜索測試1,2代表搜索測試2
     */
    private int searchType;

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public int getSearchType() {
        return searchType;
    }

    public void setSearchType(int searchType) {
        this.searchType = searchType;
    }
}

這裏有一個searchType,是爲了區分不同的搜索類型,之後會用到.這樣數據源傳入和使用就可以通過CommonSearchBean來完成

 // 傳輸數據
 CommonSearchBean commonSearchBean = new CommonSearchBean();
 // 設置數據
 commonSearchBean.setList(mDatas);
 ...
 //---------------------分割線------------------------//
 // 獲取數據
 mDatas = commonSearchBean.getList();
 ...

再來看一下第二點,關於通用搜索欄,怎麼再進一步的優化和封裝呢?使用通用搜索欄時需要傳入一個泛型< T >去規定引用類型,但實際並不關心引用類型是什麼,只是需要在搜索回調中,把符合篩選條件的數據返回即可,相關代碼

     // 設置篩選數據
        mSGCommolySearchView.setSearchDataListener(new CommolySearchView.SearchDatas<SanGuoBean>() {
            @Override
            public List<SanGuoBean> filterDatas(List<SanGuoBean> datas, List<SanGuoBean> filterdatas, String inputstr) {
                for (int i = 0; i < datas.size(); i++) {
                    // 篩選條件
                    if ((datas.get(i).getSgDescribe()).contains(inputstr) || datas.get(i).getSgName().contains(inputstr) || datas.get(i).getSgPetName().contains(inputstr)) {
                        filterdatas.add(datas.get(i));
                    }
                }
                return filterdatas;
            }
        });

大多數的搜索都是使用包含條件,所以這裏規定一個接口BaseSearch,通過getSearchCondition()方法返回篩選條件

package com.example.junweiliu.commonlysearchview.bean;

/**
 * Created by junweiliu on 17/3/29.
 */
public interface BaseSearch {
    /**
     * 獲取篩選條件
     *
     * @return
     */
    String getSearchCondition();
}

在相關實體bean中實現該接口,例如

package com.example.junweiliu.commonlysearchview.bean;

import java.io.Serializable;

/**
 * Created by junweiliu on 17/3/29.
 */
public class SearchDemoBeanTwo implements BaseSearch, Serializable {
    /**
     * 頭像資源
     */
    private int iconRes;
    /**
     * 頭像地址
     */
    private int iconUrl;
    /**
     * 姓名
     */
    private String name;
    /**
     * 電話
     */
    private String phone;
    /**
     * 郵箱
     */
    private String email;

    public int getIconRes() {
        return iconRes;
    }

    public void setIconRes(int iconRes) {
        this.iconRes = iconRes;
    }

    public int getIconUrl() {
        return iconUrl;
    }

    public void setIconUrl(int iconUrl) {
        this.iconUrl = iconUrl;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    /**
     * 搜索條件
     *
     * @return
     */
    @Override
    public String getSearchCondition() {
        StringBuilder searchStr = new StringBuilder();
        searchStr.append(name);
        searchStr.append(phone);
        searchStr.append(email);
        return searchStr.toString();
    }
}

把篩選條件合併(當然可以根據需求返回篩選條件,因爲需要修改字符串,所以這裏使用StringBuilder,效率比較高),通過getSearchCondition()方法返回.之後在搜索頁就可以這樣寫

    /**
     * 搜索框
     */
    CommolySearchView<BaseSearch> mCsvShow;

    ...

    // 設置搜索
    mCsvShow.setSearchDataListener(new CommolySearchView.SearchDatas<BaseSearch>() {
            @Override
            public List<BaseSearch> filterDatas(List<BaseSearch> datas, List<BaseSearch> filterdatas, String inputstr) {
                for (int i = 0; i < datas.size(); i++) {
                    // 篩選條件,如果有必要,在此做修改
                    if (datas.get(i).getSearchCondition().contains(inputstr)) {
                        filterdatas.add(datas.get(i));
                    }
                }
                return filterdatas;
            }
        });

最後看一下第三個問題,不同的適配器.適配器初始化一般都需要上下文,數據源,佈局文件資源.數據源的問題在第一個問題中已經解決,所以在搜索頁定義一個BaseAdapter對象,再根據搜索類型實例化不同的對象即可,相關代碼如下

    /**
     * 適配器
     */
    private BaseAdapter mAdapter;
    /**
     * 封裝的搜索bean
     */
    private CommonSearchBean mCommonSearchBean;
    /**
     * 搜索類型(用於區分不同的搜索)
     */
    private int searchType;

    ...

    if (1 == searchType) {              // 測試例子1
            // 適配器1
            mAdapter = new SearchDemoAapterOne(this, mCommonSearchBean.getList(), R.layout.item_search_one);
    } else if (2 == searchType) {       // 測試例子2
            // 適配器2
            mAdapter = new SearchDemoAdapterTwo(this, mCommonSearchBean.getList());
    }

細心的童鞋可能注意到在定義CommonSearchBean時沒有規定引用類型,這裏不規定引用類型的原因就是爲了通用性,當使用泛型不規定引用類型時,默認爲Object,在適配器初始化時傳入的數據源通過CommonSearchBean.getList()方法獲得,只需要保證setList()方法中的數據類型和getList()方法中的數據類型一致即可.

具體代碼

最後看一下主要的代碼

搜索頁CommonSearchActivity

package com.example.junweiliu.commonlysearchview.activity;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.example.junweiliu.commonlysearchview.R;
import com.example.junweiliu.commonlysearchview.adapter.SearchDemoAapterOne;
import com.example.junweiliu.commonlysearchview.adapter.SearchDemoAdapterTwo;
import com.example.junweiliu.commonlysearchview.bean.BaseSearch;
import com.example.junweiliu.commonlysearchview.bean.CommonSearchBean;
import com.example.junweiliu.commonlysearchview.bean.SearchDemoBeanOne;
import com.example.junweiliu.commonlysearchview.bean.SearchDemoBeanTwo;
import com.example.junweiliu.commonlysearchview.widget.CommolySearchView;

import java.util.List;


/**
 * Created by junweiliu on 17/3/29.
 */
public class CommonSearchActivity extends AppCompatActivity {
    /**
     * 搜索框
     */
    CommolySearchView<BaseSearch> mCsvShow;
    /**
     * 數據展示
     */
    ListView mLvShow;
    /**
     * 適配器
     */
    private BaseAdapter mAdapter;
    /**
     * 封裝的搜索bean
     */
    private CommonSearchBean mCommonSearchBean = new CommonSearchBean();
    /**
     * 搜索類型(用於區分不同的搜索)
     */
    private int searchType;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_common_search);
        initData();
        initView();
        initAdapter();
        initSearch();
    }


    /**
     * 初始化適配器,一般的擴展只需修改該方法即可
     */
    private void initAdapter() {
        if (1 == searchType) {              // 測試例子1
            // 適配器1
            mAdapter = new SearchDemoAapterOne(this, mCommonSearchBean.getList(), R.layout.item_search_one);
            // 點擊事件
            mLvShow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(CommonSearchActivity.this, "點擊的是:" + ((SearchDemoBeanOne) mCommonSearchBean.getList().get(position)).getName(), Toast.LENGTH_SHORT).show();
                }
            });
        } else if (2 == searchType) {       // 測試例子2
            // 適配器2
            mAdapter = new SearchDemoAdapterTwo(this, mCommonSearchBean.getList());
            // 點擊事件
            mLvShow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(CommonSearchActivity.this, "點擊的是:" + ((SearchDemoBeanTwo) mCommonSearchBean.getList().get(position)).getName(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    /**
     * 初始化數據
     */
    private void initData() {
        mCommonSearchBean = (CommonSearchBean) getIntent().getSerializableExtra("seachBean");
        searchType = mCommonSearchBean.getSearchType();
    }

    /**
     * 初始化view
     */
    private void initView() {
        mCsvShow = (CommolySearchView<BaseSearch>) findViewById(R.id.csv_show);
        mLvShow = (ListView) findViewById(R.id.lv_show);
    }

    /**
     * 初始化搜索
     */
    private void initSearch() {
        mLvShow.setAdapter(mAdapter);
        // 設置數據源
        mCsvShow.setDatas(mCommonSearchBean.getList());
        // 設置適配器
        mCsvShow.setAdapter(mAdapter);
        // 設置搜索
        mCsvShow.setSearchDataListener(new CommolySearchView.SearchDatas<BaseSearch>() {
            @Override
            public List<BaseSearch> filterDatas(List<BaseSearch> datas, List<BaseSearch> filterdatas, String inputstr) {
                for (int i = 0; i < datas.size(); i++) {
                    // 篩選條件,如果有必要,在此做修改
                    if (datas.get(i).getSearchCondition().contains(inputstr)) {
                        filterdatas.add(datas.get(i));
                    }
                }
                return filterdatas;
            }
        });
    }
}

註釋寫的比較全,每次添加新的搜索類型時,只需要在initAdapter()方法中添加新的搜索類型的擴展即可(主要是實例化新的適配器),有必要的話,可以去修改篩選邏輯或者擴展BaseSearch,大多數包含情況下是不需要修改的.當然本文只是提供一個思路,應該有更好的封裝方法.

通用搜索欄CommolySearchView

package com.example.junweiliu.commonlysearchview.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.example.junweiliu.commonlysearchview.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by junweiliu on 16/5/31.
 */
public class CommolySearchView<T> extends LinearLayout {
    /**
     * 上下文
     */
    private Context mContext;
    /**
     * 編輯框
     */
    private EditText mEditText;
    /**
     * 清除按鈕
     */
    private ImageView mClearImg;
    /**
     * 搜索圖標
     */
    private ImageView mSearchBarImg;
    /**
     * 適配器
     */
    private BaseAdapter mAdapter;
    /**
     * 數據源
     */
    private List<T> mDatas = new ArrayList<T>();
    /**
     * 數據源副本
     */
    private List<T> mDupDatas = new ArrayList<T>();

    /**
     * 篩選後的數據源
     */
    private List<T> mFilterDatas = new ArrayList<T>();
    /**
     * 篩選後的數據源副本
     */
    private List<T> mDupFilterDatas = new ArrayList<T>();
    /**
     * 搜索圖標
     */
    private Bitmap mSearchIcon;
    /**
     * 搜索框距離左邊邊距
     */
    private int mSearchIconMarginLeft;
    /**
     * 搜索框距離右邊邊距
     */
    private int mSearchIconMarginRight;
    /**
     * 清除圖標
     */
    private Bitmap mClearIcon;
    /**
     * 清除圖標距離左邊邊距
     */
    private int mClearIconMarginLeft;
    /**
     * 清除圖標距離右邊邊距
     */
    private int mClearIconMarginRight;
    /**
     * 搜索文字大小
     */
    private int mSearchTextSize;
    /**
     * 搜索文字顏色
     */
    private int mSearchTextColor;

    /**
     * 回調接口
     *
     * @param <T>
     */
    public interface SearchDatas<T> {
        /**
         * 參數一:全部數據,參數二:篩選後的數據,參數三:輸入的內容
         *
         * @param datas
         * @param filterdatas
         * @param inputstr
         * @return
         */
        List<T> filterDatas(List<T> datas, List<T> filterdatas, String inputstr);
    }

    /**
     * 回調
     */
    private SearchDatas<T> mListener;

    /**
     * 設置回調
     *
     * @param listener
     */
    public void setSearchDataListener(SearchDatas<T> listener) {
        mListener = listener;

    }

    public CommolySearchView(Context context) {
        this(context, null);
    }

    public CommolySearchView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CommolySearchView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        // 自定義屬性
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CommolySearchView);
        Drawable searchD = ta.getDrawable(R.styleable.CommolySearchView_SearchBarIconSrc);
        mSearchIcon = drawableToBitamp(searchD);
        mSearchIconMarginLeft = px2dip(context, ta.getDimensionPixelOffset(R.styleable.CommolySearchView_SearchBarIconMarginLeft, 0));
        mSearchIconMarginRight = px2dip(context, ta.getDimensionPixelOffset(R.styleable.CommolySearchView_SearchBarIconMarginRight, 0));
        Drawable clearD = ta.getDrawable(R.styleable.CommolySearchView_ClearIconSrc);
        mClearIcon = drawableToBitamp(clearD);
        mClearIconMarginLeft = px2dip(context, ta.getDimensionPixelOffset(R.styleable.CommolySearchView_ClearIconMarginLeft, 0));
        mClearIconMarginRight = px2dip(context, ta.getDimensionPixelOffset(R.styleable.CommolySearchView_ClearIconMarginRight, 0));
        mSearchTextSize = px2sp(context, ta.getDimensionPixelOffset(R.styleable.CommolySearchView_SearchTextSize, 0));
        mSearchTextColor = ta.getColor(R.styleable.CommolySearchView_SearchTextColor, 0);
        ta.recycle();
        // 綁定佈局文件
        LayoutInflater.from(context).inflate(R.layout.searchview_layout, this);
        initView();
    }

    /**
     * 初始化控件
     */
    private void initView() {
        mEditText = (EditText) findViewById(R.id.et_search);
        mClearImg = (ImageView) findViewById(R.id.iv_search_clear);
        mSearchBarImg = (ImageView) findViewById(R.id.iv_search_icon);
        // 處理自定義屬性
        if (0 != mSearchIconMarginLeft || 0 != mSearchIconMarginRight) {
            mSearchBarImg.setPadding(mSearchIconMarginLeft, 0, mSearchIconMarginRight, 0);
        }
        if (0 != mClearIconMarginLeft || 0 != mClearIconMarginRight) {
            mClearImg.setPadding(mClearIconMarginLeft, 0, mClearIconMarginRight, 0);
        }
        if (null != mSearchIcon) {
            mSearchBarImg.setImageBitmap(mSearchIcon);
        }
        if (null != mClearIcon) {
            mClearImg.setImageBitmap(mClearIcon);
        }
        if (0 != mSearchTextSize) {
            mEditText.setTextSize(mSearchTextSize);
        }
        if (0 != mSearchTextColor) {
            mEditText.setTextColor(mSearchTextColor);
        }
        // 清空按鈕處理事件
        mClearImg.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                mEditText.setText("");
                mClearImg.setVisibility(View.GONE);
                if (null != mDatas) {
                    mDatas.clear();
                }
                mDatas.addAll(mDupDatas);
                mAdapter.notifyDataSetChanged();
                reSetDatas();
            }
        });
        // 搜索欄處理事件
        mEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                // 獲取篩選後的數據
                mFilterDatas = mListener.filterDatas(mDupDatas, mFilterDatas, charSequence.toString());
                if (charSequence.toString().length() > 0 && !charSequence.toString().equals("")) {
                    mClearImg.setVisibility(View.VISIBLE);
                } else {
                    mClearImg.setVisibility(View.GONE);
                }
                if (null != mDatas) {
                    mDatas.clear();
                }
                mDatas.addAll(mFilterDatas);
                mAdapter.notifyDataSetChanged();
                reSetDatas();
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }

    /**
     * 獲取篩選後的數據
     *
     * @return
     */
    public List<T> getFilterDatas() {
        return (null != mDupFilterDatas && mDupFilterDatas.size() > 0) ? mDupFilterDatas : mDupDatas;
    }


    /**
     * 重置數據
     */
    private void reSetDatas() {
        if (null != mFilterDatas) {
            if (null != mDupFilterDatas) {
                mDupFilterDatas.clear();
                mDupFilterDatas.addAll(mFilterDatas);
            }
            mFilterDatas.clear();
        }
    }


    /**
     * 設置數據源
     *
     * @param datas
     */
    public void setDatas(List<T> datas) {
        if (null == datas) {
            return;
        }
        if (null != mDatas) {
            mDatas.clear();
        }
        if (null != mDupDatas) {
            mDupDatas.clear();
        }
        mDatas = datas;
        mDupDatas.addAll(mDatas);
    }

    /**
     * 設置適配器
     *
     * @param adapter
     */
    public void setAdapter(BaseAdapter adapter) {
        if (null == adapter) {
            return;
        }
        mAdapter = adapter;
    }

    /**
     * drawable轉bitmap
     *
     * @param drawable
     * @return
     */
    private Bitmap drawableToBitamp(Drawable drawable) {
        if (null == drawable) {
            return null;
        }
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bd = (BitmapDrawable) drawable;
            return bd.getBitmap();
        }
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();
        Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }

    /**
     * 將px值轉換爲dip或dp值,保證尺寸大小不變
     *
     * @param pxValue
     * @return
     * @param(DisplayMetrics類中屬性density)
     */
    public int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }


    /**
     * 將px值轉換爲sp值,保證文字大小不變
     *
     * @param pxValue
     * @return
     */
    public static int px2sp(Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }
}

源碼下載

源碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章