Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Android之搜索框的纯代码实现

在Android开发中,搜索框是很常用的,但是控件中没有现成的,需要自己封装。那要怎么封装呢?方式一:使用XML和JAVA代码相结合的方式。在XML中定义搜索的相关控件及布局,JAVA代码中进行相应事件的控制。方式二:对于浮动搜索框,可以使用SearchRecentSuggestionsProvider和searchable来实现。方式三:全部使用JAVA代码实现。前面两种,网上的代码已经很多,这里使用方式三来实现。先来看看效果图。功能:(1)、搜索框中有提示。(2)、输入内容后,提示自动清除,显示输入的内容,并在右边显示清空的图标。(3)、点击搜索按钮后,将搜索结果输出。依据这些功能,我们可以作如下分解。(1)、输入框、清空图标、搜索按钮在同一水平线上,所以可以需要使用LinearLayout的水平布局来实现。(2)、输入框可以使用EditText实现。(3)、输入框的提示内容使用EditText的hint实现。(4)、清空图标可以在EditText中绘制一个靠右的图标,并设定一定的感应区,以响应清空操作。(5)、搜索按钮使用Button添加图片实现,同时添加点击事件的响应。(6)、为了确保按钮外的空间被输入框占满,需要使用比重layout_weight=1来设置。通过分解,大致可以理出需要用到的控件和相应的逻辑,下面是实现的代码。SearchWidget.javapackage com.example.searchframetest;import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;public class SearchWidget extends LinearLayout { public final static int SEARCH_ID = 0x7ff20001;
 public final static String HINT_NAME = "hint"; private EditText _data_editText = null;
 private Button _search_button = null;
 private Context _context = null;
 private Drawable _clear_drawable = null;
 private Drawable _search_drawable = null;
 private Resources _res = null;
 private AttributeSet _attrs = null;
 private String _hint = ""; public SearchWidget(Context context, AttributeSet attrs) {
  super(context, attrs);
  if (context == null) {
   return;
  }
  _context = context;
  _attrs = attrs;
  Init();
 } private void Init() {
  InitParams();
  InitAttrs();
  InitControls();
  InitLayout();
  BindingEvents();
 } private void InitLayout() {
  this.setOrientation(LinearLayout.HORIZONTAL);
 } private void InitParams() {
  _res = _context.getResources();
  _clear_drawable = _res.getDrawable(R.drawable.clear);
  _search_drawable = _res.getDrawable(R.drawable.search); } private void InitAttrs() {
  for (int i = 0; i < _attrs.getAttributeCount(); i++) {
   if (_attrs.getAttributeName(i).equals(HINT_NAME)) {
    _hint = _attrs.getAttributeValue(i);
    break;
   }
  }
 } private void InitControls() {
  _data_editText = new EditText(_context);
  _search_button = new Button(_context);  LayoutParams dataLayoutParams = new LayoutParams(0,
    LayoutParams.FILL_PARENT, 1);
  _data_editText.setLayoutParams(dataLayoutParams);  _search_button.setCompoundDrawablesWithIntrinsicBounds(null, null,
    _search_drawable, null);  _search_button.setId(SEARCH_ID);  this.addView(_data_editText);
  this.addView(_search_button);
  // addHint();
  _data_editText.setHint(_hint);
  // _data_editText.setFocusable(false);
 } private void BindingEvents() {  _data_editText.addTextChangedListener(_search_TextChanged);
  _data_editText.setOnTouchListener(_search_OnTouch);
 } public void setSearchOnClickListener(OnClickListener onclickListener) {  _search_button.setOnClickListener(onclickListener);
 } public String getSearchData() {  return _data_editText.getText().toString();
 } private TextWatcher _search_TextChanged = new TextWatcher() {  @Override
  public void afterTextChanged(Editable s) {   Editable data = s;   if (TextUtils.isEmpty(data)) {
    _data_editText.setCompoundDrawablesWithIntrinsicBounds(null,
      null, null, null);
    return;
   }   _data_editText.setCompoundDrawablesWithIntrinsicBounds(null, null,
     _clear_drawable, null);  }  @Override
  public void beforeTextChanged(CharSequence s, int start, int count,
    int after) {  }  @Override
  public void onTextChanged(CharSequence s, int start, int before,
    int count) {
   // Log.e("TEST","3");
  }
 }; private OnTouchListener _search_OnTouch = new OnTouchListener() {  @Override
  public boolean onTouch(View v, MotionEvent event) {   switch (event.getAction()) {   case MotionEvent.ACTION_UP: {    int curX = (int) event.getX();
    String data = _data_editText.getText().toString();
    if (TextUtils.isEmpty(data)) {
     return false;
    }
    boolean isClearPosition = (curX > v.getWidth() - 88);    if (isClearPosition) {
     Clear(event);
     return true;
    }   }
   default: {
    break;
   }   }   return false;  }  private void Clear(MotionEvent event) {
   int cacheInputType = _data_editText.getInputType();// backup
   // the
   // input
   // type   _data_editText.setInputType(InputType.TYPE_NULL);// disable
   // soft
   // input   _data_editText.onTouchEvent(event);// call native handler   _data_editText.setInputType(cacheInputType);// restore input
   // type
   // addHint();
   _data_editText.setText("");
  } };}注:
(1)、给_search_button定义一个id,以便响应点击事件。此处的SearchWidget.SEARCH_ID在实际中可能会与xml中定义的ID值有冲突,可以根据实际的情况作相应的调整。
(2)、定义HINT_NAME,以便在xml中调用搜索框控件时使用hint属性。
(3)、InitAttrs方法中,过虑出hint属性。
(4)、_data_editText.setHint(_hint)中设置输入框的内容提示。
(5)、BindingEvents添加_data_editText的文件改变和触摸事件的监听。
(6)、增加getSearchData函数供外部调用。
(7)、增加setSearchOnClickListener供外部设置搜索按钮的监听事件。
(8)、setCompoundDrawablesWithIntrinsicBounds动态修改输入框右侧的图标。
(9)、在_data_editText的layoutParams的布局参数设置中,将其宽度设置为0,高度设置为充满父容器,比重设置为1,以确保充满搜索按钮外的空间。调用代码:package com.example.searchframetest;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;public class MainActivity extends Activity { private SearchWidget _search_widget = null;
 private TextView _result_text=null;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  Init();
 }
 
 private void Init() {
  FetchUIControls();
  BindingEvents(); 
 }
 
 private void FetchUIControls() {
  _search_widget = (SearchWidget) findViewById(R.id.searchWidget);
  _result_text = (TextView) findViewById(R.id.result);
 }
 
 private void BindingEvents() {  _search_widget.setSearchOnClickListener(_clickListener); } private OnClickListener _clickListener = new OnClickListener() {  @Override
  public void onClick(View v) {
   switch (v.getId()) {
   case SearchWidget.SEARCH_ID: {
    Search();
    break;
   }
   default: {
    break;
   }
   }  }
 }; protected void Search() {
  String data=_search_widget.getSearchData();
  _result_text.setText(data);
 }}注:(1)、使用常用的获取控件的方式来获取SearchWidget。(2)、为搜索按钮设置监听事件时,使用SearchWidget.SEARCH_ID来区别点击事件的响应ID。Android 4.4.4 发布下载 http://www.linuxidc.com/Linux/2014-06/103467.htm最简单的Ubuntu Touch & Android 双系统安装方式 http://www.linuxidc.com/Linux/2014-01/94881.htm在Nexus上实现Ubuntu和Android 4.4.2 双启动 http://www.linuxidc.com/Linux/2014-05/101849.htmUbuntu 14.04 配置 Android SDK 开发环境 http://www.linuxidc.com/Linux/2014-05/101039.htm64位Ubuntu 11.10下Android开发环境的搭建(JDK+Eclipse+ADT+Android SDK详细) http://www.linuxidc.com/Linux/2013-06/85303.htmUbuntu 14.04 x64配置Android 4.4 kitkat编译环境的方法 http://www.linuxidc.com/Linux/2014-04/101148.htmUbuntu 12.10 x64 安装 Android SDK http://www.linuxidc.com/Linux/2013-03/82005.htm更多Android相关信息见Android 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=11本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-11/109069.htm