18

介绍:

随着 Android 6.0.1 的新版本,Android 似乎对 Spinner 组件进行了一些更改,因为默认情况下,向下胡萝卜周围的内部填充有点大。

我在一个应用程序上注意到了这一点,我没有修改代码中的任何内容,只是简单地更新了设备上的操作系统,但微调器的大小不同。

情况:

我有 2 个微调器,一个挨着一个RelativeLayout(注意其余的组件,我添加了所有内容,以便您可以看到这部分布局 - 删除了完全不必要的属性或视图 ID)

<RelativeLayout
    android:id="@+id/header"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:id="@+id/container_for_buttons_on_the_right"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true">

        <!-- Buttons here-->
    </LinearLayout>

    <android.support.v7.widget.AppCompatSpinner
        android:id="@+id/spinner_1"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <ViewSwitcher
        android:id="@+id/spinner_switch"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_toEndOf="@id/spinner_1"
        android:layout_toLeftOf="@id/container_for_buttons_on_the_right"
        android:layout_toRightOf="@id/spinner_1"
        android:layout_toStartOf="@id/container_for_buttons_on_the_right"
        android:inAnimation="@anim/fade_in"
        android:outAnimation="@anim/fade_out">

        <android.support.v7.widget.AppCompatSpinner
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <!-- ImageView properties are incomplete but I need it there.-->
    </ViewSwitcher>
</RelativeLayout>

Spinner 适配器用于该getView()方法的布局是这样的:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:orientation="horizontal"
    android:paddingLeft="8dp"
    android:paddingRight="8dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:ellipsize="end"
        android:gravity="center_vertical"
        android:singleLine="true"
        tools:text="Test" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="0"
        android:gravity="center"
        android:paddingLeft="4dp"
        android:singleLine="true"
        android:textColor="@color/text_primary"
        android:textSize="@dimen/text_size_body"
        tools:ignore="RtlHardcoded,RtlSymmetry"
        tools:text="7%" />
</LinearLayout>

举例:

该屏幕截图由 2 个单独的屏幕截图组合而成:

  1. 上图是在运行Android 6.0的Nexus 5设备上拍摄的
  2. 下面的一个也是在运行Android 6.0.1的Nexus 5设备上拍摄的

截屏

  • 编辑 1

使用支持库中的 AppCompatSpinner 不会改变行为。使用的支持库版本是23.1.1

4

2 回答 2

7

通过为微调器构建自定义背景,我能够以最小的努力解决这个问题。

使用AppCompatSpinner我必须为背景创建 2 个 xml,我们称之为spinner_background.xml

1.第一个进入drawable文件夹,看起来像这样,spinner_background.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:opacity="transparent">
    <item
        android:width="24dp"
        android:height="24dp"
        android:drawable="@drawable/selector_background_borderless"
        android:gravity="end|center_vertical" />
    <item android:drawable="@drawable/bg_spinner_anchor" />
</layer-list>

普通选择器在哪里selector_background_borderless(我添加了您需要的最少项目,您可以探索它是 v21+ 的涟漪替代方案。事实上,我建议您这样做):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="#19000000" android:state_pressed="true" />
    <item android:drawable="@android:color/transparent" />
</selector>

并且bg_spinner_anchor是插入符号的 9patch PNG。我使用了这些资产:bg_spinner_anchor

2.第二个去drawable-v23文件夹正确支持波纹,看起来像这样,spinner_background.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:paddingEnd="16dp"
    android:paddingLeft="0dp"
    android:paddingMode="stack"
    android:paddingRight="0dp"
    android:paddingStart="0dp">
    <item
        android:width="24dp"
        android:height="24dp"
        android:drawable="@drawable/selector_background_borderless"
        android:gravity="end|center_vertical" />

    <item
        android:width="24dp"
        android:height="24dp"
        android:drawable="@drawable/ic_spinner_caret"
        android:gravity="end|center_vertical" />
</layer-list>

从 Android 源代码中使用的向量在哪里ic_spinner_caret,看起来像这样。您还应该将其添加到您的drawable-v23文件夹中:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0"
    android:tint="?attr/colorControlNormal">
    <path
        android:pathData="M7,10l5,5,5-5z"
        android:fillColor="#524e4a"/>
</vector>

积分来自 Android UI 工具包的指导alanv !

于 2015-12-21T22:40:58.650 回答
4

我遇到了同样的问题,我的计划是仅回滚v23 的 6.0.1 更新。

  1. 确保你Spinner有一个附加的风格。例如样式命名如下Widget.Spinner例所示:
<Spinner
    android:id="@+id/spinner_1"
    style="@style/Widget.Spinner"
    android:layout_width="64dp"
    android:layout_height="64dp"/>
  1. styles.xml在目录下创建(如果不存在)values-v23(更改将仅应用于 API v23)。例如,请参见Widget.Spinner下面的样式定义示例:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Widget.Spinner" parent="Widget.AppCompat.Spinner">
        <item name="android:background">@drawable/spinner_background_material</item>
    </style>
</resources>

样式的父级是Widget.AppCompat.Spinner,它android:background用我们将从 6.0.1 源回滚的那个重新定义它。

请注意,如果您也针对其他版本,则需要styles.xmlvalues目录下添加默认条目

<style name="Widget.Spinner" parent="Widget.AppCompat.Spinner"/>

因为定义另一种通用样式而不是不同的布局 xml 文件更容易,并且您的项目无论如何都应该有一个通用styles.xmlvalues目录,对吗?:)

  1. spinner_background_material.xml从 https://android.googlesource.com/platform/frameworks/base.git/+/android-6.0.1_r3/core/res/res/drawable/引入。再次保存它drawable-v23,我们将确保我们只更改 API v23。

文件的默认内容是:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:paddingMode="stack"
    android:paddingStart="0dp"
    android:paddingEnd="48dp"
    android:paddingLeft="0dp"
    android:paddingRight="0dp">

    <item
        android:gravity="end|fill_vertical"
        android:width="48dp"
        android:drawable="@drawable/control_background_40dp_material" />

    <item
        android:drawable="@drawable/ic_spinner_caret"
        android:gravity="end|center_vertical"
        android:width="24dp"
        android:height="24dp"
        android:end="12dp" />
</layer-list>

现在,这是您可能想要调整的文件。我对此文件进行了更改以调整插入符号的位置:
a) set等于b)将第一项layer-list的 减半 c) 删除了第二项的属性android:paddingEnd0dp
android:width24dp
android:end

这些变化通过剥离它的侧面使背景变薄,但这种方法保留了涟漪效应。如果需要,请随意使用您自己的自定义值。

  1. 上面的更改不会编译,因为需要引入更多文件,因为它们将由上面的文件引用。

下载到drawable-v23(见上面的链接):
a)control_background_40dp_material.xml
b)ic_spinner_caret.xml

下载到color-v23
a)control_highlight_material.xmlhttps://android.googlesource.com/platform/frameworks/base.git/+/android-6.0.1_r3/core/res/res/color/(这个文件也可能驻留在下面drawable-v23,但是现在让我们遵循原始源位置的模式)。请注意,该文件@dimen/highlight_alpha_material_colored是从 中提取的appcompat-v7,如果您使用一个 :) 如果没有,您可以从中引用它的值:

<item format="float" name="highlight_alpha_material_colored" type="dimen">0.26</item>

该解决方案不是最好的,因为您需要带入您最初不拥有的文件。此外,您可能希望监视对 v23 的可能更新以了解未来的任何更改。但至少这些更改仅包含在 v23 中。

于 2016-01-04T12:03:33.080 回答