本文共 9845 字,大约阅读时间需要 32 分钟。
今天抽出时间写一写关于这个控件我的理解,文笔不好,但是可以解决问题哈。
1、某两个界面都有右侧侧滑;
2、侧滑上有四个文本框; 3、每个文本框点击时候即出现提示下拉; 4、每个文本框输入的时候也会出现提示下拉; 6、当点击下拉内的item时,item文字显示在文本框内; 7、巴拉巴拉...就这么一堆。1、EditText+ListView;
2、AutoCompleteTextView或AppCompatAutoCompleteTextView或MultiAutoCompleteTextView 3、EditText+ListView; 4、去gihub大海捞针去; ... 为了保证程序性的简洁性、易用性、低维护成本....(其实就是懒),选择了第二个方案;实施之后,第二个虽然代码少了,但是这个逻辑啊,一张图表示(此处省略一万字)。既然是自己选择的方案,哭着也得写完。这样的控件写了四个,其实可以写到values/style.xml文件内,但是为了只管展现,我就这么写了(说到底第还是懒)。下面放完整的侧滑代码:
然后进入咱们的熟悉的Activity内开始装x大业;
初始化后的 AppCompatAutoCompleteTextView 对象实现 onFocusChangeListener() 接口
在 onFocusChangeListener() 接口内判断点击的是哪个控件,并且这个控件是否真的活得了焦点; 我当时没有用 switch、case 的形式,而是采用了 if、 else 的形式进行的判断,代码如下:@Override public void onFocusChange(View v, boolean hasFocus) { if (TextUtils.isEmpty(etProName.getText().toString())) { projectId = 0; } if (TextUtils.isEmpty(etSysName.getText().toString().trim())) { systemId = 0; } if (TextUtils.isEmpty(etSysName.getText().toString().trim())) { firmId = 0; } if (v.getId() == etProName.getId() && etProName.hasFocus()) { HttpRequest.getProject(etProName.getText().toString().trim(), HiddenDangerActivity.this); } else if (v.getId() == etSysName.getId() && etSysName.hasFocus()) { if (TextUtils.isEmpty(etProName.getText().toString().trim())) { if (TextUtils.isEmpty(etFirmName.getText().toString().trim())) firmId = 0; HttpRequest.getSystems(etSysName.getText().toString().trim(), firmId, 0, HiddenDangerActivity.this); } else { HttpRequest.getSystemData(projectId, HiddenDangerActivity.this); } } else if (v.getId() == etFirmName.getId() && etFirmName.hasFocus()) { if (TextUtils.isEmpty(etSysName.getText().toString().trim())) systemId = 0; HttpRequest.getFirms(etFirmName.getText().toString().trim(), 0, systemId, HiddenDangerActivity.this); } else if (v.getId() == etTypeName.getId() && etTypeName.hasFocus()) { HttpRequest.getDanger(etTypeName.getText().toString().trim(), HiddenDangerActivity.this); } }
当点击的控件为当前控件并且该控件获取了焦点,则进行相关的网络请求,此时返回数据展示在文本框的下拉的菜单当中
/** * 展示搜索框下拉列表 * * @param i 标志位 */ private void setAdapter(int i) { if (isShow) { switch (i) { case 1: ArrayAdapter projectAdapter = new ArrayAdapter<>(HiddenDangerActivity.this, R.layout.item_h_f_iact, projects); projectAdapter.notifyDataSetChanged(); etProName.setAdapter(projectAdapter); removeViewFocus(etProName); etProName.showDropDown(); break; case 2: ArrayAdapter systemAdapter = new ArrayAdapter<>(HiddenDangerActivity.this, R.layout.item_h_f_iact, systems); systemAdapter.notifyDataSetChanged(); etSysName.setAdapter(systemAdapter); removeViewFocus(etSysName); etSysName.showDropDown(); break; case 3: ArrayAdapter firmAdapter = new ArrayAdapter<>(HiddenDangerActivity.this, R.layout.item_h_f_iact, firms); firmAdapter.notifyDataSetChanged(); etFirmName.setAdapter(firmAdapter); removeViewFocus(etFirmName); etFirmName.showDropDown(); break; case 4: ArrayAdapter warnTypeAdapter = new ArrayAdapter<>(HiddenDangerActivity.this, R.layout.item_h_f_iact, dangerTypes); warnTypeAdapter.notifyDataSetChanged(); etTypeName.setAdapter(warnTypeAdapter); removeViewFocus(etTypeName); etTypeName.showDropDown(); break; default: } } }
这里比较非常重要的代码是:etTypeName.showDropDown()
这句话丢了就会导致,输入两个字(默认情况下)才会出现下拉菜单,或者是你设置了 android:completionThreshold="1"
属性,也得输入一个字之后才会出息下拉菜单的尴尬局面;所以 .showDropDown()
方法绝对不能懒。
对了 removeViewFocus();
方法内代码为:
private void removeViewFocus(AppCompatAutoCompleteTextView view) { ArrayListviews = new ArrayList<>(); views.add(etFirmName); views.add(etSysName); views.add(etProName); views.add(etTypeName); for (int i = 0; i < views.size(); i++) { if (views.get(i).equals(view)) { views.remove(i); } } for (AppCompatAutoCompleteTextView v : views) { v.clearFocus(); v.dismissDropDown(); } }
这个方法很简单了,就不多解释了(还是有点懒),如果你要是不明白了,留言给我,我告诉你哈(手动滑稽);
当用户不喜欢选择item的时候也可以一个字一个字的的进行输入(一般来说客户都很勤快,别我勤快),我们也得提示一下,放置用户打错了啥的,于是也得展现下拉菜单,导致这4个控件得实现 TextWatcher
这个接口;
class MyTextWatcher implements TextWatcher { private int tag; MyTextWatcher(int tag) { this.tag = tag; } @Override public void afterTextChanged(Editable s) { if (isShow) { switch (tag) { case 1: if (TextUtils.isEmpty(etProName.getText().toString().trim())) { projectId = 0; } HttpRequest.getProject(s.toString(), HiddenDangerActivity.this); break; case 2: if (projectId == 0) { HttpRequest.getSystems(s.toString(), firmId, 0, HiddenDangerActivity.this); } else { HttpRequest.getSystemData(projectId, HiddenDangerActivity.this); } break; case 3: if (TextUtils.isEmpty(s.toString())) { firmId = 0; } HttpRequest.getFirms(s.toString(), 0, systemId, HiddenDangerActivity.this); break; case 4: HttpRequest.getDanger(s.toString(), HiddenDangerActivity.this); break; } } } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } }
每次输入的时候都会出现下拉菜单,完美(沾沾自喜中)。以后一测试,傻眼了。。。。
经过反复沉思,想到了一个比较靠谱的方法:
在.showDropDown();
方法处加个if 判断,即将网络请求来的 “数据第一个”与“控件内取出的数据”进行对比,如果不同则展示下拉列表,相同则不展示下拉列表; 修改之后的下拉数据展示代码为: /** * 展示搜索框下拉列表 * * @param i 标志位 */ private void setAdapter(int i) { if (isShow) { switch (i) { case 1: ArrayAdapter projectAdapter = new ArrayAdapter<>(HiddenDangerActivity.this, R.layout.item_h_f_iact, projects); projectAdapter.notifyDataSetChanged(); etProName.setAdapter(projectAdapter); removeViewFocus(etProName); if (!etProName.getText().toString().trim().equals(projects.get(0).getProjName())) { etProName.showDropDown(); } break; case 2: ArrayAdapter systemAdapter = new ArrayAdapter<>(HiddenDangerActivity.this, R.layout.item_h_f_iact, systems); systemAdapter.notifyDataSetChanged(); etSysName.setAdapter(systemAdapter); removeViewFocus(etSysName); if (!etSysName.getText().toString().trim().equals(systems.get(0).getDevSysName())) { etSysName.showDropDown(); } break; case 3: ArrayAdapter firmAdapter = new ArrayAdapter<>(HiddenDangerActivity.this, R.layout.item_h_f_iact, firms); firmAdapter.notifyDataSetChanged(); etFirmName.setAdapter(firmAdapter); removeViewFocus(etFirmName); if (!etFirmName.getText().toString().trim().equals(firms.get(0).getFirmName())) { etFirmName.showDropDown(); } break; case 4: ArrayAdapter warnTypeAdapter = new ArrayAdapter<>(HiddenDangerActivity.this, R.layout.item_h_f_iact, dangerTypes); warnTypeAdapter.notifyDataSetChanged(); etTypeName.setAdapter(warnTypeAdapter); removeViewFocus(etTypeName); if (!etTypeName.getText().toString().trim().equals(dangerTypes.get(0).getWarnTyDesc())) { etTypeName.showDropDown(); } break; default: } } }
到此为止,完美的实现了需求,文本框点击数显下拉、输入输入出现下拉的需求。
文笔不好,代码水平不太高。有大佬指点,小弟感激涕零。当然有问题,大家留言区留言,一起探讨哈。关于探讨问题,楼主还是不太懒得哈。
转载地址:http://regol.baihongyu.com/