当查询已经成标配

查询是已成为每个应用常用的功能,也正是这样前端后对查询的设计需求也日益增加,本文针对前端(Android端)查询控件做一个例子;

 

控件设计与逻辑

产品的设计UI图;

要达到如下

1|、默认第一张图,中间展示默认提示文字,左边搜索图标;

2、输入文字后提示语消失,搜索的文字在后面,另外右边显示取消的图标

3、外加一个性能需求,我们搜索没必要每输入一个字都请求一次后台数据,有时候用户很快输入很多字符,就会导致大量没用的期过后,可以输入完等一段时间没输入才发起查询请求;

 

具体代码实现

先贴出代码后面做关键的解释

  1 public class SearchDisplayView extends EditText {
  2     private static int COUNTDOWN_INTERVAL = 300;
  3     private DelayAfterTextChangedListener mDelayTextChangedListener;
  4 
  5     public static interface DelayAfterTextChangedListener {
  6         public void afterTextChanged(String keyword);
  7     }
  8 
  9     private CountDownTimer mCountDownTimer = new CountDownTimer(COUNTDOWN_INTERVAL, COUNTDOWN_INTERVAL) {
 10 
 11         @Override
 12         public void onTick(long millisUntilFinished) {
 13             //间隔执行
 14         }
 15 
 16         @Override
 17         public void onFinish() {
 18             if(mDelayTextChangedListener != null) {
 19                 mDelayTextChangedListener.afterTextChanged(getText().toString());
 20             }
 21         }
 22     };
 23 
 24     public SearchDisplayView(Context context) {
 25         this(context, null);
 26     }
 27 
 28     public SearchDisplayView(Context context, AttributeSet attrs) {
 29         super(context, attrs);
 30         if (isInEditMode()) {
 31             return;
 32         }
 33         initViews();
 34     }
 35 
 36     private void initViews() {
 37         setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_search, 0, 0, 0);
 38         setTextAppearance(getContext(), R.style.LHBTextView_Medium_DaryGray);
 39         setHintTextColor(getResources().getColor(R.color.light_gray));
 40         setBackgroundResource(R.drawable.bg_corner_white);
 41         int paddingLeft = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10,
 42                 getResources().getDisplayMetrics());
 43         int paddingTop = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4,
 44                 getResources().getDisplayMetrics());
 45         setPadding(paddingLeft, paddingTop, paddingLeft, paddingTop);
 46         setCompoundDrawablePadding(paddingLeft);
 47         setGravity(Gravity.CENTER);
 48 
 49         setOnTouchListener(new OnTouchListener() {
 50             @Override
 51             public boolean onTouch(View v, MotionEvent event) {
 52                 if (event.getAction() == MotionEvent.ACTION_UP) {
 53                     if (getCompoundDrawables()[2] != null) {
 54                         boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight()) &&
 55                                 (event.getX() < ((getWidth() - getPaddingRight())));
 56                         if (touchable) {
 57                             setText("");
 58                         }
 59                     }
 60                 }
 61                 return false;
 62             }
 63         });
 64 
 65         addTextChangedListener(new TextWatcher() {
 66             @Override
 67             public void beforeTextChanged(CharSequence s, int start, int count, int after) {
 68 
 69             }
 70 
 71             @Override
 72             public void onTextChanged(CharSequence s, int start, int before, int count) {
 73                 boolean empty = TextUtils.isEmpty(s);
 74                 setCompoundDrawablesWithIntrinsicBounds(0, 0, !empty ? R.drawable.ic_dialog_close : 0, 0);
 75             }
 76 
 77             @Override
 78             public void afterTextChanged(Editable s) {
 79                 if(mDelayTextChangedListener != null) {
 80                     mCountDownTimer.cancel();
 81                     mCountDownTimer.start();
 82                 }
 83             }
 84         });
 85 
 86         setOnFocusChangeListener(new View.OnFocusChangeListener() {
 87             @Override
 88             public void onFocusChange(View v, boolean hasFocus) {
 89                 if (hasFocus) {
 90                     setTag(getHint());
 91                     setHint("");
 92                 } else {
 93                     setHint(getTag().toString());
 94                 }
 95                 setGravity(hasFocus ? Gravity.LEFT : Gravity.CENTER);
 96                 setCompoundDrawablesWithIntrinsicBounds(!hasFocus ? R.drawable.ic_search : 0, 0, getCompoundDrawables()[2] != null ? R.drawable.ic_dialog_close : 0, 0);
 97             }
 98         });
 99     }
100 
101     public void setDelayAfterTextChangedListener(DelayAfterTextChangedListener afterTextChangedListener) {
102         mDelayTextChangedListener = afterTextChangedListener;
103     }
104 
105     @Override
106     protected void onDetachedFromWindow() {
107         super.onDetachedFromWindow();
108         if (mCountDownTimer != null) {
109             mCountDownTimer.cancel();
110         }
111     }
112 
113     public void setDisplayHint(int resid) {
114         setHint(resid);
115         setTag(getResources().getString(resid));
116     }
117 }
查看代码

 1、代码继承EditText实现输入框的查询;

 2、initView()初始化查询控件的样式和相关事件触发;

 3、setOnTouchListener()处理右边"点击关闭图标"的出现时机和清楚输入文字处理;

 4、addTextChangedListener() 监听文字变化,当中 onTextChanged() 回调函数处理左边样式控制,afterTextChanged() 做延时查询处理;

 5、setOnFocusChangeListener() 处理在获得焦点的时候样式的变化,如提示语消失和文字靠左;

 6、延时处理核心在CountDownTimer这个匿名内部类段落,里面重写了CountDownTimer回调方法并实现自己的逻辑,这是一个时间倒数的处理类,通过人肉实验300毫秒能处理好少请求并查询速度响应的时点;到最后在控件脱离窗体的时候onDetachedFromWindow(),为了安全起见别忘了重新取消下定时的操作;

 7、这样控件并封装完成,在需要使用的地方直接引用就可以,需要延时的则调用监听方法setDelayAfterTextChangedListener() 可以使用;

 

最后

上面以安卓为例子,IOS WEB端当然也可以实现自己的延时查询控件,达到一次编写,到处运行; 

posted on 2016-07-04 15:11  理货宝  阅读(292)  评论(0编辑  收藏  举报