6

Przy ustawieniu właściwości z tylko wartością MultiSelectListPreference z jej wpisami, wartościami i wartościami domyślnymi w zasobach tablicy, niektóre pola wyboru nie są rysowane jako zaznaczone, mimo że Android wie, że są powinien być sprawdzony. Po kliknięciu niezaznaczonego elementu element pozostaje niezaznaczony (ponieważ Android myśli, że odznacza zaznaczony element).Pola wyboru MultiSelectListPreference nie są zaznaczone, gdy nie są początkowo widoczne na liście (API 23)

Here's a video of this happening

Projekt dostępny tutaj: https://github.com/ImmersibleElf/MSLPBug

Wydaje się działać prawidłowo w API 21 i 22, ale nie w 23. Czy to może być błąd w recyklingu poglądów? Lub co może być przyczyną?

SettingsActivity.java

package com.immersibleelf.mslpbug; 

import android.os.Bundle; 
import android.preference.PreferenceFragment; 
import android.support.v7.app.AppCompatActivity; 

public class SettingsActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Display the fragment as the main content. 
     getFragmentManager().beginTransaction() 
       .replace(android.R.id.content, new SettingsFragment()) 
       .commit(); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
    } 

    public static class SettingsFragment extends PreferenceFragment { 
     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      // Load the settings from an XML resource 
      addPreferencesFromResource(R.xml.settings); 
     } 
    } 
} 

settings.xml

<?xml version="1.0" encoding="utf-8"?> 

<PreferenceScreen 
    xmlns:android="http://schemas.android.com/apk/res/android"> 

     <MultiSelectListPreference 
      android:key="mslp_key" 
      android:title="MultiSelectListPreference" 
      android:entries="@array/mslp_entries" 
      android:entryValues="@array/mslp_entry_values" 
      android:defaultValue="@array/mslp_default_value" 
      android:persistent="true" 
      /> 
</PreferenceScreen> 

arrays.xml

<?xml version="1.0" encoding="utf-8"?> 

<resources> 

    <string-array name="mslp_entries"> 
     <item>Entry 01</item> 
     <item>Entry 02</item> 
     <item>Entry 03</item> 
     <item>Entry 04</item> 
     <item>Entry 05</item> 
     <item>Entry 06</item> 
     <item>Entry 07</item> 
     <item>Entry 08</item> 
     <item>Entry 09</item> 
     <item>Entry 10</item> 
     <item>Entry 11</item> 
     <item>Entry 12</item> 
     <item>Entry 13</item> 
     <item>Entry 14</item> 
     <item>Entry 15</item> 
    </string-array> 

    <string-array name="mslp_entry_values"> 
     <item>1</item> 
     <item>2</item> 
     <item>3</item> 
     <item>4</item> 
     <item>5</item> 
     <item>6</item> 
     <item>7</item> 
     <item>8</item> 
     <item>9</item> 
     <item>10</item> 
     <item>11</item> 
     <item>12</item> 
     <item>13</item> 
     <item>14</item> 
     <item>15</item> 
    </string-array> 

    <string-array name="mslp_default_value"> 
     <item>1</item> 
     <item>2</item> 
     <item>3</item> 
     <item>4</item> 
     <item>5</item> 
     <item>6</item> 
     <item>7</item> 
     <item>8</item> 
     <item>9</item> 
     <item>10</item> 
     <item>11</item> 
     <item>12</item> 
     <item>13</item> 
     <item>14</item> 
     <item>15</item> 
    </string-array> 

</resources> 
+0

myślę jest androidem bug na recyklingu, jeśli masz więcej elementów podczas przewijania odznacz elementu losowo – Xan

+0

mających ten sam problem. Czy znalazłeś więcej informacji lub możliwą poprawkę? – mdiener

+1

@mdiener Ja [zgłosiłem tutaj] (https://code.google.com/p/android/issues/detail?id=205487) ale wyobrażam sobie, że jest to błąd o bardzo niskim priorytecie. Próbowałem go wyśledzić, ale mogłem go śledzić do tej pory na komputerach z Windows w czasie, który miałem. Jeśli masz system Linux lub Mac OS i masz ochotę zadzierać ze źródłem Androida, być może będę mógł wskazać ci problematyczne obszary. Ale nawet dokładne zorientowanie się, co i gdzie dzieje się źle, niekoniecznie prowadzi do oczywistej poprawki. – Chroaster

Odpowiedz

4

Rozwiązaniem jest stworzenie klasy Sub MultiSelectListPreference i zastąpić metodę jak ShowDialog to:

@Override 
protected void showDialog(Bundle state) { 
    super.showDialog(state); 

    AlertDialog dialog = (AlertDialog)getDialog(); 
    if (dialog == null) 
     return; 

    if (Build.VERSION.SDK_INT >= 23) { 
     ListView listView = dialog.getListView(); 

     listView.setOnScrollListener(new AbsListView.OnScrollListener() { 
      @Override 
      public void onScrollStateChanged(AbsListView view, int scrollState) { 
       int size = view.getChildCount(); 
       for (int i=0; i<size; i++) { 
        View v = view.getChildAt(i); 
        if (v instanceof CheckedTextView) 
         ((CheckedTextView)v).refreshDrawableState(); 
       } 
      } 

      @Override 
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
       int size = view.getChildCount(); 
       for (int i=0; i<size; i++) { 
        View v = view.getChildAt(i); 
        if (v instanceof CheckedTextView) 
         ((CheckedTextView)v).refreshDrawableState(); 
       } 
      } 
     }); 
    } 
} 
+1

Dwa rzutowania do 'CheckedTextView' są zbędne. Poza tym jest to doskonałe, wielkie dzięki. – Keelan

0

Doskonały. Ten kod działa jak mdiener wymienić:

import android.app.AlertDialog; 
import android.content.Context; 
import android.os.Build; 
import android.os.Bundle; 
import android.preference.MultiSelectListPreference; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.AbsListView; 
import android.widget.CheckedTextView; 
import android.widget.ListView; 

/** 
* Android bug: https://code.google.com/p/android/issues/detail?id=205487 
*/ 
public class MultiSelectWrapper extends MultiSelectListPreference { 

public MultiSelectWrapper(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
    super(context, attrs, defStyleAttr, defStyleRes); 
} 

public MultiSelectWrapper(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
} 

public MultiSelectWrapper(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public MultiSelectWrapper(Context context) { 
    super(context); 
} 

@Override 
protected void showDialog(Bundle state) { 
    super.showDialog(state); 

    AlertDialog dialog = (AlertDialog)getDialog(); 
    if (dialog == null) 
     return; 

    if (Build.VERSION.SDK_INT >= 23) { 
     ListView listView = dialog.getListView(); 

     listView.setOnScrollListener(new AbsListView.OnScrollListener() { 
      @Override 
      public void onScrollStateChanged(AbsListView view, int scrollState) { 
       int size = view.getChildCount(); 
       for (int i=0; i<size; i++) { 
        View v = view.getChildAt(i); 
        if (v instanceof CheckedTextView) 
         ((CheckedTextView)v).refreshDrawableState(); 
       } 
      } 

      @Override 
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
       int size = view.getChildCount(); 
       for (int i=0; i<size; i++) { 
        View v = view.getChildAt(i); 
        if (v instanceof CheckedTextView) 
         ((CheckedTextView)v).refreshDrawableState(); 
       } 
      } 
     }); 
    } 
} 
} 
Powiązane problemy