Внутренняя обивка Spinner больше на Android 6.0.1

Вступление:

Похоже, что в новой версии Android 6.0.1 Android внес некоторые изменения в компонент Spinner, потому что по умолчанию внутренний отступ вокруг нижней морковки немного больше.

Я заметил это в приложении, в котором я ничего не изменил в коде, а просто обновил ОС на устройстве, и при этом счетчики имеют разные размеры.

Ситуация:

У меня есть 2 блесны один рядом с другим в RelativeLayout(обратите внимание на остальные компоненты, я добавил все, чтобы вы могли видеть эту часть макета - убрал совершенно ненужные свойства или просмотр идентификаторов)

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

вышеописанное:

Скриншот состоит из двух отдельных снимков экрана:

  1. Тот, что сверху, сделан на устройстве Nexus 5, работающем на Android 6.0.
  2. Приведенный ниже также сделан на устройстве Nexus 5, НО работает на Android 6.0.1

Скриншот

  • РЕДАКТИРОВАТЬ 1

Использование AppCompatSpinner из библиотеки поддержки не меняет поведение. Используемая версия библиотеки поддержки 23.1.1

2 ответа

Решение

С минимальными усилиями я смог это исправить, создав собственный фон для блесны.

С помощью AppCompatSpinner Я должен был создать 2 xmls для фона, давайте назовем это 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 это 9-патч 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>

куда ic_spinner_caret вектор, используемый из исходного кода Android, выглядит следующим образом. Вы должны добавить и добавить это к вашему 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>

Кредиты идут в alanv из инструментария пользовательского интерфейса Android для руководства!

У меня была та же проблема, и я планировал откатить обновление 6.0.1 только для v23.

===

  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.xml под values каталог с записью

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

так как легче определить другой общий стиль, чем другие XML-файлы макета, и ваш проект должен иметь общий styles.xml под values каталог в любом случае, верно?:)

  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>

Теперь этот файл вы можете настроить. Я внес изменения в этот файл для настройки положения каретки:
множество layer-list "s android:paddingEnd равно 0dp
б) наполовину первый предмет android:width в 24dp
в) убрал второй предмет android:end атрибут

Изменения сделали фон более тонким, зачищая его стороны, но подход сохранил волновые эффекты. Не стесняйтесь поиграть со своими собственными значениями, если это необходимо.

  1. Изменения, приведенные выше, не будут компилироваться, так как необходимо ввести больше файлов, так как они будут ссылаться на файлы выше.

Скачать в drawable-v23 (см. ссылку выше):
а) control_background_40dp_material.xml
б) ic_spinner_caret.xml

Скачать в color-v23:
а) control_highlight_material.xml с https://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.

Другие вопросы по тегам