在安卓系统上创建和设计下拉菜单
7月26日- 5分钟阅读
我最近不得不为我的应用程序实现一个定制的下拉菜单,我花了很长时间来弄清楚什么是风格,以及如何正确地实现它,以达到我想要的外观和感觉。所以,在这篇文章中,我将介绍如何使用TextInputLayout和AutoCompleteTextView来定制一个暴露的下拉菜单。我们将从这里开始。
略微定制的外露式下拉菜单
到这个。
最终的外露式下拉菜单
什么是暴露的下拉菜单?
外露式下拉菜单在选项列表的上方显示当前选择的菜单项。有些变化可以接受用户输入的信息。在安卓系统中,这个功能可以用一个TextInputLayout
和一个嵌套的AutocompleteTextView
来实现,它们都是安卓系统材料库的组成部分。让我们把这个库导入我们的项目中。
implementation ‘com.google.android.material:material:1.4.0’
我还将在本教程中使用ViewBinding ,所以请确保你在模块的build.gradle中通过添加以下内容启用它。
android { ... buildFeatures { viewBinding true }}
设计基本布局
让我们首先声明一个材料暴露的下拉菜单的基本布局。
<com.google.android.material.textfield.TextInputLayout android:id="@+id/dateFilterContainer" style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="@string/label"> <AutoCompleteTextView android:id="@+id/datesFilterSpinner" android:layout_width="match_parent" android:layout_height="match_parent" android:inputType="none" tools:text="All Time"" /></com.google.android.material.textfield.TextInputLayout>
在这里,我们只是添加一个TextInputLayout
,其中包含一个AutoCompleteTextView
,它将作为我们的下拉菜单。请注意inputType="none"
,因为它告诉AutoCompleteTextView我们不打算用手输入任何文本细节。这与我们分配给TextInputLayout的自定义样式相结合,将允许AutoCompleteTextView在点击时像一个旋转器一样运作。
要了解更多关于各种可用的样式和自定义选项,请看Google的Menus - Material Design文档。
赋予我们的下拉菜单一个更多的自定义外观
让我们从我们将用于下拉菜单背景的颜色开始。
<color name="pastel_orange_light">#FBE8DF</color>
接下来,我们要创建一个新的filter_spinner_dropdown_bg.xml
,并使用以下代码来塑造它。
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/pastel_orange_light" /> <corners android:radius="20dp" /></shape>
我们最后需要的是一个下拉图标,它将被放置在TextInputLayout的末端。我使用了免费的羽毛图标包中的下拉箭头。好了,现在我们有了所有的资源,让我们进一步设计我们的下拉菜单。
首先,我们要把TextInputLayout的background
设置为我们先前创建的drawable。
接下来,我们要通过改变各个角的radius
,使放置在TextInputLayout周围的盒子的角变圆(由于我们选择的样式),同时将boxStrokeWidth
和boxStrokeWidthFocused
设置为0dp
,因为我们不希望我们的下拉菜单上有任何轮廓。
此外,让我们使用endIconDrawable
属性添加我们的自定义下拉箭头图标,并使用endIconTint
将其染成与我们的风格相匹配。
现在我们已经完成了TextInputLayout的样式设计,所以让我们转到AutoCompleteTextView。在这里,我们要设置background="@null"
,这样它就不会和TextInputLayout的背景重叠了。
接下来,我们指定一个dropDownSelector
drawable,在这种情况下,它将是我们先前创建的那个drawable。
DropDownSelector是一个可画的,当你点击一个项目时,它被用来突出显示该项目。
对于我的应用程序,我不希望有任何类似的东西是可见的,所以我只是把它设置为与我们的背景drawable相同。
继续下去,添加以下几行将简单地把文本限制在一行,以便一切看起来都是一致的,当文本太长时,省略号(...
)将被添加在文本的末尾。
android:ellipsize="end"android:maxLines="1"android:singleLine="true"
我们还将在顶部和底部添加一些填充,因为出于某种原因,AutoCompleteTextView在TextInputLayout中的嵌套会导致它与TextInputLayout的边界有一些冲突。
最后,我们要把我们的文本放在中心位置,并对其进行一些样式设计,就这样了。下面是最后的代码。
<com.google.android.material.textfield.TextInputLayout android:id="@+id/typesFilterContainer" style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu" android:layout_width="wrap_content" android:layout_height="40dp" android:background="@drawable/filter_spinner_dropdown_bg" app:boxBackgroundColor="@color/pastel_orange_light" app:boxCornerRadiusBottomEnd="20dp" app:boxCornerRadiusBottomStart="20dp" app:boxCornerRadiusTopEnd="20dp" app:boxCornerRadiusTopStart="20dp" app:boxStrokeWidth="0dp" app:boxStrokeWidthFocused="0dp" app:endIconDrawable="@drawable/ic_arrow_down" app:endIconTint="@color/pastel_orange_txt_highlight"> <AutoCompleteTextView android:id="@+id/typesFilter" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@null" android:fontFamily="@font/lato" android:dropDownSelector="@drawable/filter_spinner_dropdown_bg" android:ellipsize="end" android:inputType="none" android:maxLines="1" android:paddingTop="10dp" android:paddingBottom="10dp" android:singleLine="true" android:text="All Types" android:textAlignment="center" android:textColor="@color/pastel_orange_txt_highlight" tools:ignore="LabelFor" /></com.google.android.material.textfield.TextInputLayout>
你现在应该有一个看起来很像这样的东西。
输出
接下来,让我们看看如何用项目来填充我们的下拉菜单吧
指定下拉项目
为了给我们的菜单设置下拉项,我们需要使用一个ArrayAdapter<>()
,并传入上下文、项目布局和项目的列表。在这种情况下,我们将使用预定义的android.R.layout.simple_spinner_dropdown_item
布局,因为它可以满足我们现在的需要,但你也可以使用一个自定义的布局,并在一个自定义ArrayAdapter子类中进一步定制。让我们看看到目前为止的代码。
val adapter = ArrayAdapter( requireContext(), android.R.layout.simple_spinner_dropdown_item, arraylistOf("All Types", "Assignments", "Exam", "Lab"))binding?.typesFilterSpinner?.setAdapter(adapter)binding?.typesFilterSpinner?.setText("All Types")
很好,现在我们的下拉菜单已经填满了项目,我们需要定义一个自定义的drawable来作为下拉菜单的背景,因为现在将使用默认的白色背景。
使用一个自定义的下拉菜单背景绘图
再一次,我们将利用我们的filter_spinner_dropdown_bg.xml
drawable。简单地在AutoCompleteTextView上调用setDropDownBackgroundDrawable()
,这就可以作为背景了。
binding?.typesFilterSpinner.setDropDownBackgroundDrawable( ResourcesCompat.getDrawable( resources, R.drawable.filter_spinner_dropdown_bg, null ))
好了,我们终于完成了我们的下拉菜单的样式设计。它现在看起来应该是这样的。
最终结果
在最后一部分,我们将看到如何处理项目的点击事件。
处理项目点击事件
为了在下拉项目被点击时得到通知,我们将简单地定义我们自己的AdapterView.OnItemClickListener
,并在我们的AutoCompleteTextView中使用它。
binding?.typesFilterSpinner.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id-> // do something with the available information }
本教程到此结束,你现在应该有一个功能齐全、外观漂亮的下拉菜单/旋转器了。如果你有任何建议、改进或意见,请在评论中告诉我,我会尽我所能将它们纳入。编码愉快!