Android 打造可下拉的EditText--DropEditText

android 基于EditView+PopWindow+Listview实现可输入检索式下拉框 开发过程中经常使用Spinner标签,但如果数据量太多,用户下拉选择效率低,体验差。为了解决这个问题,可以使用PopWindow+listView实现可输入检索式下拉框。 实现思路:1、请求后台数据,将数据放入ListView中。 1、因为是可输入,所以页面元素使用EditView。为editview设置addTextChangedListener监听事件,该方法中代码逻辑:如果获取当前字符,对后台请求得list进行删选,根据删选后的list,将ListView更新,弹出PopWindow。 2、Po 阅读详情

android的默认Spinner只能下拉选择内容,而不能选择,有时候我们想提供给用户更加人性化的UI,既可以通过下拉选择,也可以通过EditText输入,是要定义两个组件吗? 这样并不适合我们的设计要求。

那么, 我们就自己写一个这样的组件吧——DropEditText。

一、思路

1、DropEditText并不是一个Spinner,也不是一个EditText。

2、这里的解决方式是,组合以个EditText和一个ImageView,点击ImageView弹出一个PopupWindow达到下拉的效果。


二、问题

1、组合EditText和ImageView,而又不能让用户看出这是一个组合。

2、PopupWindow弹出的位置怎么控制。

3、如何做到当点击PopupWindow上的选项,向EditText填充对应的内容。


三、效果

再开始代码之前,先看看预想的效果吧,有了目标才好code


通过效果图可以看出,DropEditText还算比较灵活的,可以设置下拉的模式:跟随上面和包裹内容。


四、解决问题

再回头看看我们的问题。

第一个问题很好解决,相信很多人都可以轻松的解决。做法是用一个LinearLayout包裹EditText和ImageView,同时设置LinearLayout的背景为我们定义的shape,同时取消掉EditText默认的背景。

[html]  view plain copy
  1. <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”  
  2.     android:layout_width=“match_parent”  
  3.     android:layout_height=“wrap_content”  
  4.     android:orientation=“horizontal”  
  5.     android:background=“@drawable/edit_bg_shape” >  
  6.       
  7.     <EditText  
  8.         android:id=“@+id/dropview_edit”  
  9.         android:layout_width=“0dip”  
  10.         android:layout_weight=“1”  
  11.         android:layout_height=“wrap_content”  
  12.         style=“?android:attr/textViewStyle”  
  13.         android:background=“@null”  
  14.         android:height=“40dip” />  
  15.       
  16.     <ImageView  
  17.         android:id=“@+id/dropview_image”  
  18.         android:layout_width=“wrap_content”  
  19.         android:layout_height=“match_parent”  
  20.         android:layout_gravity=“center_vertical”  
  21.         android:scaleType=“fitXY”  
  22.         android:layout_marginTop=“2dip”  
  23.         android:layout_marginBottom=“2dip”  
  24.         android:paddingRight=“2dip” />  
  25. </LinearLayout>  


第二个问题,控制PopupWindow的弹出的位置,很明显我们需要它显示在EditText上下面,sdk给我们提供了一个很好的方法:

[html]  view plain copy
  1. PopupWindow.showAsDropDown(anchor, xoff, yoff)  


参数1:以哪个view为目标弹出

参数2:x偏移量

参数3:y的偏移量

第二个问题就这么轻松的解决了。


第三个问题,我想到了用ListView做,用ListView做可以很方便的取item,但是有一个问题:ListView默认是占满横向的屏幕的,但这也不是问题,我们可以重写ListView的onMeasure方法改变它的测量机制。



五、上代码

先来看看重写的ListView吧,做的工作就是重写onMeasure方法,使它的宽度可变,还提供了一个方法可以设置ListView的宽度:

[java]  view plain copy
  1. public class WrapListView extends ListView {  
  2.     private int mWidth = 0;  
  3.       
  4.     public WrapListView(Context context, AttributeSet attrs) {  
  5.         this(context, attrs, 0);  
  6.     }  
  7.   
  8.     public WrapListView(Context context, AttributeSet attrs, int defStyle) {  
  9.         super(context, attrs, defStyle);  
  10.     }  
  11.       
  12.     // 重写onMeasure方法 解决默认横向占满屏幕问题  
  13.     @Override  
  14.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  15.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  16.           
  17.         int height = getMeasuredHeight();  
  18.         // measureChildren(widthMeasureSpec, heightMeasureSpec);  
  19.         for(int i=0;i<getChildCount();i++) {  
  20.             int childWidth = getChildAt(i).getMeasuredWidth();  
  21.             mWidth = Math.max(mWidth, childWidth);  
  22.         }  
  23.           
  24.         setMeasuredDimension(mWidth, height);  
  25.     }  
  26.       
  27.     /** 
  28.      * 设置宽度,如果不设置,则默认包裹内容 
  29.      * @param width 宽度 
  30.      */  
  31.     protected void setListWidth(int width) {  
  32.         mWidth = width;  
  33.     }  
  34. }  
重点在14~25行,首先我们调用了一下父类的onMeasure方法,为的就是利用ListView默认的测量机制获取总高度。在第17行我们获取了测量后的高度,接下来就是一个for循环,取出每一个item,并获取他的高度。mWidth的值就是子item中最宽的那个item的宽度(当然在下面我们提供的方法中可以手动修改mWidth的值)。

自定义的setListWidth方法可以手动设置ListView的宽度,按说,我们改变了width的值,应该requestLayout()一下让ListView重走一下测量流程才对,但这里没有提供。答案就是:ListView默认是不显示的,只有在点击了drop图标后才会出现,也就是setListWidth()永远会走在onMeasure前面,可能到这里会有点晕,看完下面的代码后就会清楚了。

 

再来看看DropEditText吧,这个View是组合了EditText和ImageView,内置了一个PopupWindow,让组件用起来更见方便。

[java]  view plain copy
  1. public class DropEditText extends FrameLayout implements View.OnClickListener, OnItemClickListener {  
  2.     private EditText mEditText;  // 输入框  
  3.     private ImageView mDropImage; // 右边的图片按钮  
  4.     private PopupWindow mPopup; // 点击图片弹出popupwindow  
  5.     private WrapListView mPopView; // popupwindow的布局  
  6.       
  7.     private int mDrawableLeft;  
  8.     private int mDropMode; // flower_parent or wrap_content  
  9.     private String mHit;  
  10.       
  11.     public DropEditText(Context context, AttributeSet attrs) {  
  12.         this(context, attrs, 0);  
  13.     }  
  14.       
  15.     public DropEditText(Context context, AttributeSet attrs, int defStyle) {  
  16.         super(context, attrs, defStyle);  
  17.         LayoutInflater.from(context).inflate(R.layout.edit_layout, this);  
  18.         mPopView = (WrapListView) LayoutInflater.from(context).inflate(R.layout.pop_view, null);  
  19.           
  20.         TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.DropEditText, defStyle, 0);  
  21.         mDrawableLeft = ta.getResourceId(R.styleable.DropEditText_drawableRight, R.drawable.ic_launcher);  
  22.         mDropMode = ta.getInt(R.styleable.DropEditText_dropMode, 0);  
  23.         mHit = ta.getString(R.styleable.DropEditText_hint);  
  24.         ta.recycle();  
  25.     }  
  26.       
  27.     @Override  
  28.     protected void onFinishInflate() {  
  29.         super.onFinishInflate();  
  30.           
  31.         mEditText = (EditText) findViewById(R.id.dropview_edit);  
  32.         mDropImage = (ImageView) findViewById(R.id.dropview_image);  
  33.           
  34.         mEditText.setSelectAllOnFocus(true);  
  35.         mDropImage.setImageResource(mDrawableLeft);  
  36.       
  37.         if(!TextUtils.isEmpty(mHit)) {  
  38.             mEditText.setHint(mHit);  
  39.         }  
  40.           
  41.         mDropImage.setOnClickListener(this);  
  42.         mPopView.setOnItemClickListener(this);  
  43.     }  
  44.       
  45.     @Override  
  46.     protected void onLayout(boolean changed, int left, int top, int right,  
  47.             int bottom) {  
  48.         super.onLayout(changed, left, top, right, bottom);  
  49.         // 如果布局发生改  
  50.         // 并且dropMode是flower_parent  
  51.         // 则设置ListView的宽度  
  52.         if(changed && 0 == mDropMode) {  
  53.             mPopView.setListWidth(getMeasuredWidth());  
  54.         }  
  55.     }  
  56.       
  57.     /** 
  58.      * 设置Adapter 
  59.      * @param adapter ListView的Adapter 
  60.      */  
  61.     public void setAdapter(BaseAdapter adapter) {  
  62.         mPopView.setAdapter(adapter);  
  63.           
  64.         mPopup = new PopupWindow(mPopView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);  
  65.         mPopup.setBackgroundDrawable(new ColorDrawable(color.transparent));  
  66.         mPopup.setFocusable(true); // 让popwin获取焦点  
  67.     }  
  68.       
  69.     /** 
  70.      * 获取输入框内的内容 
  71.      * @return String content 
  72.      */  
  73.     public String getText() {  
  74.         return mEditText.getText().toString();  
  75.     }  
  76.       
  77.     @Override  
  78.     public void onClick(View v) {  
  79.         if(v.getId() == R.id.dropview_image) {  
  80.             if(mPopup.isShowing()) {  
  81.                 mPopup.dismiss();  
  82.                 return;  
  83.             }  
  84.               
  85.             mPopup.showAsDropDown(this, 0, 5);  
  86.         }  
  87.     }  
  88.   
  89.     @Override  
  90.     public void onItemClick(AdapterView<?> parent, View view, int position,  
  91.             long id) {  
  92.         mEditText.setText(mPopView.getAdapter().getItem(position).toString());  
  93.         mPopup.dismiss();  
  94.     }  
  95. }  

在构造方法中我们获取了三个自定义的属性:

mDrawableLeft —— 点击下拉的图标

mDropMode —— 下拉菜单显示的模式,是一个枚举类型,提供了wrap_content和flower_parent两种模式,在演示的图片中可以看到两个DropEditText的下拉列表是不同的,第一个是宽度和上面的View相同,使用了flower_parent类型;第二个是包裹内容,使用了wrap_content类型。

mHit —— 就是EditText的hit。

再看onLayout:

[java]  view plain copy
  1. @Override  
  2. protected void onLayout(boolean changed, int left, int top, int right,  
  3.         int bottom) {  
  4.     super.onLayout(changed, left, top, right, bottom);  
  5.     if(changed && 0 == mDropMode) {  
  6.         mPopView.setListWidth(getMeasuredWidth());  
  7.     }  
  8. }  



一个if语句,表示如果模式为flower_parent时才去设置ListView的宽度,为什么呢? 答案就是:WrapListView默认就是包裹内容的,所以在wrap_content模式下根本不需要任何代码,ListView就是包裹内容的。

接下来就是一个setAdapter的方法了:

[java]  view plain copy
  1. public void setAdapter(BaseAdapter adapter) {  
  2.     mPopView.setAdapter(adapter);  
  3.           
  4.     mPopup = new PopupWindow(mPopView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);  
  5.     mPopup.setBackgroundDrawable(new ColorDrawable(color.transparent));  
  6.     mPopup.setFocusable(true); // 让popwin获取焦点  
  7. }  



参数就是BasicAdapter,功能就是给ListView设置adapter,在这里还初始化了PopupWindow,没关系它完全可以不在这里初始化,把它放这是因为我并没有想一开始就用ListView做。

下面的代码就没什么好说的了。getText()是获取EditText文本的,在onClick()中显示和隐藏PopupWindow,在onItemClick()中获取ListView的item的内容,并填充到EditText中。

 

ok,到这里DropEditText的实现已经完成,最后再让我们看看效果吧:



最后是项目下载地址:https://github.com/qibin0506/DropEditText

android 手动实现可输入下拉框Spinner控件(工具类) 一、前言 一丝感想 一直想着多写几篇博客,一个为了提升自己,也是给需要的人提供帮助。可惜,项目太近,琐事太多,实在闲不下来,唉。不管怎样,还是想抽点时间出来完成这篇博客! 进入正题 android 是自带有下拉框spinner控件的,但是android原生的Spinner控件是不支持用户输入的(据我所知),仅仅支持在数据列表确定的情况下进行选择。所以要实现一个手动输入的下拉框,我们需要自己手动实现... 阅读详情

相关推荐

Android实现一个可以输入也可以下拉选择的EditText输入框(附完整源码)

Android实现一个可以输入也可以下拉选择的EditText输入框(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 537

打造可下拉的EditText--DropEditText

android的默认Spinner只能下拉选择内容,而不能选择,有时候我们想提供给用户更加人性化的

Loader's Blog 4175

论文记录:Affine Formation Maneuver Control of Multiagent Systems

多智能体编队控制仿真记录 实现功能:平移/旋转/尺寸缩放/shear,见截图 注意:本仿真图只是起到了演示效果,中间过程速度产生突变,实际中是不允许的。需要进行速度规划,这一点论文中仿真图更为贴合实际。 参考论文:Zhao, S. (2018). Affine Formation Maneuver Control of Multiagent Systems. IEEE Transactions on Automatic Control, 63(12), 4140–4155. 突然发现有个博主写得很好,参考:

W1H1J1的博客 2108

DropEditText,带下拉功能的EditText

带下拉功能的DropEditText!

阿飞的博客 6805

从零开始:手把手教你规划与部署华为FusionCompute虚拟化平台(含网络规划避坑指南)

本文详细介绍了华为FusionCompute虚拟化平台的规划与部署流程,特别针对网络规划中的常见问题提供了避坑指南。从硬件软件清单检查、网络平面配置到VRM部署方案选择,帮助用户高效完成部署并优化性能,适用于云计算环境中的虚拟化平台搭建。

weixin_28693447的博客 243

基于单片机电能质量检测仪设计

*单片机设计介绍,基于单片机电能质量检测仪设计。

2201_75940997的博客 1205

Android学习笔记:自定义组合控件--打造可下拉的EditText--DropEditText

由于安卓并没有这样的控件,所以在需要用到的时候,只能够自己通过将EditText和Listview组合起来实现需求功能,为了方便使用,可以自定义一个组合控件,这样使用起来就很方便的啦! 实现过程: 首先一个布局文件,里面放一个editText和个人自定义的控件(也可以用Imageview或者其他view,主要是用来实现点击的) xml version="1.0" encoding

weixin_40340362的博客 735

关于使用CMT2300A FIFO缓存区间设置为64Byte的问题

帮助你解决在使用CMT2300A 时遇到的各种问题,若有需要,请及时与我交流

teleger的博客 1429

android edittext 下拉菜单,Android EditText+ListPopupWindow实现可编辑的下拉列表

使用场景AutoCompleteEditText只有开始输入并且与输入的字符有匹配的时候才弹出下拉列表.Spinner的缺点是不可以编辑.所以本文介绍如何使用EditText+ListPopupWindow实现可编辑的下拉列表.使用场景可以是有记住密码功能的登录框.给EditText增加上下箭头我们需要一个箭头图片,放在EditText的右面,用来点击后弹出下拉列表.如图所示要想实现这个很容易,只...

weixin_26704349的博客 1239

历年北京理工大学复试专业综合题

。

A place to record sth. 2万+

FAGLB03余额显示异常排查与修复指南

本文针对SAP新总账中FAGLB03报表余额显示异常问题,提供了专业的排查与修复指南。文章深入剖析了数据不一致的核心原因,如FAGLFLEXT汇总表与凭证明细不同步、年度余额结转(FAGLGVTR)失败等,并详细介绍了使用FAGLF03进行精准诊断、通过SE38执行标准调整程序TFC_ADJUST_VZ进行修复的标准操作流程,帮助用户快速恢复数据一致性,确保财务报表的准确性。

weixin_29313423的博客 307

android可编辑下拉列表,DropEditText

DropEditText一款可以在android上实现类似windows上的下拉效果的组件,并且可以实现文本输入。效果演示:使用方法:在布局文件配置:android:id="@+id/drop_edit"android:layout_width="200dip"android:layout_height="wrap_content"drop:drawableRight="@drawable/dro...

weixin_42363600的博客 368

Qwen-Image-2.1本地图像生成整合包:8G显存一键部署指南

文生图模型是AI视觉创作的核心技术,其本地化部署需兼顾模型能力、硬件适配与工程易用性。Qwen-Image-2.1作为支持文本生成、图像编辑与多图参考的统一架构模型,突破了传统Diffusion模型在消费级显卡上的运行瓶颈。通过AWQ量化、vLLM推理优化与ComfyUI节点重构,实现8G显存稳定运行,显著降低CUDA环境配置复杂度。该方案面向设计师、教师与普通用户,提供开箱即用的本地AI图像工作流,适用于电商主图迭代、教学配图生成与IP角色延展等真实场景,让高质量图像生成真正走出云端,落地桌面。

weixin_29082143的博客 398

Android EditText输入框实现下拉且保存最近5个历史记录

文章结构 需求阐述 技术部同事提出想要在APP上保存最近输入成功的5个密钥信息,同时支持可以下拉进行选择。 这也是为了方便客户在现在多次输入信息,帮助其快速进行输入。 实现思路 目前想要实现的需求 想要实现保存用户输入的密钥信息。 通过点击右侧的下拉来触发,让用户去选择已经发送成功的信息。 通过SharedPreferences来保存每次APP退出后的数据。 当发送成功后,更新后台的存储数据,进行逻辑判断。 代码逻辑 下面图片是最终的实现效果,当输入标识和密钥,点击发送按钮,成功后将数据自动保存到后台

讲述工作、生活、技术中的日常与感悟。 1672

[EdgeAI] NXP eIQ 机器学习Toolkit (二):模型篇

eIQ™机器学习(ML)软件开发环境支持在恩智浦EdgeVerse™微控制器和微处理器(包括i.MX RT跨界MCU和i.MX系列应用处理器)上使用ML算法。eIQ ML软件包括称为eIQ Toolkit的ML工作流工具以及推理引擎、神经网络编译器和优化库。......

HowieXue 薛永浩的博客 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Android EditText+ListPopupWindow实现可编辑的下拉列表

2.生成下拉数据(这里的数据可换成真实的数据库数据),监听文本变化。属性,EditText可以添加上下左右图片资源,我们添加右边即可。里面的图片可直接再阿里巴巴图标库搜索"上拉"、"下拉"即可。下箭头item_icon_down.xml。方法的参数分别是设置左、上、右、下位置。上箭头item_icon_up.xml。

D_AKJS 1534

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

安卓 带下拉选的输入框,适用于安卓5.0,使用AndroidX

一、介绍 带下拉选的输入框,适用于安卓5.0,使用AndroidX 二、工程引入工具包准备 com.android.tools.build:gradle:4.2.2及以下版本,在工程的 build.gradle 文件添加 allprojects { repositories { google() mavenCentral() //jitpack 仓库 maven { url 'https://jitpack.io' } } }

智识家园的博客 1665

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Android开发丶实现一个可以输入可以下拉选择的EditText输入框

接到个需求,登录界面需要做一个显示历史登录账号的功能,即用户名输入框即可以手动输入,也可以通过展示的下拉框从而选择以往登录的账号,呃,有点拗口?效果大概就是这样的 如图所示,我们点击文本输入框时,就可以显示一个底部列表,这块我们也可以根据项目实际需求把列表放在一个dialog弹窗里,此时既可以手动输入也可以点击列表,点击列表后,列表会自动消失,当下次输入时,它又会显示出来。 下面说下实现步骤: 1.首先在xml文件里,放一个EditText和listview。 activity_main.xml

u014078990的博客 4715

EditText既可以输入编辑也可以下拉选择 EditText +ListPopupWindow

1、效果展示 2、布局文件 &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt; &amp;lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; xmlns:app=&quot

Venus 的博客 7576

自定义EditText自设样式并带有下拉选择框的实现

先上一张效果图: 在drawable目录下建一个xml: <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape xmlns:android="http://schemas.android.com/apk/res/android"

jinyu_mobao的博客 824

安卓可输入可选择的下拉框

先看代码 public class EditableSpinner extends LinearLayout implements AdapterView.OnItemClickListener { private LinearLayout linearLayout; private EditText inputText; private ListPopupWindow popupWindow; private ArrayAda

silencefly的博客 1668

android edittext 下拉菜单,DropEditText

DropEditText一款可以在android上实现类似windows上的下拉效果的组件,并且可以实现文本输入。效果演示:使用方法:在布局文件配置:android:id="@+id/drop_edit"android:layout_width="200dip"android:layout_height="wrap_content"drop:drawableRight="@drawable/dro...

weixin_28730037的博客 455

自定义控件>带下拉框的文本框 (DropEditView)

package xxx.view; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.inputmethodservice.Keyboard; import android.text.TextW

baidu_28177841的博客 882
上一篇: Android仿QQ聊天记录待定与删除功能效果
下一篇: Android 设置EditText光标Curso颜色及粗细
潘建成
博客等级 码龄12年 139粉丝 120原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值