博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android之搜索框的纯代码实现
阅读量:5943 次
发布时间:2019-06-19

本文共 6409 字,大约阅读时间需要 21 分钟。

在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.java

package 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。

转载请注明出处http://blog.csdn.net/xxdddail/article/details/23194573

转载于:https://www.cnblogs.com/sparkleDai/p/7605011.html

你可能感兴趣的文章
开发安全的 API 所需要核对的清单
查看>>
Mycat源码中的单例模式
查看>>
WPF Dispatcher介绍
查看>>
fiddler展示serverIP方法
查看>>
C语言中的随意跳转
查看>>
WPF中如何将ListViewItem双击事件绑定到Command
查看>>
《聚散两依依》
查看>>
小tips:你不知道的 npm init
查看>>
Mac笔记本中是用Idea开发工具在Java项目中调用python脚本遇到的环境变量问题解决...
查看>>
Jmeter也能IP欺骗!
查看>>
Rust 阴阳谜题,及纯基于代码的分析与化简
查看>>
ASP.NET Core的身份认证框架IdentityServer4(4)- 支持的规范
查看>>
(原創) array可以使用reference方式傳進function嗎? (C/C++)
查看>>
170多个Ionic Framework学习资源(转载)
查看>>
Azure:不能把同一个certificate同时用于Azure Management和RDP
查看>>
Directx11教程(15) D3D11管线(4)
查看>>
Microsoft Excel软件打开文件出现文件的格式与文件扩展名指定格式不一致?
查看>>
ios ble 参考
查看>>
linux中注册系统服务—service命令的原理通俗
查看>>
基于托管C++的增删改查及异步回调小程序
查看>>