Android自定义View实现搜索框(SearchView)功能

概述

在Android开发中,当系统数据项比较多时,常常会在app添加搜索功能,方便用户能快速获得需要的数据。搜索栏对于我们并不陌生,在许多app都能见到它,比如豌豆荚

在某些情况下,我们希望我们的自动补全信息可以不只是纯文本,还可以像豌豆荚这样,能显示相应的图片和其他数据信息,因此Android给我们提供的AutoCompleteTextView往往就不够用,在大多情况下我们都需要自己去实现搜索框。

分析

根据上面这张图,简单分析一下自定义搜索框的结构与功能,有
1. 搜索界面大致由三部门组成,如图:输入框+(自动补全)提示框+结果列表。
2. 提示框的数据与输入框输入的文本是实时联动的,而结果列表只有在每次进行搜索操作时才会更新数据

3. 输入框的UI应是动态的,即UI随着输入的文本的改变而改变,如:在未输入文本时,清除按钮应该是隐藏的;只有当框中有文本时才会显示。
4. 软键盘也应该是动态的,如完成搜索时应自动隐藏。
5. 选择提示框的选项会自动补全输入框,且自动进行搜索
6. (external)有热门搜索推荐/记录搜索记录的功能——热门搜索推荐列表只在刚要进行搜索的时候弹出,即未输入文本时,可供用户选择。

根据上面的分析,我们认为一个搜索框应该包含输入框和提示框两个部分。搜索框可以设置一个回调监听接口,当需要进行搜索操作时,调用监听者的search()方法,从而实现具体的搜索操作以及结果列表的数据联动。

演示Demo

注意:

1. 这里,博主图方便没有模拟太多数据,而且提示框和热搜列表也都只是使用String类型的数据,各位看官们可以根据自身需要去设置item_layout和相应的adapter。
2. 由于个人习惯,博主在这个demo中使用了通用适配器,所以生成和设置adapter的代码比较简略,看官们可以根据传统的ViewHolder模式打造自己的adapter。或者学习一下通用适配器的打造。可以参考这里(鸿神博客Again)学习一下通用适配器的打造,在我的源码里面也有对应的源码。

实现

好了,说了那么多,开始来看代码吧

先看SearchView的布局文件 search_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:background="#eee"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="vertical"> 

  <LinearLayout
    android:background="#eb4f38"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"> 

    <FrameLayout 

      android:layout_weight="1"
      android:layout_width="0dp"
      android:layout_height="wrap_content"> 

      <EditText
        android:id="@+id/search_et_input"
        android:layout_gravity="center_vertical"
        android:layout_margin="10dp"
        android:drawableLeft="@drawable/search_icon"
        android:drawablePadding="5dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/search_edittext_shape"
        android:textSize="16sp"
        android:imeOptions="actionSearch"
        android:inputType="text"
        android:hint="请输入关键字"/> 

      <ImageView
        android:visibility="gone"
        android:layout_marginRight="20dp"
        android:src="@drawable/iv_delete_bg"
        android:id="@+id/search_iv_delete"
        android:layout_gravity="right|center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    </FrameLayout> 

    <Button
      android:id="@+id/search_btn_back"
      android:layout_marginRight="10dp"
      android:layout_marginTop="10dp"
      android:layout_marginBottom="10dp"
      android:layout_gravity="center_vertical"
      android:background="@drawable/btn_search_bg"
      android:layout_width="@dimen/btn_width"
      android:layout_height="@dimen/btn_height"
      android:text="返回"
      android:textColor="@color/color_white"/>
  </LinearLayout> 

  <ListView
    android:visibility="gone"
    android:id="@+id/search_lv_tips"
    android:background="@drawable/lv_search_tips_bg"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:layout_marginBottom="10dp"
    android:layout_width="match_parent"
    android:layout_height="200dp">
  </ListView>
</LinearLayout> 

注意:demo中颜色什么的都直接用的rgb 值去设置,在实际开发时,需要把它们都统一管理到values目录下 。

比较简单,需要注意的是EditText的这个属性

android:imeOptions="actionSearch"
就是把Enter键设置为Search键,并把点击Enter键的动作设为actionSearch,这样既可在代码中监听何时按下search键

没什么说的,bg属性可以直接看看源码。接下来看模拟的bean类,这里直接就叫Bean.java

public class Bean { 

  private int iconId;
  private String title;
  private String content;
  private String comments; 

  public Bean(int iconId, String title, String content, String comments) {
    this.iconId = iconId;
    this.title = title;
    this.content = content;
    this.comments = comments;
  } 

  public int getIconId() {
    return iconId;
  } 

  public void setIconId(int iconId) {
    this.iconId = iconId;
  } 

  public String getTitle() {
    return title;
  } 

  public void setTitle(String title) {
    this.title = title;
  } 

  public String getContent() {
    return content;
  } 

  public void setContent(String content) {
    this.content = content;
  } 

  public String getComments() {
    return comments;
  } 

  public void setComments(String comments) {
    this.comments = comments;
  }
}

接着看主角SearchView.java

public class SearchView extends LinearLayout implements View.OnClickListener { 

  /**
   * 输入框
   */
  private EditText etInput; 

  /**
   * 删除键
   */
  private ImageView ivDelete; 

  /**
   * 返回按钮
   */
  private Button btnBack; 

  /**
   * 上下文对象
   */
  private Context mContext; 

  /**
   * 弹出列表
   */
  private ListView lvTips; 

  /**
   * 提示adapter (推荐adapter)
   */
  private ArrayAdapter<String> mHintAdapter; 

  /**
   * 自动补全adapter 只显示名字
   */
  private ArrayAdapter<String> mAutoCompleteAdapter; 

  /**
   * 搜索回调接口
   */
  private SearchViewListener mListener; 

  /**
   * 设置搜索回调接口
   *
   * @param listener 监听者
   */
  public void setSearchViewListener(SearchViewListener listener) {
    mListener = listener;
  } 

  public SearchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    mContext = context;
    LayoutInflater.from(context).inflate(R.layout.search_layout, this);
    initViews();
  } 

  private void initViews() {
    etInput = (EditText) findViewById(R.id.search_et_input);
    ivDelete = (ImageView) findViewById(R.id.search_iv_delete);
    btnBack = (Button) findViewById(R.id.search_btn_back);
    lvTips = (ListView) findViewById(R.id.search_lv_tips); 

    lvTips.setOnItemClickListener(new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        //set edit text
        String text = lvTips.getAdapter().getItem(i).toString();
        etInput.setText(text);
        etInput.setSelection(text.length());
        //hint list view gone and result list view show
        lvTips.setVisibility(View.GONE);
        notifyStartSearching(text);
      }
    }); 

    ivDelete.setOnClickListener(this);
    btnBack.setOnClickListener(this); 

    etInput.addTextChangedListener(new EditChangedListener());
    etInput.setOnClickListener(this);
    etInput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
      @Override
      public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
        if (actionId == EditorInfo.IME_ACTION_SEARCH) {
          lvTips.setVisibility(GONE);
          notifyStartSearching(etInput.getText().toString());
        }
        return true;
      }
    });
  } 

  /**
   * 通知监听者 进行搜索操作
   * @param text
   */
  private void notifyStartSearching(String text){
    if (mListener != null) {
      mListener.onSearch(etInput.getText().toString());
    }
    //隐藏软键盘
    InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
  } 

  /**
   * 设置热搜版提示 adapter
   */
  public void setTipsHintAdapter(ArrayAdapter<String> adapter) {
    this.mHintAdapter = adapter;
    if (lvTips.getAdapter() == null) {
      lvTips.setAdapter(mHintAdapter);
    }
  } 

  /**
   * 设置自动补全adapter
   */
  public void setAutoCompleteAdapter(ArrayAdapter<String> adapter) {
    this.mAutoCompleteAdapter = adapter;
  } 

  private class EditChangedListener implements TextWatcher {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { 

    } 

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
      if (!"".equals(charSequence.toString())) {
        ivDelete.setVisibility(VISIBLE);
        lvTips.setVisibility(VISIBLE);
        if (mAutoCompleteAdapter != null && lvTips.getAdapter() != mAutoCompleteAdapter) {
          lvTips.setAdapter(mAutoCompleteAdapter);
        }
        //更新autoComplete数据
        if (mListener != null) {
          mListener.onRefreshAutoComplete(charSequence + "");
        }
      } else {
        ivDelete.setVisibility(GONE);
        if (mHintAdapter != null) {
          lvTips.setAdapter(mHintAdapter);
        }
        lvTips.setVisibility(GONE);
      } 

    } 

    @Override
    public void afterTextChanged(Editable editable) {
    }
  } 

  @Override
  public void onClick(View view) {
    switch (view.getId()) {
      case R.id.search_et_input:
        lvTips.setVisibility(VISIBLE);
        break;
      case R.id.search_iv_delete:
        etInput.setText("");
        ivDelete.setVisibility(GONE);
        break;
      case R.id.search_btn_back:
        ((Activity) mContext).finish();
        break;
    }
  } 

  /**
   * search view回调方法
   */
  public interface SearchViewListener { 

    /**
     * 更新自动补全内容
     *
     * @param text 传入补全后的文本
     */
    void onRefreshAutoComplete(String text); 

    /**
     * 开始搜索
     *
     * @param text 传入输入框的文本
     */
    void onSearch(String text); 

//    /**
//     * 提示列表项点击时回调方法 (提示/自动补全)
//     */
//    void onTipsItemClick(String text);
  } 

}

搜索框主要包含两个结构:输入栏+弹出框(自动补全或热门搜素推荐)。

代码不多,实现很简单,主要是需要给EditText(输入框)设置点击监听和文本改变监听,有以下几点:
1. 当输入框没有文本时,点击输入框,显示热门搜索列表框。
2. 当输入框有文本时,点击输入框,应显示自动补全列表框。
3. 当输入框的文本发生改变时,需要更新自动补全列表框的数据。由于这些数据应该是在外部(调用者)中获得的,所以可以通过接口回调的形式,当需要更新时,通知监听者更新数据。
4. 当输入框的文本从空”“变换到非空时,即有字符时,界面应显示自动补全框,隐藏热门搜索框。
5. 当输入框的文本从非空变为空时,系统应隐藏自动补全框和热门搜索框。
6. 需要监听是否按下search键(enter),按下时通知监听者执行search操作

结合以上6点和在上文分析过的内容,就能很轻松地实现该view。

之后来看看搜索界面的布局文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"
       tools:context=".MainActivity"
       android:orientation="vertical"> 

  <com.yetwish.customsearchdemo.activity.widge.SearchView
    android:id="@+id/main_search_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
  </com.yetwish.customsearchdemo.activity.widge.SearchView> 

  <ListView
    android:visibility="gone"
    android:id="@+id/main_lv_search_results"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"> 

  </ListView>
</LinearLayout>

就是一个SearchView加上一个结果列表,这些我们在上文都分析过了,所以也没什么好说的。布局可根据自身需求去自定义。

最后就是搜索界面调用该view  MainActiviy.java

public class MainActivity extends Activity implements SearchView.SearchViewListener { 

  /**
   * 搜索结果列表view
   */
  private ListView lvResults; 

  /**
   * 搜索view
   */
  private SearchView searchView; 

  /**
   * 热搜框列表adapter
   */
  private ArrayAdapter<String> hintAdapter; 

  /**
   * 自动补全列表adapter
   */
  private ArrayAdapter<String> autoCompleteAdapter; 

  /**
   * 搜索结果列表adapter
   */
  private SearchAdapter resultAdapter; 

  /**
   * 数据库数据,总数据
   */
  private List<Bean> dbData; 

  /**
   * 热搜版数据
   */
  private List<String> hintData; 

  /**
   * 搜索过程中自动补全数据
   */
  private List<String> autoCompleteData; 

  /**
   * 搜索结果的数据
   */
  private List<Bean> resultData; 

  /**
   * 默认提示框显示项的个数
   */
  private static int DEFAULT_HINT_SIZE = 4; 

  /**
   * 提示框显示项的个数
   */
  private static int hintSize = DEFAULT_HINT_SIZE; 

  /**
   * 设置提示框显示项的个数
   *
   * @param hintSize 提示框显示个数
   */
  public static void setHintSize(int hintSize) {
    MainActivity.hintSize = hintSize;
  } 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    initData();
    initViews();
  } 

  /**
   * 初始化视图
   */
  private void initViews() {
    lvResults = (ListView) findViewById(R.id.main_lv_search_results);
    searchView = (SearchView) findViewById(R.id.main_search_layout);
    //设置监听
    searchView.setSearchViewListener(this);
    //设置adapter
    searchView.setTipsHintAdapter(hintAdapter);
    searchView.setAutoCompleteAdapter(autoCompleteAdapter); 

    lvResults.setOnItemClickListener(new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
        Toast.makeText(MainActivity.this, position + "", Toast.LENGTH_SHORT).show();
      }
    });
  } 

  /**
   * 初始化数据
   */
  private void initData() {
    //从数据库获取数据
    getDbData();
    //初始化热搜版数据
    getHintData();
    //初始化自动补全数据
    getAutoCompleteData(null);
    //初始化搜索结果数据
    getResultData(null);
  } 

  /**
   * 获取db 数据
   */
  private void getDbData() {
    int size = 100;
    dbData = new ArrayList<>(size);
    for (int i = 0; i < size; i++) {
      dbData.add(new Bean(R.drawable.icon, "android开发必备技能" + (i + 1), "Android自定义view——自定义搜索view", i * 20 + 2 + ""));
    }
  } 

  /**
   * 获取热搜版data 和adapter
   */
  private void getHintData() {
    hintData = new ArrayList<>(hintSize);
    for (int i = 1; i <= hintSize; i++) {
      hintData.add("热搜版" + i + ":Android自定义View");
    }
    hintAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, hintData);
  } 

  /**
   * 获取自动补全data 和adapter
   */
  private void getAutoCompleteData(String text) {
    if (autoCompleteData == null) {
      //初始化
      autoCompleteData = new ArrayList<>(hintSize);
    } else {
      // 根据text 获取auto data
      autoCompleteData.clear();
      for (int i = 0, count = 0; i < dbData.size()
          && count < hintSize; i++) {
        if (dbData.get(i).getTitle().contains(text.trim())) {
          autoCompleteData.add(dbData.get(i).getTitle());
          count++;
        }
      }
    }
    if (autoCompleteAdapter == null) {
      autoCompleteAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, autoCompleteData);
    } else {
      autoCompleteAdapter.notifyDataSetChanged();
    }
  } 

  /**
   * 获取搜索结果data和adapter
   */
  private void getResultData(String text) {
    if (resultData == null) {
      // 初始化
      resultData = new ArrayList<>();
    } else {
      resultData.clear();
      for (int i = 0; i < dbData.size(); i++) {
        if (dbData.get(i).getTitle().contains(text.trim())) {
          resultData.add(dbData.get(i));
        }
      }
    }
    if (resultAdapter == null) {
      resultAdapter = new SearchAdapter(this, resultData, R.layout.item_bean_list);
    } else {
      resultAdapter.notifyDataSetChanged();
    }
  } 

  /**
   * 当搜索框 文本改变时 触发的回调 ,更新自动补全数据
   * @param text
   */
  @Override
  public void onRefreshAutoComplete(String text) {
    //更新数据
    getAutoCompleteData(text);
  } 

  /**
   * 点击搜索键时edit text触发的回调
   *
   * @param text
   */
  @Override
  public void onSearch(String text) {
    //更新result数据
    getResultData(text);
    lvResults.setVisibility(View.VISIBLE);
    //第一次获取结果 还未配置适配器
    if (lvResults.getAdapter() == null) {
      //获取搜索数据 设置适配器
      lvResults.setAdapter(resultAdapter);
    } else {
      //更新搜索数据
      resultAdapter.notifyDataSetChanged();
    }
    Toast.makeText(this, "完成搜素", Toast.LENGTH_SHORT).show();
  } 

}

使用SearchView比较简单,只要给SearchView设置onSearchViewListener监听接口,实现对应的方法,并给SearchView传入热搜版和自动补全的adapter既可。

这里使用的匹配算法比较简单,也没有考虑多个搜索词的情况,(这些之后都可以再完善),主要实现就是在总数据中匹配每个Bean的Title是否包含搜索词,包含则表示该数据匹配,否则不匹配。然后将所有匹配的Bean显示到结果列表中。

考虑到实际开发中,数据量十分庞大,可以只把结果集的一部分(如前10个)显示出来,上拉到底的时候再加载之后的记录,也就是可以加入上拉加载的机制,使app性能更优化。

自动补全匹配也是采用相同的算法。算法都比较简单,当然也可以弄得复杂点,比如根据“ ”(空格)去分割输入文本,再逐个考虑单个搜索词的匹配项,把匹配次数从多到少排列出结果集等等。这里不细说。

这里有一个问题是进入该搜索界面时需要加载所有的数据项到内存,当数据项很多时,是否会占用大量的内存?如果是应该如何避免?是采用只加载一部分数据的形式,还是直接使用搜索词到数据库中查询更优?还请各位看官大神们给出宝贵的意见~

好了,自定义搜索框到这就打造完成啦,是不是感觉简单过头了。

各位看官如果有任何问题可评论或者发邮件跟我联系yetwish@gmail.com

囧~忘记贴代码了,代码放在github上,各位看官直接download即可
链接:https://github.com/yetwish/CustomSearchView

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android搜索框(SearchView)的功能和用法详解

    SearchView是搜索框组件,它可以让用户在文本框里输入文字,通过监听器取得用户的输入,当用户点击搜索时,监听器执行实际的搜索. 1.SearchView组件的常用方法如下: ①setIconifiedByDefault(boolean iconified) ===> 设置搜索框默认是否自动缩小为图标. ②setOnQueryTextListener(SearchView,OnQueryTextListener listener) ===> 为搜索框设置监听器 ③setSubmitButt

  • android搜索框上下滑动变色效果

    搜索框上下滑动变透明度是现在APP中很常见的效果,先看看效果: 首先来看下布局骨架: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height

  • Android实现实时搜索框功能

    AutoCompleteTextView,自动完成文本框. 用于实现允许用户输入一定字符后,显示一个下拉菜单,供用户从中选择,当用户选择某个选项后,按用户选择自动填写该文本框. 该组件继承EditText,所以它支持EditText组件提供的属性,同时,该组件该支持如下功能. activity_main.xml <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.Co

  • Android搜索框组件SearchView的基本使用方法

    SearchView是android系统中内置的一个搜索框组件,可以很方便在添加在用户界面之上,但是也带来了一些问题,那就是searchview的UI是固定的,定制起来会很麻烦,如果对SearchView的要求比较高,完全可以采用button和EditText自己实现.这里先简单的说说SearchView的使用: main.xml: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" x

  • Android SearchView搜索框组件的使用方法

    SearchView是搜索框组件,它可以让用户在文本框里输入文字,通过监听器取得用户的输入,当用户点击搜索时,监听器执行实际的搜索. 本文就为大家分享了SearchView搜索框组件的使用方法,供大家参考,具体内容如下 效果: 代码SearchActivity.java package com.jialianjia.bzw.activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.

  • Android编程自定义搜索框实现方法【附demo源码下载】

    本文实例讲述了Android编程自定义搜索框实现方法.分享给大家供大家参考,具体如下: 先来看效果图吧~ 分析:这只是模拟了一个静态数据的删除与显示 用EditText+PopupWindow+listView实现的 步骤: 1.先写出搜索框来-activity_mian布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://sc

  • Android搜索框SearchView属性和用法详解

    SearchView简介 SearchView是Android原生的搜索框控件,它提供了一个用户界面,用于用户搜索查询. SearchView默认是展示一个search的icon,点击icon展开搜索框,如果你想让搜索框默认就展开,可以通过setIconifiedByDefault(false);实现. SearchView属性 SearchView使用 xml中定义SearchView: <?xml version="1.0" encoding="utf-8"

  • Android中如何实现清空搜索框的文字

    需求:项目中的有关搜索的地方,加上清空文字的功能,目的是为了增加用户体验,使用户删除文本更加快捷 解决过程:开始的时候感觉这个东西不太好实现,主要就是布局的问题,可能是开始顾虑的太多了,再加上当时产品催的不太紧,而且这个功能也不是必须实现的.但是今天不一样了,这个是老大让加上的,说别的很多应用中都有这个功能,没办法那就加上呗,试着去使用了相对布局去实现,把一个删除按键放在编辑框的右上方,当文字的时候就把删除按键给显示出来,当编辑框为空的时候就把删除按键给隐藏掉.布局代码 <?xml versio

  • Android顶部(toolbar)搜索框实现的实例详解

    Android顶部(toolbar)搜索框实现的实例详解 本文介绍两种SearchView的使用情况,一种是输入框和搜索结果不在一个activity中,另一种是在一个activity中. 首先编写toolbar的布局文件 toolbar中图标在menu文件下定义一个布局文件实现 示例代码: <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.

  • Android EditText搜索框实现图标居中

    类似这样EditText 搜索框,hiht 提示有一个icon并且text内容. 重写EditText : package mobi.truekey.weapp2.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.dr

  • Android搜索框通用版

    之前项目总会遇到很多搜索框类的功能,虽然不是很复杂,不过每次都要去自己处理数据,并且去处理搜索框的变化,写起来也比较麻烦,今天来做一个比较简单的通用搜索栏. 先看下效果图: 没什么特别的,只是今天要做的就是简单的把搜索框的内容封装一下. 一.分析功能 先考虑一下,搜索框一般都是由一个搜索图标(一般都是一个放大镜),一个输入框和一个清除按钮组成.然后会通过监听输入框的变化去处理清除按钮的显示和隐藏并且去过滤相关的数据.最后去刷新适配器,显示过滤后的数据.基本上搜索框的功能都大同小异. 有了上边的分

  • Android 改变图标原有颜色和搜索框的实例代码

    图标改变颜色:Drawable的变色,让Android也能有iOS那么方便的图片色调转换,就像同一个图标,但是有多个地方使用,并且颜色不一样,就可以用这个方法了. 搜索框: 一般是EditText实现,本文 实现 TextView图片和文字居中,键盘搜索. 来看看效果图: 图标改变颜色:第一个界面的左边(二维码)和右边(更多)两个实现,我放进去的图片是黑色的,显示出来是白色的. 搜索框:第一个界面的图片和文字居中,还可以设置间距,第二个见面搜索设置键盘搜索按钮,点击搜索监听事件,清除内容的图标.

随机推荐