前言
之前寫過一篇文章是關於搜索框的封裝( 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);
}
}