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

最近在项目中有使用到搜索框的地方,由于其样式要求与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>

示例代码下载

时间: 2024-08-14 07:49:21

自定义EditText实现类iOS风格搜索框的相关文章

ios UISearchBar搜索框的基本使用

摘要: 小巧简洁的原生搜索框,漂亮而易用,如果我们的应用没有特殊需求,都可以使用它. iOS中UISearchBar(搜索框)使用总结 初始化:UISearchBar继承于UIView,我们可以像创建View那样创建searchBar     UISearchBar * bar = [[UISearchBar alloc]initWithFrame:CGRectMake(20, 100, 250, 40)];     [self.view addSubview:bar]; @property(n

iOS UISearchController 搜索框

#import <Foundation/Foundation.h> @interface Student : NSObject @property(strong,nonatomic) NSString *name; @property(strong,nonatomic) NSString *pic; @property(strong,nonatomic) NSString *tel; -(Student *)initWithDic:(NSDictionary *)dic; +(Student

IOS中搜索框UISearchBar及搜索方法的使用

搜索框可以用UISearchBar,并且可以设置代理UISearchBarDelegate. 1 -(void)addSearchBar{ 2 CGRect searchBarRect = CGRectMake(0, 0, self.view.frame.size.width, 44); 3 UISearchBar *searchBar = [[UISearchBar alloc]initWithFrame:searchBarRect]; 4 searchBar.placeholder = @"

IOS自定义搜索框

如果只是在某个地方添加一个自定义的搜索框,只需要添加以下代码: //创建搜索框对象 UITextField *searchBar=[[UITextField alloc] init]; searchBar.width=300; searchBar.height=30; searchBar.font=[UIFont systemFontofSize:15]; [email protected]"请输入搜索框"; searchBar.backgroud=[UIImage imageName

IOS第二天-新浪微博 - 添加搜索框,弹出下拉菜单 ,代理的使用 ,HWTabBar.h(自定义TabBar)

********HWDiscoverViewController.m(发现) - (void)viewDidLoad { [super viewDidLoad]; // 创建搜索框对象 HWSearchBar *searchBar = [HWSearchBar searchBar]; searchBar.width = 300; searchBar.height = 30; self.navigationItem.titleView = searchBar; //设置titleView 是搜索框

猫猫学iOS 之微博项目实战(5)微博自定义搜索框searchBar

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 用UITextField简单定义一个搜索框 二:调用: 调用的代码,很简单,直接init就可以,以后加功能自己添加就行了. - (void)viewDidLoad { [super viewDidLoad]; // 创建搜索框 NYSearchBar *searchBar = [[NYSearchBar alloc] initWithFrame:CGR

iOS - 完全自定义搜索框

此项目已上传GitHub,支持pods安装,Awsearch git地址: https://github.com/adampei/AwSearch git上有详细说明 效果图大概长这样 这个库都能做什么? 自定义搜索的icon, icon大小, icon位置, 搜索框背景色, 位置, 圆角等, 输入框字体大小, 颜色, placeholder字体大小, 颜色等, 右侧按钮字体大小, 背景色, 图片, 背景图等详细说明在GitHub,喜欢的话可以给个star谢谢 原文地址:https://www.

Android自定义View——自定义搜索框(SearchView)

概述 在Android开发中,当系统数据项比较多时,常常会在app添加搜索功能,方便用户能快速获得需要的数据.搜索栏对于我们并不陌生,在许多app都能见到它,比如豌豆荚 在某些情况下,我们希望我们的自动补全信息可以不只是纯文本,还可以像豌豆荚这样,能显示相应的图片和其他数据信息,因此Android给我们提供的AutoCompleteTextView往往就不够用,在大多情况下我们都需要自己去实现搜索框. 分析 根据上面这张图,简单分析一下自定义搜索框的结构与功能,有 1. 搜索界面大致由三部门组成

iOS新浪微博-1.1导航栏搜索框

导航栏搜索框是非常常用一个UI控件. 1.需求: 在“发现”页面,在顶部导航栏NavigationBar上添加一个搜索框 左端带有“放大镜”图标 2.思路 使用UISearchBar: 苹果系统自带,简单易用,但是样式死板不能定制(此处UISearchBar的背景色容易和导航栏的背景色混淆),不能修改宽高,而且在iOS6和iOS7上会产生不同的样式. 使用UITextField创建:继承或者扩展UITextField,设置背景图和左端图标 3.实现 创建一个继承UITextField的自定义类,