Android搜索控件SearchView

由于項(xiàng)目很多地方需要搜索框暂雹,就自定義了一個SearchView控件,順便復(fù)習(xí)下自定義View的操作。

一.復(fù)用性

雖然我自己在多個地方進(jìn)行復(fù)制粘貼也很省時田炭,但是總覺得這樣的做法太Low了,所以還是抽出來自定義一個view漓柑,看看效果教硫。

默認(rèn)情況

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


image.png

抽離出以后再使用的話會比較方便。

二.默認(rèn)輸入框結(jié)構(gòu)

目錄
image.png

第一個是view瞬矩,三個接口分別表示監(jiān)聽搜索框的焦點(diǎn)茶鉴,監(jiān)聽搜索框的搜索操作和擴(kuò)展自定義View時的行為。

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>

簡單說說這樣設(shè)計的理由景用,本來圖片和Edit是可以直接用一個EditText來完成的涵叮,但是為了考慮擴(kuò)展性所以分成了ImageView和EditText。
然后我是不想在中間多加一層的LinearLayout布局的伞插,但是如果顯示在中間的情況布局就會看著挺別扭割粮,而且直接用RelativeLayout 去動態(tài)改變兩個子控件的布局的話就會做很多操作,所以在中間加了一層媚污,我覺得性能方面也不會影響很大舀瓢。

再講講這樣設(shè)計是為了確保存在ImageView和EditText,布局可以自定義進(jìn)行擴(kuò)展杠步,不一定要使用默認(rèn)的氢伟,但是一定要有ImageView和EditText,這個之后會說幽歼。

三.自定義屬性

添加部分自定義屬性朵锣,方便改變一些常用的樣式

<!-- 搜索框 -->
    <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表示展示的位置,其它都有注解甸私。

不僅如此诚些,還會在View內(nèi)部加入返回子控件的操作,可以在外部設(shè)置皇型,因?yàn)槲矣X得如果在內(nèi)部定義太多屬性的話诬烹,要在View內(nèi)寫很多變量,這種做法我覺得很不劃算弃鸦,所以只寫了一些常變化的绞吁,下面的方法返回控件。

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(""))
                ? "請輸入搜索內(nèi)容" : edtHint;
        edtSearch.setHint(edtHint);
        edtSearch.setHintTextColor(edtHintColor);
        edtSearch.setTextSize(edt_size);


    }

就是初始化設(shè)置那些常用的屬性唬格。關(guān)鍵是下面的操作家破,為了增加擴(kuò)展性,我添加了一步類似鉤子的操作购岗。

 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)聽
        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;
    }

開發(fā)者可以寫個類繼承這個控件汰聋,然后重寫上邊說的SearchExtendImpl接口的4個方法

public interface SearchExtendImpl {

    int getLayoutId();

    ImageView getImageView();

    EditText getEditText();

    ViewGroup getSearchFrame();

}

如果布局和默認(rèn)布局很大程度不同的話,可以使用繼承的方式喊积,但是要把搜索框的圖標(biāo)用getImageView來返給父類烹困,輸入框用getEditText傳,搜索邊框用getSearchFrame傳乾吻。我這里這樣設(shè)計的目的是因?yàn)樗杳罚@東西子控件就兩三個拟蜻,所以在布局方面我沒必要做太多的擴(kuò)展,就幾個子控件女淑,做過多的擴(kuò)展不如重做一個新的瞭郑,但是邏輯是可以復(fù)用的。

五.搜索邏輯

這部分是可以服用的鸭你,所以不管是使用我寫的默認(rèn)的搜索框樣式屈张,還是開發(fā)者自定義的布局都可以服用這個邏輯。

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();//請求焦點(diǎn)
                    edtSearch.findFocus();//獲取焦點(diǎn)
                }
            });
            // 監(jiān)聽焦點(diǎn)
            edtSearch.setOnFocusChangeListener(new OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if (hasFocus) {
                        imm.showSoftInput(v, InputMethodManager.SHOW_FORCED); //顯示軟鍵盤
                    } else {
                        imm.hideSoftInputFromWindow(v.getWindowToken(), 0); //隱藏軟鍵盤
                    }
                    if (onSearchFocusListener != null){
                        onSearchFocusListener.searchFocusChange(v,hasFocus);
                    }
                }
            });
            // 監(jiān)聽軟鍵盤的按鍵
            edtSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                @Override
                public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                    //回車等操作
                    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;
                }
            });
        }
    }

這里涉及兩個比較啰嗦的東西袱巨,光標(biāo)(焦點(diǎn))和軟鍵盤阁谆,軟鍵盤的操做相關(guān)的一個類InputMethodManager,我沒有很好去理解愉老,只是查了一些大概的用法场绿。

(1)我先給輸入框設(shè)置點(diǎn)擊之后獲取焦點(diǎn)
edtSearch.setFocusable(true);//設(shè)置輸入框可聚集
edtSearch.setFocusableInTouchMode(true);//設(shè)置觸摸聚焦
edtSearch.requestFocus();//請求焦點(diǎn)
edtSearch.findFocus();//獲取焦點(diǎn)

為什么要這樣做,因?yàn)槲抑笠鍪Ы共僮骷等耄绻粚戇@個代碼的話焰盗,我這邊會出個BUG,失焦后就無法再重新獲取焦點(diǎn)咒林。

(2)失焦操作
/**
     *  讓EditText失去焦點(diǎn)
     */
    public void lostRocus(){
        if(edtSearch != null) {
            edtSearch.setFocusable(false);
        }
    }
(3)關(guān)聯(lián)軟鍵盤
              public void onFocusChange(View v, boolean hasFocus) {
                    if (hasFocus) {
                        imm.showSoftInput(v, InputMethodManager.SHOW_FORCED); //顯示軟鍵盤
                    } else {
                        imm.hideSoftInputFromWindow(v.getWindowToken(), 0); //隱藏軟鍵盤
                    }
                }

獲取焦點(diǎn)后軟鍵盤彈起熬拒,失去焦點(diǎn)后軟鍵盤消失。

六.全部代碼

項(xiàng)目沒有放到gayhub垫竞,一是有些BUG澎粟,我等下會說,二是我沒寫自定義布局的demo欢瞪,三是我沒寫文檔活烙。所以我先寫文章,過后完善了再把項(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.三個定義的接口

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)聽
        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(""))
                ? "請輸入搜索內(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();//請求焦點(diǎn)
                    edtSearch.findFocus();//獲取焦點(diǎn)
                }
            });
            // 監(jiān)聽焦點(diǎn)
            edtSearch.setOnFocusChangeListener(new OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if (hasFocus) {
                        imm.showSoftInput(v, InputMethodManager.SHOW_FORCED); //顯示軟鍵盤
                    } else {
                        imm.hideSoftInputFromWindow(v.getWindowToken(), 0); //隱藏軟鍵盤
                    }
                    if (onSearchFocusListener != null){
                        onSearchFocusListener.searchFocusChange(v,hasFocus);
                    }
                }
            });
            // 監(jiān)聽軟鍵盤的按鍵
            edtSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                @Override
                public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                    //回車等操作
                    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)尺寸單位赎离,這些命名就很明顯盛撑,自己寫個工具類轉(zhuǎn)就行。

伸手黨要用的話只能全抄了曾我,gayhub沒這么快。

tmp2.gif

模擬一下健民,軟鍵盤回車后失去焦點(diǎn)抒巢。

六.BUG

我在玩的時候玩出個BUG,關(guān)鍵是這個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"
image.png

圖片大小沒變稚晚,但是間距莫名其妙變大了。還有文字也是型诚,用sp的話比正常情況的sp大得多客燕。所以我現(xiàn)在還不懂這個format="dimension"出了什么毛病,這是其中一個問題狰贯。

還有一個問題是軟鍵盤也搓,這個東西比較容易出BUG,我無法保證不同的軟鍵盤或者不同的版本不會出問題涵紊,我是感覺之后可能要做適配的問題傍妒。

暫時就這些,簡單封裝了一下摸柄,完善也只能在之后碰到問題再去完善颤练,然后之后我有時間寫個demo寫個文檔再放到gayhub


更新

項(xiàng)目地址

https://github.com/994866755/handsomeYe.SearchView


BUG修改

之前說有幾個傳資源時的BUG,我先在這寫出來驱负,gayhub的過后我改了再傳嗦玖。

1.背景資源的類型寫錯了
seaBackgroup = typedArray.getResourceId(R.styleable.kylin_search_style_search_backgroup,R.drawable.bg_search_default);

這里我之前用getInteger用錯了。

2.設(shè)置字體大小

我之前說怎么設(shè)置字體大小總是出問題跃脊,然后發(fā)現(xiàn)是setTextSize方法默認(rèn)是sp的宇挫,然后我用getDimension傳進(jìn)來的會轉(zhuǎn)成px,這樣就造成了px套到sp上匾乓,尺寸就錯了捞稿,應(yīng)該把類型再做一次轉(zhuǎn)換

edtSearch.setTextSize(TypedValue.COMPLEX_UNIT_PX,edt_size);

這個問題我之前也碰到過,只是忘了做筆記拼缝,所以不記得了娱局。詳細(xì)的原因可以看下這篇博客,講得很不錯咧七。
http://www.reibang.com/p/7f2941dbfb17

3.設(shè)置自適應(yīng)大小

我發(fā)現(xiàn)用getDimension如果設(shè)默認(rèn)大小的話就擴(kuò)展性太差了衰齐,所以想改成自適應(yīng),但是我又不知道這個方法要怎么設(shè)置默認(rèn)值為自適應(yīng)继阻,所以我就投機(jī)用正負(fù)值來判斷耻涛,默認(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ǔ)充

我想做個功能的補(bǔ)充是關(guān)于軟鍵盤的瘟檩,有很多時候抹缕,我們需要在軟鍵盤彈出的情況下,點(diǎn)擊空白處的話就隱藏軟鍵盤墨辛。
而這個操作我這邊不好一起封裝到searchView里面卓研,我覺得可以直接在頁面中用攔截事件來實(shí)現(xiàn)這功能。

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN){
            // 收軟鍵盤
            InputMethodManager imm =  (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
            if (imm.isActive()){
                imm.hideSoftInputFromWindow(searchView.getSearchEditText().getWindowToken(), 0); //隱藏軟鍵盤
            }
        }
        return super.dispatchTouchEvent(ev);
    }

這樣寫就能實(shí)現(xiàn)點(diǎn)擊頁面時隱藏軟鍵盤的操作,比如美團(tuán)的搜索就是點(diǎn)頁面能隱藏軟鍵盤奏赘。

但是這里有個問題寥闪,dispatchTouchEvent方法會頻繁的調(diào)用,只要一碰到這個頁面就會調(diào)用這個方法磨淌,而我在這里面創(chuàng)建InputMethodManager 的話是不是會一直創(chuàng)建對象疲憋。

我看Monitors來測試,其實(shí)我不是很會用Monitors梁只,然后用我單身20年的手速不斷搓屏幕缚柳,發(fā)現(xiàn)內(nèi)存一直在增長,所以我覺得InputMethodManager 在dispatchTouchEvent中創(chuàng)建不是很好敛纲,把它抽出去喂击,在全局中創(chuàng)建。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淤翔,一起剝皮案震驚了整個濱河市翰绊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旁壮,老刑警劉巖监嗜,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異抡谐,居然都是意外死亡裁奇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進(jìn)店門麦撵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刽肠,“玉大人,你說我怎么就攤上這事免胃∫粑澹” “怎么了?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵羔沙,是天一觀的道長躺涝。 經(jīng)常有香客問我,道長扼雏,這世上最難降的妖魔是什么坚嗜? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮诗充,結(jié)果婚禮上苍蔬,老公的妹妹穿的比我還像新娘。我一直安慰自己蝴蜓,他們只是感情好碟绑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般蜈敢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汽抚,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天抓狭,我揣著相機(jī)與錄音,去河邊找鬼造烁。 笑死否过,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惭蟋。 我是一名探鬼主播苗桂,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼告组!你這毒婦竟也來了煤伟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤木缝,失蹤者是張志新(化名)和其女友劉穎便锨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體我碟,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡放案,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了矫俺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吱殉。...
    茶點(diǎn)故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖厘托,靈堂內(nèi)的尸體忽然破棺而出友雳,到底是詐尸還是另有隱情,我是刑警寧澤催烘,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布沥阱,位于F島的核電站,受9級特大地震影響伊群,放射性物質(zhì)發(fā)生泄漏考杉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一舰始、第九天 我趴在偏房一處隱蔽的房頂上張望崇棠。 院中可真熱鬧,春花似錦丸卷、人聲如沸枕稀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萎坷。三九已至凹联,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哆档,已是汗流浹背蔽挠。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瓜浸,地道東北人澳淑。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像插佛,于是被迫代替她去往敵國和親杠巡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評論 2 350

推薦閱讀更多精彩內(nèi)容