繁体   English   中英

在列表中最初不可见时未选中MultiSelectListPreference复选框(API 23)

[英]MultiSelectListPreference checkboxes not checked when not initially visible in list (API 23)

给定一个具有一个MultiSelectListPreference及其数组资源中的条目,值和默认值的SettingsActivity,即使Android知道应该选中它们,某些复选框也不会绘制为选中状态。 单击未选中的项目时,该项目保持未选中状态(因为Android认为它正在取消选中已选中的项目)。

这是发生这种情况的视频

可在此处找到项目: https//github.com/ImmersibleElf/MSLPBug

它在API 21和22中似乎可以正常工作,但在23中却不能正常工作。这是否可能是视图回收中的错误? 或可能是什么原因?

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>

一种解决方法是创建MultiSelectListPreference的子类,并覆盖如下所示的showDialog方法:

@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();
                }
            }
        });
    }
}

优秀。 这段代码就像mdiener提到的那样:

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();
                }
            }
        });
    }
}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM