17

Intro:Spinner imbottitura interna è più grande su Android 6.0.1

Con la nuova versione di Android 6.0.1, sembra che Android ha fatto alcuni cambiamenti sulla componente Spinner perché per impostazione predefinita, l'imbottitura interna in tutto il la carota in giù è un po 'più grande.

Ho notato questo in un'app in cui non ho modificato nulla nel codice, ma ho semplicemente aggiornato il sistema operativo sul dispositivo e tuttavia i pennini hanno dimensioni diverse.

Situazione:

Ho 2 filatori uno accanto all'altro in un RelativeLayout (mente il resto dei componenti, ho aggiunto tutto in modo da poter vedere questa parte del layout - rimosso le proprietà del tutto inutile o visualizzare ids)

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

il layout utilizzato dall'adattatore Spinner per il metodo getView() è questo:

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

esemplificato:

La schermata è combinata di 2 screenshots separati adottate:

  1. Quello in alto è fatta in un 5 dispositivo Nexus esecuzione su Android 6.0
  2. L' uno di seguito è anche preso su un dispositivo Nexus 5 MA in esecuzione su Android 6.0.1

screenshot

  • EDIT 1

Utilizzando AppCompatSpinner dalla libreria di supporto non cambia il comportamento. La versione della libreria di supporto utilizzata è 23.1.1

+0

Abbiamo dovuto aggiungere più padding attorno al cursore in basso per evitare un bug durante la visualizzazione dell'effetto di ripple. Se hai bisogno di una dimensione costante, copia lo sfondo fuori dal framework e usalo oppure usa AppCompat. – alanv

+0

Uso AppCompat :). Potresti dirmi qual è la dimensione esatta di quella imbottitura? Mi sembra che siano circa 8 o 10? – Mike

+0

E '12dp di fine padding e un gap costante di 48dp in coda, che è in effetti 12dp di start padding. Puoi controllare direttamente nella directory di Android SDK sotto 'piattaforme/android-23/data/res/drawable/spinner_background_material.xml'. – alanv

risposta

7

Con il minimo sforzo sono riuscito a risolvere questo problema costruendo uno sfondo personalizzato per lo spinner.

Utilizzando AppCompatSpinner ho dovuto creare 2 XMLs per lo sfondo, chiamiamo questo spinner_background.xml:

1. Prima si va alla cartella drawable e si presenta così, 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> 

Dove selector_background_borderless è un semplice selettore come (ho aggiunto gli elementi minimi di cui hai bisogno, potresti esplorare la sua alternativa a ondulazione per la v21 +.In realtà io vi consiglierei di farlo):

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

E bg_spinner_anchor è un 9patch PNG per il cursore. Ho usato queste risorse: bg_spinner_anchor

2. Il secondo va alla cartella drawable-v23 per supportare adeguatamente ripple e si presenta così, 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> 

Dove ic_spinner_caret è un vettore utilizzato dalla sorgente di Android codice simile a questo. Si dovrebbe aggiungere anche aggiungere questo alla cartella 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> 

crediti vanno a alanv dal toolkit UI Android di orientamento!

+1

Il collegamento per 'bg_spinner_assets' sta reindirizzando per scaricare il file mp3' Backstreet_Boys'. Puoi per favore guardare in questo? Grazie –

+0

Fammi sapere se il mio collegamento github funziona. – Mike

+0

Il link funziona ora. Grazie. –

3

Ho avuto lo stesso problema e il mio piano era di rollback l'aggiornamento 6.0.1 solo per v23.

===

  1. Assicurarsi che il Spinner ha uno stile collegato ad esso. Per esempio stile denominato come Widget.Spinner nell'esempio qui sotto:
<Spinner 
    android:id="@+id/spinner_1" 
    style="@style/Widget.Spinner" 
    android:layout_width="64dp" 
    android:layout_height="64dp"/> 
  1. Crea (se già non esiste) styles.xml sotto values-v23 directory (ad verranno applicate modifiche solo V23 API). Ad esempio, vedi definizione esempio Widget.Spinner stile di seguito: genitore
<?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> 

del stile è Widget.AppCompat.Spinner e ridefinisce è android:background con quello saremo rollback da 6.0.1 fonte.

nota, che se ci si rivolge anche altre versioni, è necessario aggiungere un valore predefinito styles.xml sotto values directory con ingresso

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

perché è più facile definire un altro stile generico piuttosto che diversi layout di xml i file e il tuo progetto dovrebbero avere un generico styles.xml nella directory values in ogni caso, giusto? :)

  1. Immettere spinner_background_material.xml da https://android.googlesource.com/platform/frameworks/base.git/+/android-6.0.1_r3/core/res/res/drawable/. Salvalo sotto drawable-v23 per di nuovo, ci assicureremo solo che stiamo cambiando solo API v23. contenuto predefinito

del file è:

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

Ora, questo è il file che si potrebbe desiderare di modificare.Ho fatto modifiche a questo file sia per ottimizzare la posizione del cursore:
a) prevedono layer-list s' android:paddingEnd uguale 0dp
b) dimezzata primo elemento android:width per 24dp
c) rimosso attributo del secondo elemento android:end

L' le modifiche rendevano il fondo più sottile, spogliandone i lati ma l'approccio manteneva gli effetti a catena. Sentiti libero di giocare con i tuoi valori personalizzati, se necessario.

  1. Le modifiche precedenti non verranno compilate poiché saranno necessari più file per essere richiamati dai file sopra.

Scarica in drawable-v23 (vedi link sopra):
a) control_background_40dp_material.xml
b) ic_spinner_caret.xml

Scarica in color-v23:
a) control_highlight_material.xml da https://android.googlesource.com/platform/frameworks/base.git/+/android-6.0.1_r3/core/res/res/color/ (questo file può probabilmente risiedere sotto drawable-v23 anche, ma lascia seguire il modello dei luoghi di origine originali per ora). Si noti, che del file @dimen/highlight_alpha_material_colored viene prelevato dal appcompat-v7, se si utilizza uno :) In caso contrario, è possibile reffer il suo valore da esso:

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

===

La soluzione non è la migliore, come si è necessario portare su file che non si possiedono originariamente. Inoltre, è possibile monitorare i possibili aggiornamenti di v23 per eventuali modifiche future. Ma almeno le modifiche sono contenute solo in v23.

+0

Grazie per la risposta dettagliata. Lavori! –

+0

Grazie per aver postato questo svennu. Mi hai risparmiato un sacco di tempo con la spiegazione utile! – JPM

+0

Al secondo pensiero. Questo non funziona bene su API 24 quando si tenta di nascondere il cursore. – JPM