zoukankan      html  css  js  c++  java
  • 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.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

  • 相关阅读:
    Oracle数据导出到MySql
    ORA04031 shared_pool 不能分配足够内存或磁盘碎片
    IDEA那些好用的插件
    MySQL基础篇增删改查
    SpringBoot项目部署在阿里云
    三、Mybatis相应API
    chrome的书签备份
    redis踩坑
    四、Mybatis的Dao层实现
    MySQL基础篇函数
  • 原文地址:https://www.cnblogs.com/sparkleDai/p/7605011.html
Copyright © 2011-2022 走看看