搜索图标居中的搜索框~iOS风格搜索框

来源:互联网 发布:fullscreen软件 编辑:程序博客网 时间:2024/05/17 09:26

原文:http://www.bkjia.com/Androidjc/1012884.html


自定义EditText实现类iOS风格搜索框,edittextios


最近在项目中有使用到搜索框的地方,由于其样式要求与iOS的UISearchBar的风格一致。默认情况下,搜索图标和文字是居中的,在获取焦点的时候,图标和文字左移。但是在Android是并没有这样的控件(可能见识少,并不知道有)。通常情况下我们使用组合控件,使用ReleativeLayout或者FrameLayout来实现。此篇并不是使用上述方法实现,其核心是继承系统EditText,重写onDraw方法,来改变默认的左上右下的drawable,实现平移到中间位置。这里暂时只实现了drawableLeft的情况,后续将对其进行更新。先来看看实现效果图: 
 


直接来看代码实现

package com.jinlin.custom.iconcenterview;import android.view.View;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends BaseActivity{    private EditText et_search;    private IconCenterEditText icet_search;    @Override    public void iniView() {        setContentView(R.layout.activity_main);        et_search = (EditText) findViewById(R.id.et_search);        icet_search = (IconCenterEditText) findViewById(R.id.icet_search);        // 实现TextWatcher监听即可        icet_search.setOnSearchClickListener(new IconCenterEditText.OnSearchClickListener() {            @Override            public void onSearchClick(View view) {                Toast.makeText(MainActivity.this, "i'm going to seach", Toast.LENGTH_SHORT).show();            }        });    }}
这是主Activity的代码,其继承自BaseActivity基类,BaseActivity的实现详细见上篇博文Android点击空白区域,隐藏输入法软键盘只是在isShouldHideKeyboard(View v, MotionEvent event)方法内部增加一行v.clearFocus();代码进行去除焦点处理,其他均一致。
private boolean isShouldHideKeyboard(View v, MotionEvent event) {        if (v != null && (v instanceof EditText)) {            int[] l = {0, 0};            v.getLocationInWindow(l);            int left = l[0],                    top = l[1],                    bottom = top + v.getHeight(),                    right = left + v.getWidth();            if (event.getX() > left && event.getX() < right                    && event.getY() > top && event.getY() < bottom) {                // 点击EditText的事件,忽略它。                return false;            } else {                v.clearFocus();                return true;            }        }        // 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上,和用户用轨迹球选择其他的焦点        return false;    }

接下来是自定义View的代码实现


IconCenterEditText.java

package com.jinlin.custom.iconcenterview;import android.content.Context;import android.graphics.Canvas;import android.graphics.drawable.Drawable;import android.text.TextUtils;import android.util.AttributeSet;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.view.inputmethod.InputMethodManager;import android.widget.EditText;/** * Created by J!nl!n on 2015/1/26. */public class IconCenterEditText extends EditText implements View.OnFocusChangeListener, View.OnKeyListener {    private static final String TAG = IconCenterEditText.class.getSimpleName();    /**     * 是否是默认图标再左边的样式     */    private boolean isLeft = false;    /**     * 是否点击软键盘搜索     */    private boolean pressSearch = false;    /**     * 软键盘搜索键监听     */    private OnSearchClickListener listener;    public void setOnSearchClickListener(OnSearchClickListener listener) {        this.listener = listener;    }    public IconCenterEditText(Context context) {        this(context, null);        init();    }    public IconCenterEditText(Context context, AttributeSet attrs) {        this(context, attrs, android.R.attr.editTextStyle);        init();    }    public IconCenterEditText(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private void init() {        setOnFocusChangeListener(this);        setOnKeyListener(this);    }    @Override    protected void onDraw(Canvas canvas) {        if (isLeft) { // 如果是默认样式,则直接绘制            super.onDraw(canvas);        } else { // 如果不是默认样式,需要将图标绘制在中间            Drawable[] drawables = getCompoundDrawables();            if (drawables != null) {                Drawable drawableLeft = drawables[0];                if (drawableLeft != null) {                    float textWidth = getPaint().measureText(getHint().toString());                    int drawablePadding = getCompoundDrawablePadding();                    int drawableWidth = drawableLeft.getIntrinsicWidth();                    float bodyWidth = textWidth + drawableWidth + drawablePadding;                    canvas.translate((getWidth() - bodyWidth - getPaddingLeft() - getPaddingRight()) / 2, 0);                }            }            super.onDraw(canvas);        }    }    @Override    public void onFocusChange(View v, boolean hasFocus) {        Log.d(TAG, "onFocusChange execute");        // 恢复EditText默认的样式        if (!pressSearch && TextUtils.isEmpty(getText().toString())) {            isLeft = hasFocus;        }    }    @Override    public boolean onKey(View v, int keyCode, KeyEvent event) {        pressSearch = (keyCode == KeyEvent.KEYCODE_ENTER);        if (pressSearch && listener != null) {            /*隐藏软键盘*/            InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);            if (imm.isActive()) {                imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);            }            listener.onSearchClick(v);        }        return false;    }    public interface OnSearchClickListener {        void onSearchClick(View view);    }}

此View重写onDraw(Canvas canvas)方法,并实现OnFocusChangeListener, OnKeyListener监听接口,在onFocusChange(View v, boolean hasFocus)方法判断是否需要恢复样式,然后在onDraw(Canvas canvas)进行重绘,实现焦点失去和获取时,平移图标和文字。同时还会判断软键盘搜索键的操作进行处理。其核心代码也就是一下这一小段:

Drawable[] drawables = getCompoundDrawables();if (drawables != null) {     Drawable drawableLeft = drawables[0];     if (drawableLeft != null) {         float textWidth = getPaint().measureText(getHint().toString());         int drawablePadding = getCompoundDrawablePadding();         int drawableWidth = drawableLeft.getIntrinsicWidth();         float bodyWidth = textWidth + drawableWidth + drawablePadding;         canvas.translate((getWidth() - bodyWidth - getPaddingLeft() - getPaddingRight()) / 2, 0);      }}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:focusableInTouchMode="true"    android:orientation="vertical"    android:padding="@dimen/activity_vertical_margin"    tools:context=".MainActivity">    <TextView        style="@style/StyleTextView"        android:text="默认样式" />    <EditText        android:id="@+id/et_search"        style="@style/StyleEditText" />    <TextView        style="@style/StyleTextView"        android:text="居中样式" />    <com.jinlin.custom.iconcenterview.IconCenterEditText        android:id="@+id/icet_search"        style="@style/StyleEditText" /></LinearLayout>

bg_search_bar.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="@android:color/white" />    <stroke        android:width="1px"        android:color="@android:color/darker_gray" />    <corners android:radius="3dp" /></shape>

styles.xml

<resources>    <!-- Base application theme. -->    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->    </style>    <style name="StyleEditText">        <item name="android:layout_width">match_parent</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:background">@drawable/bg_search_bar</item>        <item name="android:drawablePadding">5dp</item>        <item name="android:drawableStart">@mipmap/icon_search</item>        <item name="android:gravity">center_vertical</item>        <item name="android:imeOptions">actionSearch</item>        <item name="android:padding">5dp</item>        <item name="android:singleLine">true</item>        <item name="android:textColorHint">@color/gray_white</item>        <item name="android:textSize">16sp</item>        <item name="android:hint">搜索</item>    </style>    <style name="StyleTextView">        <item name="android:layout_width">match_parent</item>        <item name="android:layout_height">40dp</item>        <item name="android:gravity">center</item>        <item name="android:textSize">20sp</item>    </style></resources>

colors.xml

    <?xml version="1.0" encoding="utf-8"?>    <resources>        <color name="gray_white">#ffcccccc</color>    </resources>

0 0
原创粉丝点击