自定义纺纱'间距 [英] Customizing spinners' spacing

查看:312
本文介绍了自定义纺纱'间距的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

纱厂提供两种状态。第一,默认状态(的状态A 的)显示当前选择的值。第二(的状态B 的)显示时微调显示触摸下拉菜单。

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

由于填充设置为与中创建微调时指定的布局中使用的 CheckedTextView 的,我的第一次尝试是传递给微调构造一个包含CheckedTextView空自定义布局填充。这样,在状态A,而且在状态B.左填充在前看不见不过,我的目标是保持了状态的。

我的第二次​​尝试是可以自定义的的android:dropDownSpinnerStyle 的在我的主题定义。由于改变背景颜色的的android:dropDownSpinnerStyle 的改变状态的唯一,我的想法是要覆盖marginLeft或paddingLeft与负值的项目的背景颜色。不幸的是,它没有任何效果。

由于阴性切缘/填充似乎并没有被考虑到了,我已经试过相反。首先,我使用了一个自定义项目布局(作为我的第一次尝试解释),以消除对两种状态(A和B)左填充。其次,我已经定义属性的 Android的自定义样式:dropDownListViewStyle 的。不幸的是,使用正marginLeft值与最后属性不起作用。因此,我已经设置paddingLeft。它的工作原理,让我得到了唯一的国家B中的左间距。然而,在左侧空间也适用于背景触摸颜色(参见下面图)。

我想,如果我想有触摸背景颜色,充分填充的下拉菜单宽度仅为状态的样式会被改变。任何想法,建议或示例的欢迎。

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

 <样式名称=Theme.App.Base父=Theme.App>
    ...
    <项目名称=机器人:dropDownListViewStyle> @风格/ Widget.Spinner.DropDown.ListView< /项目>
< /风格><样式名称=Widget.Spinner.DropDown.ListView父=Widget.AppCompat.ListView.DropDown>
    <项目名称=机器人:paddingLeft>&16DP LT; /项目>
< /风格>


解决方案

A国发生在以下样式:

  //主题(基地)// Theme.AppCompat
@android:款式/ Widget.TextView.SpinnerItem//霍洛&安培;全息光
@android:款式/ Widget.Holo.TextView.SpinnerItem

在这里打球的属性是 spinnerItemStyle

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

如果您使用的应用程序兼容性,你仍然会覆盖 spinnerItemStyle 属性,但提供 paddingLeft paddingRight

例如:

 <样式名称=Theme.App.Base父=Theme.App>
...
    <项目名称=机器人:spinnerItemStyle> @风格/ TextViewSpinnerItem< /项目>
< /风格><样式名称=TextViewSpinnerItem父=@安卓风格/ Widget.TextView.SpinnerItem>
    <项目名称=机器人:paddingLeft> 40dp< /项目>
    <项目名称=机器人:paddingRight> 40dp< /项目>
< /风格>

40dp 的值是测试如果设置这种风格甚至可以。这只应该垫国家A (带40dp),离开 B国的默认填充8DP 。一旦确认,你可以把它 0dp ,或者按您的要求。

这是结果我得到:

更新:

在参考示例项目 - MainActivity

  spinner.setAdapter(ArrayAdapter.createFromResource(这一点,
            R.array.planets_array,android.R.layout.simple_spinner_item));

通过给适配器 android.R.layout.simple_spinner_item ,你告诉它使用布局的两个的国家A和B国这是因为这种布局被定义的方式有问题:

 < TextView中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:ID =@机器人:ID / text1中
    风格=机器人:ATTR / spinnerItemStyle
    机器人:单线=真
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:ellipsize =金字招牌
    机器人:textAlignment =继承/>

注意风格适用于这一的TextView 。此前,我曾建议你重写此属性。和它的工作。但由于这种布局被用于这两种状态,其结果是不理想的。

事实上,语句正上方(虽然目前没有做任何事情)是更有前途:

  ArrayAdapter.createFromResource(这一点,
            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 psented重新$ P $和B国将使用 android.R.layout .simple_spinner_dropdown_item

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

 < CheckedTextView的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:ID =@机器人:ID / text1中
    风格=机器人:ATTR / spinnerDropDownItemStyle
    机器人:单线=真
    机器人:layout_width =match_parent
    机器人:layout_height =机器人:ATTR / DROPDOWNLIST preferredItemHeight
    机器人:ellipsize =金字招牌/>

现在我们可以覆盖另一个属性 - spinnerDropDownItemStyle - 并给B国的整体不同的外观。但是,我们不会。在棒棒糖, spinnerDropDownItemStyle 指向风格 Widget.Material.DropDownItem.Spinner 这台 paddingX 8DP 。你说你没事,在B国

默认填充

所以,在这里就是你需要:

  //创建一个ArrayAdapter
ArrayAdapter<&CharSequence的GT; mAdapter = ArrayAdapter.createFromResource(这一点,
            R.array.planets_array,android.R.layout.simple_spinner_item);// B国
mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

和,如果你没有这个已经,将其添加到价值观/ styles.xml:

 <样式名称=AppTheme父=Theme.AppCompat.Light.DarkActionBar>
    <项目名称=机器人:spinnerItemStyle> @风格/ TextViewSpinnerItem< /项目>
< /风格><样式名称=TextViewSpinnerItem父=@安卓风格/ Widget.TextView.SpinnerItem>
    <项目名称=机器人:paddingLeft> 0dp< /项目>
    <项目名称=机器人:paddingRight> 0dp< /项目>
< /风格>

您还应该创建值-V21 / styles.xml 并添加:

 <样式名称=TextViewSpinnerItem父=@安卓风格/ Widget.Material.TextView.SpinnerItem>
    <项目名称=机器人:paddingLeft> 0dp< /项目>
    <项目名称=机器人:paddingRight> 0dp< /项目>
< /风格>

Spinners provide two states. The first and default state (state A) shows the currently selected value. The second (state B) shows a dropdown menu when the spinner display is touched.

By default a left padding is added to the items displayed in state A and B. I would like to remove it when the current selected value is displayed (state A) but to keep it when items are displayed in the dropdown menu (state B).

Since the padding is set with the CheckedTextView used in the layout that is specified when the spinner is created, my first try was to pass to the spinner constructor a custom layout that contains a CheckedTextView with empty padding. This way, the left padding disapears in state A but also in state B. However, my goal was to keep it for state A.

My second try was to customize android:dropDownSpinnerStyle in my theme definition. Since changing background color for android:dropDownSpinnerStyle changes the background color of the item in state A only, my thought was to override the marginLeft or paddingLeft with a negative value. Unfortunately, it has no effect.

Given that negative margin/padding seems not to be taken into account, I have tried the opposite. Firstly, I have used a custom item layout (as explained for my first try) in order to remove left padding on both states (A and B). Secondly, I have defined a custom style for property android:dropDownListViewStyle. Unfortunately, using a positive marginLeft value with the last property has no effect. Thus, I have set paddingLeft. It works and allows me to get the left spacing for state B only. However, the left space applies also to the background touch color (cf. image below).

I think that only the style for state A should be altered if I want to have the on touch background color that fully fills the dropdown menu width. Any idea, suggestion or example is welcomed.

Below is my theme definition for the third try:

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

解决方案

State A takes on the following style:

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

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

The attribute at play here is spinnerItemStyle.

Moreover, the padding provided is not paddingLeft, but paddingStart - to support LTR & RTL languages. Similarly, paddingEnd is set instead of paddingRight. This info applies to API >=17.

If you are using AppCompat, you will still override the spinnerItemStyle attribute, but provide paddingLeft and paddingRight.

Example:

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

The 40dp value is for testing if setting this style even works. This should only pad State A(with 40dp), leaving State B with default padding of 8dp. Once confirmed, you can make it 0dp, or as per your requirement.

This is the result I get:

Update:

In reference to the sample project - MainActivity:

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

By giving the adapter android.R.layout.simple_spinner_item, you are telling it to use the layout for both State A and State B. This is a problem because of the way this layout is defined:

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

Notice the style applied to this TextView. Earlier, I had suggested that you override this attribute. And it worked. But since this layout is used for both the states, the outcome is not as desired.

In fact, the statement right above (though not doing anything at the moment) is more promising:

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

By using setDropDownViewResource(int), you will allow the possibility of introducing different style attributes. In this case, State A will be represented by android.R.layout.simple_spinner_item and State B will use android.R.layout.simple_spinner_dropdown_item.

Let's take a look at 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"/>

Now we can override another attribute - spinnerDropDownItemStyle - and give State B a whole different look. But, we won't. On Lollipop, spinnerDropDownItemStyle points to style Widget.Material.DropDownItem.Spinner which sets the paddingX to 8dp. And you said that you're okay with the default padding in State B.

So, here's what you need:

// 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);

AND, if you don't have this already, add it to 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>

You should also create values-v21/styles.xml and add:

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

这篇关于自定义纺纱'间距的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆