在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