由于項(xiàng)目很多地方需要搜索框,就自定義了一個(gè)SearchView控件,順便復(fù)習(xí)下自定義View的操作。
一.復(fù)用性
雖然我自己在多個(gè)地方進(jìn)行復(fù)制粘貼也很省時(shí),但是總覺(jué)得這樣的做法太Low了,所以還是抽出來(lái)自定義一個(gè)view,看看效果。

這是一個(gè)默認(rèn)樣式下的搜索框,當(dāng)然也可以改

抽離出以后再使用的話會(huì)比較方便。
二.默認(rèn)輸入框結(jié)構(gòu)
目錄

第一個(gè)是view,三個(gè)接口分別表示監(jiān)聽(tīng)搜索框的焦點(diǎn),監(jiān)聽(tīng)搜索框的搜索操作和擴(kuò)展自定義View時(shí)的行為。
View結(jié)構(gòu)
默認(rèn)的View的布局如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rl_search"
android:focusable="true"
android:focusableInTouchMode="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:id="@+id/ll_search"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/iv_search"
android:layout_toLeftOf="@+id/edt_search"
android:layout_marginRight="10dp"
/>
<EditText
android:gravity="top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/get_gray_code"
android:background="@null"
android:id="@+id/edt_search"
android:maxLines="1"
/>
</LinearLayout>
</RelativeLayout>
簡(jiǎn)單說(shuō)說(shuō)這樣設(shè)計(jì)的理由,本來(lái)圖片和Edit是可以直接用一個(gè)EditText來(lái)完成的,但是為了考慮擴(kuò)展性所以分成了ImageView和EditText。
然后我是不想在中間多加一層的LinearLayout布局的,但是如果顯示在中間的情況布局就會(huì)看著挺別扭,而且直接用RelativeLayout 去動(dòng)態(tài)改變兩個(gè)子控件的布局的話就會(huì)做很多操作,所以在中間加了一層,我覺(jué)得性能方面也不會(huì)影響很大。
再講講這樣設(shè)計(jì)是為了確保存在ImageView和EditText,布局可以自定義進(jìn)行擴(kuò)展,不一定要使用默認(rèn)的,但是一定要有ImageView和EditText,這個(gè)之后會(huì)說(shuō)。
三.自定義屬性
添加部分自定義屬性,方便改變一些常用的樣式
<!-- 搜索框 -->
<declare-styleable name="kylin_search_style">
<attr name="img_src" format="reference"/><!-- 圖片地址 -->
<attr name="img_size" format="dimension"/><!-- 圖片大小 -->
<attr name="img_visibility" format="boolean"/><!-- 圖片顯示/隱藏 -->
<attr name="show_location" format="enum">
<enum name="left" value="0"/>
<enum name="right" value="2"/>
<enum name="centre" value="1"/>
</attr>
<attr name="edt_hint" format="string"/><!-- 提示文字 -->
<attr name="edt_size" format="dimension"/><!-- 提示文字大小 -->
<attr name="edt_hint_color" format="color"/><!-- 提示文字的顏色 -->
<attr name="search_backgroup" format="reference"/><!-- 搜索框背景 -->
<attr name="search_padding" format="reference"/><!-- 搜索框背景 -->
</declare-styleable>
show_location表示展示的位置,其它都有注解。
不僅如此,還會(huì)在View內(nèi)部加入返回子控件的操作,可以在外部設(shè)置,因?yàn)槲矣X(jué)得如果在內(nèi)部定義太多屬性的話,要在View內(nèi)寫(xiě)很多變量,這種做法我覺(jué)得很不劃算,所以只寫(xiě)了一些常變化的,下面的方法返回控件。
public EditText getSearchEditText() {
return edtSearch;
}
public ImageView getSearchImageView() {
return ivSearch;
}
public ViewGroup getSearchFrameView() {
return rlSearch;
}
四.初始化操作
protected void initView() {
// 初始化搜索邊框
rlSearch.setBackgroundResource(seaBackgroup);
rlSearch.setPadding((int) seaPadding, (int) seaPadding, (int) seaPadding, (int) seaPadding);
ViewGroup.LayoutParams llLp = llSearch.getLayoutParams();
if (showType == 0){
((RelativeLayout.LayoutParams) llLp).addRule(RelativeLayout.ALIGN_PARENT_LEFT);
}else if (showType == 1) {
((RelativeLayout.LayoutParams) llLp).addRule(RelativeLayout.CENTER_IN_PARENT);
}else if (showType == 2){
((RelativeLayout.LayoutParams) llLp).addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
}
llSearch.setLayoutParams(llLp);
// 初始化圖片
ViewGroup.LayoutParams lp = ivSearch.getLayoutParams();
lp.width = (int) imgSize;
lp.height = (int) imgSize;
ivSearch.setLayoutParams(lp);
ivSearch.setImageResource(imgRid);
// 初始化輸入框
edtHint = (edtHint == null || edtHint == "" || edtHint.equals(null) || edtHint.equals(""))
? "請(qǐng)輸入搜索內(nèi)容" : edtHint;
edtSearch.setHint(edtHint);
edtSearch.setHintTextColor(edtHintColor);
edtSearch.setTextSize(edt_size);
}
就是初始化設(shè)置那些常用的屬性。關(guān)鍵是下面的操作,為了增加擴(kuò)展性,我添加了一步類(lèi)似鉤子的操作。
private void init(){
// 提供自定義樣式的鉤子
int layoutId = getLayoutId();
if (layoutId == -1){
seachView = LayoutInflater.from(getContext()).inflate(R.layout.layout_base_seach,this,false);
this.addView(seachView);
ivSearch = (ImageView) seachView.findViewById(R.id.iv_search);
edtSearch = (EditText) seachView.findViewById(R.id.edt_search);
rlSearch = (RelativeLayout) seachView.findViewById(R.id.rl_search);
llSearch = (LinearLayout) seachView.findViewById(R.id.ll_search);
initView();
}else {
seachView = LayoutInflater.from(getContext()).inflate(layoutId,this,false);
this.addView(seachView);
ivSearch = getImageView();
edtSearch = getEditText();
rlSearch = getSearchFrame();
}
// 初始化事件監(jiān)聽(tīng)
initAllListener();
}
@Override
public int getLayoutId(){
return -1;
}
@Override
public ImageView getImageView(){
return null;
}
@Override
public EditText getEditText(){
return null;
}
@Override
public ViewGroup getSearchFrame(){
return null;
}
開(kāi)發(fā)者可以寫(xiě)個(gè)類(lèi)繼承這個(gè)控件,然后重寫(xiě)上邊說(shuō)的SearchExtendImpl接口的4個(gè)方法
public interface SearchExtendImpl {
int getLayoutId();
ImageView getImageView();
EditText getEditText();
ViewGroup getSearchFrame();
}
如果布局和默認(rèn)布局很大程度不同的話,可以使用繼承的方式,但是要把搜索框的圖標(biāo)用getImageView來(lái)返給父類(lèi),輸入框用getEditText傳,搜索邊框用getSearchFrame傳。我這里這樣設(shè)計(jì)的目的是因?yàn)椋@東西子控件就兩三個(gè),所以在布局方面我沒(méi)必要做太多的擴(kuò)展,就幾個(gè)子控件,做過(guò)多的擴(kuò)展不如重做一個(gè)新的,但是邏輯是可以復(fù)用的。
五.搜索邏輯
這部分是可以服用的,所以不管是使用我寫(xiě)的默認(rèn)的搜索框樣式,還是開(kāi)發(fā)者自定義的布局都可以服用這個(gè)邏輯。
protected void initAllListener(){
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(getContext().INPUT_METHOD_SERVICE);
if (edtSearch != null) {
// 點(diǎn)擊事件
edtSearch.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
edtSearch.setFocusable(true);//設(shè)置輸入框可聚集
edtSearch.setFocusableInTouchMode(true);//設(shè)置觸摸聚焦
edtSearch.requestFocus();//請(qǐng)求焦點(diǎn)
edtSearch.findFocus();//獲取焦點(diǎn)
}
});
// 監(jiān)聽(tīng)焦點(diǎn)
edtSearch.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
imm.showSoftInput(v, InputMethodManager.SHOW_FORCED); //顯示軟鍵盤(pán)
} else {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0); //隱藏軟鍵盤(pán)
}
if (onSearchFocusListener != null){
onSearchFocusListener.searchFocusChange(v,hasFocus);
}
}
});
// 監(jiān)聽(tīng)軟鍵盤(pán)的按鍵
edtSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
//回車(chē)等操作
if (actionId == EditorInfo.IME_ACTION_SEND
|| actionId == EditorInfo.IME_ACTION_DONE
|| actionId == EditorInfo.IME_ACTION_SEARCH
|| actionId == EditorInfo.IME_ACTION_GO
|| (event != null && KeyEvent.KEYCODE_ENTER == event.getKeyCode()
&& KeyEvent.ACTION_DOWN == event.getAction())) {
// 搜索
search();
}
return true;
}
});
}
}
這里涉及兩個(gè)比較啰嗦的東西,光標(biāo)(焦點(diǎn))和軟鍵盤(pán),軟鍵盤(pán)的操做相關(guān)的一個(gè)類(lèi)InputMethodManager,我沒(méi)有很好去理解,只是查了一些大概的用法。
(1)我先給輸入框設(shè)置點(diǎn)擊之后獲取焦點(diǎn)
edtSearch.setFocusable(true);//設(shè)置輸入框可聚集
edtSearch.setFocusableInTouchMode(true);//設(shè)置觸摸聚焦
edtSearch.requestFocus();//請(qǐng)求焦點(diǎn)
edtSearch.findFocus();//獲取焦點(diǎn)
為什么要這樣做,因?yàn)槲抑笠鍪Ы共僮鳎绻粚?xiě)這個(gè)代碼的話,我這邊會(huì)出個(gè)BUG,失焦后就無(wú)法再重新獲取焦點(diǎn)。
(2)失焦操作
/**
* 讓EditText失去焦點(diǎn)
*/
public void lostRocus(){
if(edtSearch != null) {
edtSearch.setFocusable(false);
}
}
(3)關(guān)聯(lián)軟鍵盤(pán)
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
imm.showSoftInput(v, InputMethodManager.SHOW_FORCED); //顯示軟鍵盤(pán)
} else {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0); //隱藏軟鍵盤(pán)
}
}
獲取焦點(diǎn)后軟鍵盤(pán)彈起,失去焦點(diǎn)后軟鍵盤(pán)消失。
六.全部代碼
項(xiàng)目沒(méi)有放到gayhub,一是有些BUG,我等下會(huì)說(shuō),二是我沒(méi)寫(xiě)自定義布局的demo,三是我沒(méi)寫(xiě)文檔。所以我先寫(xiě)文章,過(guò)后完善了再把項(xiàng)目丟到gayhub。
1.默認(rèn)樣式布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rl_search"
android:focusable="true"
android:focusableInTouchMode="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:id="@+id/ll_search"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/iv_search"
android:layout_toLeftOf="@+id/edt_search"
android:layout_marginRight="10dp"
/>
<EditText
android:gravity="top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/get_gray_code"
android:background="@null"
android:id="@+id/edt_search"
android:maxLines="1"
/>
</LinearLayout>
</RelativeLayout>
2.自定義屬性
在attrs中添加
<!-- 搜索框 -->
<declare-styleable name="kylin_search_style">
<attr name="img_src" format="reference"/><!-- 圖片地址 -->
<attr name="img_size" format="dimension"/><!-- 圖片大小 -->
<attr name="img_visibility" format="boolean"/><!-- 圖片顯示/隱藏 -->
<attr name="show_location" format="enum">
<enum name="left" value="0"/>
<enum name="right" value="2"/>
<enum name="centre" value="1"/>
</attr>
<attr name="edt_hint" format="string"/><!-- 提示文字 -->
<attr name="edt_size" format="dimension"/><!-- 提示文字大小 -->
<attr name="edt_hint_color" format="color"/><!-- 提示文字的顏色 -->
<attr name="search_backgroup" format="reference"/><!-- 搜索框背景 -->
<attr name="search_padding" format="reference"/><!-- 搜索框背景 -->
</declare-styleable>
3.三個(gè)定義的接口
public interface OnSearchFocusListener {
void searchFocusChange(View v, boolean hasFocus);
}
public interface OnSearchListener {
void search(String content);
}
public interface SearchExtendImpl {
int getLayoutId();
ImageView getImageView();
EditText getEditText();
ViewGroup getSearchFrame();
}
4.View代碼
/**
* Created by kylin on 2018/2/23.
*/
public class KylinSearchView extends FrameLayout implements SearchExtendImpl{
protected Context context;
protected View seachView;
protected ImageView ivSearch;
protected EditText edtSearch;
protected ViewGroup rlSearch;
protected LinearLayout llSearch;
/**
* 屬性定義
*/
protected int seaBackgroup;
protected int imgRid;
protected float imgSize;
protected String edtHint;
protected int edtHintColor;
protected float seaPadding;
protected int showType;
protected float edt_size;
/**
* 事件
*/
protected OnSearchListener onSearchListener;
protected OnSearchFocusListener onSearchFocusListener;
public KylinSearchView(Context context) {
super(context);
init();
}
public KylinSearchView(Context context, AttributeSet attrs) {
super(context, attrs);
initAttrs(context, attrs);
init();
}
public KylinSearchView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(context, attrs);
init();
}
/**
* 設(shè)置屬性
*/
private void initAttrs(Context context,AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.kylin_search_style);
imgRid = typedArray.getInteger(R.styleable.kylin_search_style_img_src,R.mipmap.product_serch);
// 默認(rèn)的float是px,所以要轉(zhuǎn)成dp
imgSize = typedArray.getDimension(R.styleable.kylin_search_style_img_size, DimensionUtils.dip2px(context,24));
edtHint = typedArray.getString(R.styleable.kylin_search_style_edt_hint);
edtHintColor = typedArray.getColor(R.styleable.kylin_search_style_edt_hint, getResources().getColor(R.color.get_gray_code));
seaBackgroup = typedArray.getInteger(R.styleable.kylin_search_style_search_backgroup,R.drawable.bg_search_default);
seaPadding = typedArray.getDimension(R.styleable.kylin_search_style_img_size, DimensionUtils.dip2px(context,8));
showType = typedArray.getInteger(R.styleable.kylin_search_style_show_location,0);
edt_size = typedArray.getDimension(R.styleable.kylin_search_style_edt_size, 18);
typedArray.recycle();
}
/**
* 初始化操作
*/
private void init(){
// 提供自定義樣式的鉤子
int layoutId = getLayoutId();
if (layoutId == -1){
seachView = LayoutInflater.from(getContext()).inflate(R.layout.layout_base_seach,this,false);
this.addView(seachView);
ivSearch = (ImageView) seachView.findViewById(R.id.iv_search);
edtSearch = (EditText) seachView.findViewById(R.id.edt_search);
rlSearch = (RelativeLayout) seachView.findViewById(R.id.rl_search);
llSearch = (LinearLayout) seachView.findViewById(R.id.ll_search);
initView();
}else {
seachView = LayoutInflater.from(getContext()).inflate(layoutId,this,false);
this.addView(seachView);
ivSearch = getImageView();
edtSearch = getEditText();
rlSearch = getSearchFrame();
}
// 初始化事件監(jiān)聽(tīng)
initAllListener();
}
@Override
public int getLayoutId(){
return -1;
}
@Override
public ImageView getImageView(){
return null;
}
@Override
public EditText getEditText(){
return null;
}
@Override
public ViewGroup getSearchFrame(){
return null;
}
protected void initView() {
// 初始化搜索邊框
rlSearch.setBackgroundResource(seaBackgroup);
rlSearch.setPadding((int) seaPadding, (int) seaPadding, (int) seaPadding, (int) seaPadding);
ViewGroup.LayoutParams llLp = llSearch.getLayoutParams();
if (showType == 0){
((RelativeLayout.LayoutParams) llLp).addRule(RelativeLayout.ALIGN_PARENT_LEFT);
}else if (showType == 1) {
((RelativeLayout.LayoutParams) llLp).addRule(RelativeLayout.CENTER_IN_PARENT);
}else if (showType == 2){
((RelativeLayout.LayoutParams) llLp).addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
}
llSearch.setLayoutParams(llLp);
// 初始化圖片
ViewGroup.LayoutParams lp = ivSearch.getLayoutParams();
lp.width = (int) imgSize;
lp.height = (int) imgSize;
ivSearch.setLayoutParams(lp);
ivSearch.setImageResource(imgRid);
// 初始化輸入框
edtHint = (edtHint == null || edtHint == "" || edtHint.equals(null) || edtHint.equals(""))
? "請(qǐng)輸入搜索內(nèi)容" : edtHint;
edtSearch.setHint(edtHint);
edtSearch.setHintTextColor(edtHintColor);
edtSearch.setTextSize(edt_size);
}
protected void initAllListener(){
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(getContext().INPUT_METHOD_SERVICE);
if (edtSearch != null) {
// 點(diǎn)擊事件
edtSearch.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
edtSearch.setFocusable(true);//設(shè)置輸入框可聚集
edtSearch.setFocusableInTouchMode(true);//設(shè)置觸摸聚焦
edtSearch.requestFocus();//請(qǐng)求焦點(diǎn)
edtSearch.findFocus();//獲取焦點(diǎn)
}
});
// 監(jiān)聽(tīng)焦點(diǎn)
edtSearch.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
imm.showSoftInput(v, InputMethodManager.SHOW_FORCED); //顯示軟鍵盤(pán)
} else {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0); //隱藏軟鍵盤(pán)
}
if (onSearchFocusListener != null){
onSearchFocusListener.searchFocusChange(v,hasFocus);
}
}
});
// 監(jiān)聽(tīng)軟鍵盤(pán)的按鍵
edtSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
//回車(chē)等操作
if (actionId == EditorInfo.IME_ACTION_SEND
|| actionId == EditorInfo.IME_ACTION_DONE
|| actionId == EditorInfo.IME_ACTION_SEARCH
|| actionId == EditorInfo.IME_ACTION_GO
|| (event != null && KeyEvent.KEYCODE_ENTER == event.getKeyCode()
&& KeyEvent.ACTION_DOWN == event.getAction())) {
// 搜索
search();
}
return true;
}
});
}
}
/**
* 獲取搜索框的內(nèi)容
*/
public String getSearchContent(){
if (edtSearch == null){
return null;
}
return edtSearch.getText().toString();
}
/**
* 清空搜索框
*/
public void clearSearch(){
edtSearch.setText("");
}
/**
* 讓EditText失去焦點(diǎn)
*/
public void lostRocus(){
if(edtSearch != null) {
edtSearch.setFocusable(false);
}
}
/**
* 搜索
*/
public void search(){
lostRocus();
if (onSearchListener != null){
onSearchListener.search(getSearchContent());
}
}
public void setOnSearchListener(OnSearchListener onSearchListener) {
this.onSearchListener = onSearchListener;
}
public void setOnSearchFocusListener(OnSearchFocusListener onSearchFocusListener) {
this.onSearchFocusListener = onSearchFocusListener;
}
public EditText getSearchEditText() {
return edtSearch;
}
public ImageView getSearchImageView() {
return ivSearch;
}
public ViewGroup getSearchFrameView() {
return rlSearch;
}
public void setImgSize(float size){
ViewGroup.LayoutParams lp = ivSearch.getLayoutParams();
lp.width = (int) size;
lp.height = (int) size;
ivSearch.setLayoutParams(lp);
}
public void setTextSize(float size){
edtSearch.setTextSize(size);
}
}
之中有些操作,比如 DimensionUtils.dip2px就是轉(zhuǎn)尺寸單位,這些命名就很明顯,自己寫(xiě)個(gè)工具類(lèi)轉(zhuǎn)就行。
伸手黨要用的話只能全抄了,gayhub沒(méi)這么快。

模擬一下,軟鍵盤(pán)回車(chē)后失去焦點(diǎn)。
六.BUG
我在玩的時(shí)候玩出個(gè)BUG,關(guān)鍵是這個(gè)BUG我還不知道要怎么去表達(dá),設(shè)置圖片的尺寸
imgSize = typedArray.getDimension(R.styleable.kylin_search_style_img_size, DimensionUtils.dip2px(context,24));
我這里默認(rèn)填24dp是正常,我如果在控件中設(shè)置
app:img_size="24dp"

圖片大小沒(méi)變,但是間距莫名其妙變大了。還有文字也是,用sp的話比正常情況的sp大得多。所以我現(xiàn)在還不懂這個(gè)format="dimension"出了什么毛病,這是其中一個(gè)問(wèn)題。
還有一個(gè)問(wèn)題是軟鍵盤(pán),這個(gè)東西比較容易出BUG,我無(wú)法保證不同的軟鍵盤(pán)或者不同的版本不會(huì)出問(wèn)題,我是感覺(jué)之后可能要做適配的問(wèn)題。
暫時(shí)就這些,簡(jiǎn)單封裝了一下,完善也只能在之后碰到問(wèn)題再去完善,然后之后我有時(shí)間寫(xiě)個(gè)demo寫(xiě)個(gè)文檔再放到gayhub
更新
項(xiàng)目地址
https://github.com/994866755/handsomeYe.SearchView
BUG修改
之前說(shuō)有幾個(gè)傳資源時(shí)的BUG,我先在這寫(xiě)出來(lái),gayhub的過(guò)后我改了再傳。
1.背景資源的類(lèi)型寫(xiě)錯(cuò)了
seaBackgroup = typedArray.getResourceId(R.styleable.kylin_search_style_search_backgroup,R.drawable.bg_search_default);
這里我之前用getInteger用錯(cuò)了。
2.設(shè)置字體大小
我之前說(shuō)怎么設(shè)置字體大小總是出問(wèn)題,然后發(fā)現(xiàn)是setTextSize方法默認(rèn)是sp的,然后我用getDimension傳進(jìn)來(lái)的會(huì)轉(zhuǎn)成px,這樣就造成了px套到sp上,尺寸就錯(cuò)了,應(yīng)該把類(lèi)型再做一次轉(zhuǎn)換
edtSearch.setTextSize(TypedValue.COMPLEX_UNIT_PX,edt_size);
這個(gè)問(wèn)題我之前也碰到過(guò),只是忘了做筆記,所以不記得了。詳細(xì)的原因可以看下這篇博客,講得很不錯(cuò)。
http://www.itdecent.cn/p/7f2941dbfb17
3.設(shè)置自適應(yīng)大小
我發(fā)現(xiàn)用getDimension如果設(shè)默認(rèn)大小的話就擴(kuò)展性太差了,所以想改成自適應(yīng),但是我又不知道這個(gè)方法要怎么設(shè)置默認(rèn)值為自適應(yīng),所以我就投機(jī)用正負(fù)值來(lái)判斷,默認(rèn)為負(fù)數(shù)就是自適應(yīng)的情況。
imgSize = typedArray.getDimension(R.styleable.kylin_search_style_img_size, -1);
// 初始化圖片
ViewGroup.LayoutParams lp = ivSearch.getLayoutParams();
if (imgSize >= 0) {
lp.width = (int) imgSize;
lp.height = (int) imgSize;
}else {
lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
}
ivSearch.setLayoutParams(lp);
補(bǔ)充
我想做個(gè)功能的補(bǔ)充是關(guān)于軟鍵盤(pán)的,有很多時(shí)候,我們需要在軟鍵盤(pán)彈出的情況下,點(diǎn)擊空白處的話就隱藏軟鍵盤(pán)。
而這個(gè)操作我這邊不好一起封裝到searchView里面,我覺(jué)得可以直接在頁(yè)面中用攔截事件來(lái)實(shí)現(xiàn)這功能。
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN){
// 收軟鍵盤(pán)
InputMethodManager imm = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
if (imm.isActive()){
imm.hideSoftInputFromWindow(searchView.getSearchEditText().getWindowToken(), 0); //隱藏軟鍵盤(pán)
}
}
return super.dispatchTouchEvent(ev);
}
這樣寫(xiě)就能實(shí)現(xiàn)點(diǎn)擊頁(yè)面時(shí)隱藏軟鍵盤(pán)的操作,比如美團(tuán)的搜索就是點(diǎn)頁(yè)面能隱藏軟鍵盤(pán)。
但是這里有個(gè)問(wèn)題,dispatchTouchEvent方法會(huì)頻繁的調(diào)用,只要一碰到這個(gè)頁(yè)面就會(huì)調(diào)用這個(gè)方法,而我在這里面創(chuàng)建InputMethodManager 的話是不是會(huì)一直創(chuàng)建對(duì)象。
我看Monitors來(lái)測(cè)試,其實(shí)我不是很會(huì)用Monitors,然后用我單身20年的手速不斷搓屏幕,發(fā)現(xiàn)內(nèi)存一直在增長(zhǎng),所以我覺(jué)得InputMethodManager 在dispatchTouchEvent中創(chuàng)建不是很好,把它抽出去,在全局中創(chuàng)建。