定制微调器的间距

时间:2014-11-22 12:12:03

标签: android android-layout drop-down-menu android-spinner android-appcompat

Spinners提供两种状态。第一个和默认状态(状态A )显示当前选定的值。第二个(状态B )在触摸微调器显示时显示一个下拉菜单。

State A and B example

默认情况下,左边的填充会添加到状态A和B中显示的项目。我想在显示当前选定的值时将其删除(状态A )但是在项目时保留它显示在下拉菜单中(状态B )。

由于填充是使用创建微调器时指定的布局中使用的 CheckedTextView 设置的,我的第一次尝试是将包含CheckedTextView的自定义布局传递给微调器构造函数填充。这样,左边的填充在状态A中消失,但也在状态B中消失。但是,我的目标是将其保留在状态A中。

我的第二次尝试是在我的主题定义中自定义 android:dropDownSpinnerStyle 。由于更改 android:dropDownSpinnerStyle 的背景颜色仅更改状态A中项目的背景颜色,我的想法是用负值覆盖marginLeft或paddingLeft。不幸的是,它没有效果。

鉴于负边距/填充似乎没有被考虑在内,我尝试了相反的观点。首先,我使用了自定义项目布局(我的第一次尝试解释),以便删除两个状态(A和B)上的左边距填充。其次,我已经为属性 android:dropDownListViewStyle 定义了一个自定义样式。不幸的是,对last last属性使用正的marginLeft值无效。因此,我设置了paddingLeft。它工作,并允许我只获得状态B的左边距。但是,左侧空间也适用于背景触摸颜色(参见下图)。

enter image description here

我认为如果我想要完全填充下拉菜单宽度的触摸背景颜色,则只应更改状态A的样式。任何想法,建议或例子都受到欢迎。

以下是第三次尝试的主题定义:

<style name="Theme.App.Base" parent="Theme.App">
    ...
    <item name="android:dropDownListViewStyle">@style/Widget.Spinner.DropDown.ListView</item>
</style>

<style name="Widget.Spinner.DropDown.ListView" parent="Widget.AppCompat.ListView.DropDown">
    <item name="android:paddingLeft">16dp</item>
</style>

1 个答案:

答案 0 :(得分:31)

状态A采用以下风格:

// Theme (Base) // Theme.AppCompat
@android:style/Widget.TextView.SpinnerItem

// Holo & Holo Light
@android:style/Widget.Holo.TextView.SpinnerItem

此处播放的属性为spinnerItemStyle

此外,提供的填充 paddingLeft,但paddingStart - 支持LTR&amp; RTL语言。同样,设置paddingEnd而不是paddingRight。此信息适用于API&gt; = 17。

如果您使用的是AppCompat,您仍会覆盖spinnerItemStyle属性,但会提供paddingLeftpaddingRight

示例:

<style name="Theme.App.Base" parent="Theme.App">
...
    <item name="android:spinnerItemStyle">@style/TextViewSpinnerItem</item>
</style>

<style name="TextViewSpinnerItem" parent="@android:style/Widget.TextView.SpinnerItem">
    <item name="android:paddingLeft">40dp</item>
    <item name="android:paddingRight">40dp</item>
</style>

40dp值用于测试设置此样式是否有效。这应该只填充State A(40dp),State B的默认填充为8dp。确认后,您可以0dp或根据您的要求进行确认。

这是我得到的结果:

enter image description here

<强>更新

参考示例项目 - MainActivity

spinner.setAdapter(ArrayAdapter.createFromResource(this,
            R.array.planets_array, android.R.layout.simple_spinner_item));

通过提供适配器android.R.layout.simple_spinner_item,您告诉它使用两者状态A和状态B的布局。这是一个问题,因为定义了这种布局:< / p>

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/text1"
    style="?android:attr/spinnerItemStyle"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:textAlignment="inherit"/>

请注意style已应用于此TextView。之前,我曾建议您覆盖此属性。它奏效了。但由于这种布局用于两种状态,因此结果并不理想。

事实上,上面的声明(尽管目前没有做任何事情)更有希望:

ArrayAdapter.createFromResource(this,
            R.array.planets_array, android.R.layout.simple_spinner_item)
            .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

通过使用setDropDownViewResource(int),您可以引入不同的样式属性。在这种情况下,状态A将由android.R.layout.simple_spinner_item表示,状态B将使用android.R.layout.simple_spinner_dropdown_item

让我们来看看android.R.layout.simple_spinner_dropdown_item

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerDropDownItemStyle"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/dropdownListPreferredItemHeight"
    android:ellipsize="marquee"/>

现在我们可以覆盖另一个属性 - spinnerDropDownItemStyle - 并给状态B一个完全不同的外观。但是,我们没赢。在棒棒糖上,spinnerDropDownItemStyle指向样式Widget.Material.DropDownItem.Spinner,将paddingX设置为8dp。并且你说你在状态B中使用默认填充是可以的。

所以,这就是你需要的:

// Create an ArrayAdapter
ArrayAdapter<CharSequence> mAdapter = ArrayAdapter.createFromResource(this,
            R.array.planets_array, android.R.layout.simple_spinner_item);

// State B
mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

并且,如果您还没有,请将其添加到values / styles.xml:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:spinnerItemStyle">@style/TextViewSpinnerItem</item>
</style>

<style name="TextViewSpinnerItem" parent="@android:style/Widget.TextView.SpinnerItem">
    <item name="android:paddingLeft">0dp</item>
    <item name="android:paddingRight">0dp</item>
</style>

您还应创建values-v21/styles.xml并添加:

<style name="TextViewSpinnerItem" parent="@android:style/Widget.Material.TextView.SpinnerItem">
    <item name="android:paddingLeft">0dp</item>
    <item name="android:paddingRight">0dp</item>
</style>