• 自定义延时查询控件---valen


    当查询已经成标配

    查询是已成为每个应用常用的功能,也正是这样前端后对查询的设计需求也日益增加,本文针对前端(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端当然也可以实现自己的延时查询控件,达到一次编写,到处运行; 

  • 相关阅读:
    NOIP 2017逛公园(记忆化搜索)
    NOIP 2012疫情控制 (二分+倍增+贪心)
    NOIP 2005过河(DP+路径压缩)
    P1198 [JSOI2008]最大数
    [Noip2016]蚯蚓
    [六省联考2017]期末考试
    六省联考:组合数问题
    蒜头君的兔子
    bzoj1015 [JSOI2008]星球大战starwar
    luogu P3370 【模板】字符串哈希
  • 原文地址:https://www.cnblogs.com/lihuobao/p/5640339.html
Copyright © 2020-2023  润新知