Android(Java)实现贴合Mockup样式的完全向下展开AutoCompleteTextView下拉菜单
Android(Java)实现贴合Mockup样式的完全向下展开AutoCompleteTextView下拉菜单
嘿,我来帮你搞定这个符合Mockup要求的下拉菜单,一步步来实现:
一、布局文件设置(带右侧向下箭头)
首先在你的布局XML里,我们把AutoCompleteTextView和下拉列表放在同一个线性布局里,默认隐藏列表,这样展开时能自然推挤下方视图:
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 带箭头的下拉输入框 --> <AutoCompleteTextView android:id="@+id/app_dropdown" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="选择应用" android:drawableRight="@drawable/ic_down_arrow" <!-- 替换成你的向下箭头图标 --> android:padding="16dp" android:background="@drawable/edittext_border" <!-- 可选:给输入框加边框贴合Mockup --> android:clickable="true"/> <!-- 下拉列表,默认隐藏 --> <ListView android:id="@+id/app_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone" android:background="#ffffff"/> </LinearLayout>
二、核心逻辑实现(推挤视图+应用列表)
系统默认的AutoCompleteTextView下拉是悬浮的,没法推挤视图,所以我们用内嵌列表的方式,点击输入框时切换列表显示状态,同时处理应用名称的获取与选择逻辑:
public class MainActivity extends AppCompatActivity { private AutoCompleteTextView appDropdown; private ListView appList; private ArrayAdapter<String> adapter; private List<String> appNamesList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); appDropdown = findViewById(R.id.app_dropdown); appList = findViewById(R.id.app_list); // 1. 获取手机已安装的第三方应用名称 appNamesList = getInstalledThirdPartyApps(); // 2. 给列表设置适配器 adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, appNamesList); appList.setAdapter(adapter); // 3. 点击输入框切换列表显示/隐藏 appDropdown.setOnClickListener(v -> { if (appList.getVisibility() == View.GONE) { appList.setVisibility(View.VISIBLE); // 可选:把箭头切换成向上,交互更直观 appDropdown.setCompoundDrawablesWithIntrinsicBounds(null, null, getDrawable(R.drawable.ic_up_arrow), null); } else { appList.setVisibility(View.GONE); appDropdown.setCompoundDrawablesWithIntrinsicBounds(null, null, getDrawable(R.drawable.ic_down_arrow), null); } }); // 4. 选择列表项后填充输入框并收起列表 appList.setOnItemClickListener((parent, view, position, id) -> { String selectedApp = appNamesList.get(position); appDropdown.setText(selectedApp); appList.setVisibility(View.GONE); appDropdown.setCompoundDrawablesWithIntrinsicBounds(null, null, getDrawable(R.drawable.ic_down_arrow), null); }); // 5. 让右侧箭头也能触发下拉(可选优化) appDropdown.setOnTouchListener((v, event) -> { final int DRAWABLE_RIGHT = 2; if (event.getAction() == MotionEvent.ACTION_UP) { if (event.getRawX() >= (appDropdown.getRight() - appDropdown.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) { appDropdown.performClick(); return true; } } return false; }); } // 过滤获取第三方应用名称的方法 private List<String> getInstalledThirdPartyApps() { List<String> appNames = new ArrayList<>(); PackageManager pm = getPackageManager(); List<ApplicationInfo> apps = pm.getInstalledApplications(0); for (ApplicationInfo app : apps) { // 跳过系统应用,只显示用户安装的应用 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { appNames.add(app.loadLabel(pm).toString()); } } return appNames; } }
三、适配滚动布局
如果页面内容较多,直接把整个布局嵌套进NestedScrollView(推荐支持嵌套滚动)或者ScrollView即可:
<androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 你的下拉菜单组件 --> <!-- 其他页面视图 --> </LinearLayout> </androidx.core.widget.NestedScrollView>
小优化建议
- 要是觉得ListView不够灵活,可以换成RecyclerView,自定义列表项样式更贴合Mockup;
- 给列表项添加点击动画,提升交互体验;
- 如果需要多个这类下拉菜单,建议把逻辑封装成自定义View,方便复用。
备注:内容来源于stack exchange,提问作者Long96
相关产品推荐
相关产品推荐

