package com.jiuqi.ui.widget; import java.io.Serializable; import com.jqyd.uilib.R; import android.content.Context; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnKeyListener; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.ViewStub; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; /** * <p>搜索条控件</p> * <p> * 风格可以混合使用,想要哪个用“|”的方式连接,自己new出来。<br /> * 当然通过一系列的静态create方法创建比较方便。<br />注意:最好给搜索条留的宽度大一些,因为太窄、而hint文字太多的时候,后面会空一块位置,是为了预留按钮用的。 * </p> * * <p>Copyright: 版权所有 (c)<br> * Company: 久其</p> * * @author liyue * @version 2013-9-4 */ public class SearchBar implements Serializable{ /** * 搜索回调函数 */ public interface onSearchListener{ public void onSearch(String key, View v); } //按控件内容从左到右定义控制点 /** * 简单,一般只是界面上的一个样子,点击后执行转向。不聚焦 */ public static final int DISABLE_INPUT = 1 << 1; /** * 有左侧后退按钮的搜索条 */ public static final int BUTTON_LEFT = 1 << 2; /** * 搜索框左侧有放大镜图标 */ public static final int ICON_ZOOM = 1 << 3; /** * 有清除效果 */ public static final int BUTTON_CLEAR = 1 << 4; /** * 搜索图标,(替换掉正常的放大镜图标) */ public static final int ACTION_SEARCH = 1 << 5; /** * MIC图标,(替换掉正常的放大镜图标) */ public static final int ACTION_MIC = 1 << 6; /** * 有右侧取消按钮的搜索条 */ public static final int BUTTON_RIGHT = 1 << 7; /** * 取消背景图,会让搜索条和界面结合的更紧凑 */ public static final int NO_BACKGROUND = 1 << 8; private static final long serialVersionUID = -988452860866110213L; protected Context context; protected InputMethodManager imm; protected onSearchListener listener; protected Button btnLeft; protected Button btnClear; protected Button btnAction; protected Button btnRight; protected EditText etSearch; protected ProgressBar pgAction; protected View searchBarView; protected MyTextWatcher myTextWatcher = new MyTextWatcher(); protected int style = 0; /** * 标记是否为简单,默认否 */ protected boolean FLAG_DISABLE_INPUT = false; /** * 标记是否有左侧按钮,默认否 */ protected boolean FLAG_LEFT_BUTTON = false; /** * 标记是否有右侧按钮,默认否 */ protected boolean FLAG_RIGHT_BUTTON = false; /** * 标记在录入时是否出现清除按钮,默认否 */ protected boolean FLAG_CLEAR_BUTTON = false; /** * 标记动作按钮是否为搜索图标,默认否 */ protected boolean FLAG_ACTION_SEARCH = false; /** * 标记动作按钮是否为mic图标,默认否 */ protected boolean FLAG_ACTION_MIC = false; /** * 标记录入框左侧是否有放大镜点缀图标,默认否 */ protected boolean FLAG_ZOOM_ICON = false; /** * 取消背景,默认否 */ protected boolean FLAG_NO_BACKGROUND = false; public SearchBar(View parent){ this(parent, 0); } /** * 样式可以用| * @param parent * @param style */ public SearchBar(View parent, int style){ constructObj(parent, style); prepare(); initWidgets(); initListener(); initUI(); } private void constructObj(View parent, int style){ this.style = style; this.context = parent.getContext(); imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); if(parent instanceof ViewStub){ ViewStub vs = (ViewStub)parent; vs.setLayoutResource(R.layout.search_bar); searchBarView = vs.inflate(); } else if(parent instanceof ViewGroup){ LayoutInflater inflater = LayoutInflater.from(context); ViewGroup vp = (ViewGroup)parent; searchBarView = inflater.inflate(R.layout.search_bar, vp); } //根据风格确定控制点 FLAG_DISABLE_INPUT = DISABLE_INPUT == (style & DISABLE_INPUT); FLAG_LEFT_BUTTON = BUTTON_LEFT == (style & BUTTON_LEFT); FLAG_RIGHT_BUTTON = BUTTON_RIGHT == (style & BUTTON_RIGHT); FLAG_CLEAR_BUTTON = BUTTON_CLEAR == (style & BUTTON_CLEAR); FLAG_ACTION_MIC = ACTION_MIC == (style & ACTION_MIC); FLAG_ACTION_SEARCH = ACTION_SEARCH == (style & ACTION_SEARCH); FLAG_ZOOM_ICON = ICON_ZOOM == (style & ICON_ZOOM); FLAG_NO_BACKGROUND = NO_BACKGROUND == (style & NO_BACKGROUND); } /** * 界面在初始化之前的一些准备工作,供子类去做些准备 * @param parent * @param style */ protected void prepare(){ } /** * 初始化控件 */ protected void initWidgets(){ btnLeft = (Button)searchBarView.findViewById(R.id.btnLeft); etSearch = (EditText)searchBarView.findViewById(R.id.etSearch); btnClear = (Button)searchBarView.findViewById(R.id.btnClear); btnAction = (Button)searchBarView.findViewById(R.id.btnAction); pgAction = (ProgressBar)searchBarView.findViewById(R.id.pgAction); btnRight = (Button)searchBarView.findViewById(R.id.btnRight); if(FLAG_NO_BACKGROUND){ // searchBarView.setBackgroundDrawable(null); searchBarView.setBackgroundResource(R.drawable.bg_transparent); } else{ searchBarView.setBackgroundResource(R.drawable.widget_head_bg); } if(FLAG_DISABLE_INPUT){ imm.hideSoftInputFromWindow(etSearch.getWindowToken(), 0); etSearch.setClickable(false); etSearch.setFocusable(false); } else{ etSearch.setClickable(true); etSearch.setFocusable(true); } if(FLAG_LEFT_BUTTON){ btnLeft.setVisibility(View.VISIBLE); } if(FLAG_ZOOM_ICON){ etSearch.setCompoundDrawablesWithIntrinsicBounds(R.drawable.dot_zoom, 0, 0, 0); } if(FLAG_ACTION_MIC || FLAG_ACTION_SEARCH){ btnAction.setVisibility(View.VISIBLE); } if(FLAG_ACTION_MIC){ btnAction.setBackgroundResource(R.drawable.btn_search_bg_mic); } if(FLAG_ACTION_SEARCH){ btnAction.setBackgroundResource(R.drawable.btn_search_bg); } if(FLAG_RIGHT_BUTTON){ btnRight.setVisibility(View.VISIBLE); } } /** * 初始化监听器 */ protected void initListener(){ setBtnClearOnClickListener(); setBtnActionOnClickListener(); setEtSearchOnFocusChangeListener(); setEtSearchOnKeyListener(); setEtSearchOnEditorActionListener(); setEtSearchOnChangeListener(); setEtSearchTouchListener(); } /** * “清除”按钮事件 */ private void setBtnClearOnClickListener(){ btnClear.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v){ etSearch.setText(""); } }); } /** * 设置搜索框内容改变事件 */ protected void setEtSearchOnChangeListener(){ etSearch.addTextChangedListener(myTextWatcher); } /** * 设置搜索框Touch事件 */ protected void setEtSearchTouchListener(){ if(FLAG_DISABLE_INPUT){ etSearch.setOnTouchListener(new OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event){ switch(event.getAction()){ case MotionEvent.ACTION_UP: // 只许点一次 docallback(v); break; } return true; } }); } } /** * 设置搜索框软键盘事件 */ protected void setEtSearchOnEditorActionListener(){ //软键盘上按搜索的时候进行搜索 etSearch.setOnEditorActionListener(new TextView.OnEditorActionListener(){ @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event){ if(actionId == EditorInfo.IME_ACTION_SEARCH){ docallback(v); return true; } return false; } }); } /** * 设置搜索框键盘事件 */ protected void setEtSearchOnKeyListener(){ //键盘上按回车时进行搜索 etSearch.setOnKeyListener(new OnKeyListener(){ @Override public boolean onKey(View v, int keyCode, KeyEvent event){ if(KeyEvent.KEYCODE_ENTER == keyCode && event.getAction() == KeyEvent.ACTION_DOWN){ docallback(v); return true; } return false; } }); } /** * 设置搜索框焦点事件 */ protected void setEtSearchOnFocusChangeListener(){ etSearch.setOnFocusChangeListener(new View.OnFocusChangeListener(){ public void onFocusChange(View v, boolean hasFocus){ if(hasFocus){ imm.showSoftInput(v, 0); //imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } else{ imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } }); } /** * 搜索框右侧按钮点击事件 */ protected void setBtnActionOnClickListener(){ //搜索按钮点击时进行搜索 btnAction.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v){ docallback(v); } }); } /** * 点击事件回调,默认回调外onSearchListener */ protected void docallback(View v){ if(null != listener){ listener.onSearch(etSearch.getText().toString(), v); } } /** * 界面构造后,可根据需要进行一些界面初始化操作 */ protected void initUI(){ } /** * 得到搜索条根视图 * @return View */ public View getRootView(){ return searchBarView; } /** * 得到搜索框 * @return EditText */ public EditText getEtSearch(){ return etSearch; } /** * 得到动作按钮(包含在搜索框里的按钮,不是BtnRight)。默认显示,可根据录入关键字状态改变其功能。 * 如可清空关键字,提供语音录入等。设置背景图为:@drawable/btn_search_bg_clear或@drawable/btn_search_bg_mic * 默认背景图为:@drawable/btn_search_bg * 在进行搜索时,可以把搜索条显示出来,搜索条会在此按钮上层显示,等搜索结束后,再隐藏搜索条。 * @return Button */ public Button getBtnAction(){ return btnAction; } /** * 录入框右侧的清空按钮,默认不显示 * @return Button */ public Button getBtnClear(){ return btnClear; } /** * 界面上最右侧的按钮,一般用来做“取消”等。默认不显示。 * @return Button */ public Button getBtnRight(){ return btnRight; } /** * 界面上最左侧的按钮,一般用来做“返回”按钮。默认不显示。 * @return Button */ public Button getBtnLeft(){ return btnLeft; } /** * 进度条,如果显示,则会在动作按钮上层显示,遮住动作按钮的放大镜图标。默认不显示。 * @return ProgressBar */ public ProgressBar getProgressBar(){ return pgAction; } /** * 得到风格 * @return int */ public int getStyle(){ return this.style; } /** * 设置清除关键机制是否可用 * @param boolean */ public void setClearFacilityEnabled(boolean isEnabled){ FLAG_CLEAR_BUTTON = isEnabled; } /** * 设置最左侧按钮可见 * @param boolean visible */ public void setBtnLeftVisible(boolean visible){ if(visible){ btnLeft.setVisibility(View.VISIBLE); } else{ btnLeft.setVisibility(View.GONE); } } /** * 设置最右侧按钮可见 * @param boolean visible */ public void setBtnRightVisible(boolean visible){ if(visible){ btnRight.setVisibility(View.VISIBLE); } else{ btnRight.setVisibility(View.GONE); } } /** * 设置搜索条可见 * @param boolean visible */ public void setProgressBarVisible(boolean visible){ if(visible){ pgAction.setVisibility(View.VISIBLE); } else{ pgAction.setVisibility(View.GONE); } } /** * 设置搜索的回调函数 * @param listener */ public void setOnSearchListener(onSearchListener listener){ this.listener = listener; } /** * 创建无任何样式的搜索条 * @param parent * @return SearchBar */ public static SearchBar createSearchBar(View parent){ return new SearchBar(parent, 0); } /** * 创建简单的搜索条 * @param parent * @return SearchBar */ public static SearchBar createSimpleSearchBar(View parent){ return new SearchBar(parent, DISABLE_INPUT | ICON_ZOOM); } /** * 创建有右侧按钮的搜索条 * @param parent * @return SearchBar */ public static SearchBar createSearchBarWithRightButton(View parent){ return new SearchBar(parent, BUTTON_RIGHT | ACTION_SEARCH | BUTTON_CLEAR); } /** * 创建有左侧按钮的搜索条 * @param parent * @return SearchBar */ public static SearchBar createSearchBarWithLeftButton(View parent){ return new SearchBar(parent, BUTTON_LEFT | ACTION_SEARCH | BUTTON_CLEAR); } /** * 创建有左右两侧按钮的搜索条 * @param parent * @return SearchBar */ public static SearchBar createSearchBarWithBothButtons(View parent){ return new SearchBar(parent, BUTTON_LEFT | BUTTON_RIGHT | ACTION_SEARCH | BUTTON_CLEAR); } /** * 创建标准的搜索条,有搜索按钮,可清空录入字符 * @param parent * @return SearchBar */ public static SearchBar createStandardSearchBar(View parent){ return new SearchBar(parent, ACTION_SEARCH | BUTTON_CLEAR); } /** * 创建过滤条,一般用在过滤时,得到etSearch,加文本变化监听器 * @param parent * @return SearchBar */ public static SearchBar createFillterBar(View parent){ return new SearchBar(parent, ICON_ZOOM | BUTTON_CLEAR); } /** * 默认的TextWatcher */ private class MyTextWatcher implements TextWatcher{ @Override public void onTextChanged(CharSequence s, int start, int before, int count){ } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after){ } @Override public void afterTextChanged(Editable s){ if(FLAG_CLEAR_BUTTON){ if(TextUtils.isEmpty(s.toString())){ btnClear.setVisibility(View.GONE); } else{ if(btnClear.getVisibility() == View.GONE){ btnClear.setVisibility(View.VISIBLE); } } } else{ btnClear.setVisibility(View.GONE); } } } }