歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android之搜索框的純代碼實現

Android之搜索框的純代碼實現

日期:2017/3/1 9:37:42   编辑:Linux編程

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

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.htm

Ubuntu 14.04 配置 Android SDK 開發環境 http://www.linuxidc.com/Linux/2014-05/101039.htm

64位Ubuntu 11.10下Android開發環境的搭建(JDK+Eclipse+ADT+Android SDK詳細) http://www.linuxidc.com/Linux/2013-06/85303.htm

Ubuntu 14.04 x64配置Android 4.4 kitkat編譯環境的方法 http://www.linuxidc.com/Linux/2014-04/101148.htm

Ubuntu 12.10 x64 安裝 Android SDK http://www.linuxidc.com/Linux/2013-03/82005.htm

更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11

Copyright © Linux教程網 All Rights Reserved