博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于AppCompatAutoCompleteTextView使用总结
阅读量:7058 次
发布时间:2019-06-28

本文共 9845 字,大约阅读时间需要 32 分钟。

今天抽出时间写一写关于这个控件我的理解,文笔不好,但是可以解决问题哈。

一、公司定下来的需求是这样的:

1、某两个界面都有右侧侧滑;

2、侧滑上有四个文本框;
3、每个文本框点击时候即出现提示下拉;
4、每个文本框输入的时候也会出现提示下拉;
6、当点击下拉内的item时,item文字显示在文本框内;
7、巴拉巴拉...就这么一堆。

二、想法

1、EditText+ListView;

2、AutoCompleteTextView或AppCompatAutoCompleteTextView或MultiAutoCompleteTextView
3、EditText+ListView;
4、去gihub大海捞针去;
...
为了保证程序性的简洁性、易用性、低维护成本....(其实就是懒),选择了第二个方案;实施之后,第二个虽然代码少了,但是这个逻辑啊,一张图表示(此处省略一万字)。既然是自己选择的方案,哭着也得写完。

*疼*紧

三、实施

1、在xml文件内写布局

这样的控件写了四个,其实可以写到values/style.xml文件内,但是为了只管展现,我就这么写了(说到底第还是懒)。下面放完整的侧滑代码:

然后进入咱们的熟悉的Activity内开始装x大业;

2、满足点击文本框就出现下拉菜单

初始化后的 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);        }    }

当点击的控件为当前控件并且该控件获取了焦点,则进行相关的网络请求,此时返回数据展示在文本框的下拉的菜单当中

3、展示下拉菜单

/**     * 展示搜索框下拉列表     *     * @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) {        ArrayList
views = 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(); } }

这个方法很简单了,就不多解释了(还是有点懒),如果你要是不明白了,留言给我,我告诉你哈(手动滑稽);

4、进行输入文本展示下拉

当用户不喜欢选择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) {        }    }

每次输入的时候都会出现下拉菜单,完美(沾沾自喜中)。以后一测试,傻眼了。。。。

这样写产生的结果是:每次从下拉内点击item之后,数据进入文本框触发 TextWatcher 的回调 ,然后你懂得,可能你也有可能不懂,文本框下面出现一个网络请求来的 item 。

这次我终于不懒了,百度、谷歌了好几天,翻来覆去就是那么两篇文章,而且我感觉那群楼主都是相互抄来抄去的,一个能解决问题的都没有。 不过看见一个回答问题的博主,他说可以使用一个 boolean 的标志位,我感觉也可以,但是赎晚辈愚笨,我是不知道加到哪里可以实现。如果哪位兄台可以弄出来,跪求传授修仙打法。楼主跪下了哈:
跪求修仙大法

5、解决小尾巴问题

经过反复沉思,想到了一个比较靠谱的方法:

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

你可能感兴趣的文章
沪穗深百万地铁族担心:花生WiFi到底安全吗?
查看>>
东莞:现代会展公司成立呼叫中心 大数据分析提升办展质量
查看>>
实现“中国制造”向“中国智造”转变 大数据技术成关键
查看>>
苹果市值15个交易日蒸发450亿美元 相当于半个波音
查看>>
中小企业网络方案商该关注哪些增值空间?
查看>>
苹果Safari浏览器遭遇全球故障 搜索即崩溃
查看>>
周鸿祎谈360回归初衷
查看>>
安防爆发年 谈谈车牌识别如何实现从原理到应用的转变?
查看>>
凯立德智慧物流地图服务平台让物流行业更省心
查看>>
安防产业布局跨境电商 有哪些方法?
查看>>
明晰监管范围保护信息安全
查看>>
超融合架构:主数据存储使命之外
查看>>
澳大利亚电信公布其可编程网络计划
查看>>
《Excel数据可视化:一样的数据不一样的图表》——3.2 用项目规则显示隐藏在计算机中的数据...
查看>>
诺基亚将在 MWC 上发布低成本 Android 手机
查看>>
《Outlook时间整理术》一不是电子邮件的问题,而是我们应如何处理它
查看>>
《Adobe Premiere Pro CS5经典教程》——第1课 Adobe Premiere Pro CS5概述 1.1 Adobe Premiere Pro CS5中的新功能...
查看>>
设计师是不是真正的用户
查看>>
《CCIE路由和交换认证考试指南(第5版) (第1卷)》——1.2节以太网第1层:线缆、速率和双工...
查看>>
补丁不起作用:Mac平台安全漏洞仍然存在
查看>>