使用AppCompat v21将色调应用于PreferenceActivity小部件

dev*_*cca 16 android tint android-appcompat android-preferences material-design

我在PreferenceActivity中使用CheckboxPreference,在v21支持库中使用AppCompat主题.正如您所知,使用这个最新的库小部件,如复选框,editTexts,单选按钮等,都会使用主题中定义的辅助颜色进行着色.在首选项屏幕中,文本是由我的主题指定的正确颜色,但复选框和edittext不是.似乎当CheckboxPreference实例创建窗口小部件时,它不会将我的主题应用于它.

正常布局中的单选按钮,有色:

截图1 http://i59.tinypic.com/2qv9stj.png

来自CheckboxPreference的复选框,没有着色:

截图2 http://i61.tinypic.com/91bcly.png

我用作父主题Theme.AppCompat.Light.NoActionBar.这种情况发生在Preference的每个子类中都有一个小部件,比如说EditTextPreference,其中EditText有一条黑色的底线,而不是有色的线.如何将色调应用于Preference子类显示的小部件?

更新:因为PreferenceActivity扩展了框架Activity,所以不应用着色.在工作案例中,我使用了支持库中的ActionBarActivity.现在的问题是:怎么了?

Tam*_*sák 10

编辑:从AppCompat 22.1开始,任何活动都可以使用AppCompatDelegate主题化.有色视图类的名称也从更改v7.internal.widget.TintXYZv7.widget.AppCompatXYZ.以下答案适用于AppCompat 22.0及更早版本.


我也遇到了这个问题并通过简单地从ActionBarActivity复制与小部件着色相关的代码来解决它.此解决方案的一个缺点是它依赖于可能在将来更改或变得不可用的内部类.

import android.support.v7.internal.widget.TintCheckBox;
import android.support.v7.internal.widget.TintCheckedTextView;
import android.support.v7.internal.widget.TintEditText;
import android.support.v7.internal.widget.TintRadioButton;
import android.support.v7.internal.widget.TintSpinner;

public class MyActivity extends PreferenceActivity {
    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        // Allow super to try and create a view first
        final View result = super.onCreateView(name, context, attrs);
        if (result != null) {
            return result;
        }

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            // If we're running pre-L, we need to 'inject' our tint aware Views in place of the
            // standard framework versions
            switch (name) {
                case "EditText":
                    return new TintEditText(this, attrs);
                case "Spinner":
                    return new TintSpinner(this, attrs);
                case "CheckBox":
                    return new TintCheckBox(this, attrs);
                case "RadioButton":
                    return new TintRadioButton(this, attrs);
                case "CheckedTextView":
                    return new TintCheckedTextView(this, attrs);
            }
        }

        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为对于从布局资源中膨胀的每个视图,layoutInflater服务都会调用onCreateView,这允许活动覆盖实例化的类.确保活动主题设置为Theme.AppCompat.清单中的(或后代).

有关原始代码,请参阅ActionBarActivity.javaActionBarActivityDelegateBase.java.


reV*_*rse 6

我知道这些问题有点陈旧但我想留下一个解决方案来克服你遇到过的这个问题.首先,我想说这PreferenceActivity是蜂窝时代之前的遗物,所以不要指望谷歌在这个非常古老的活动子集中为你的小部件着色.
您应该使用PreferenceFragments哪个PreferenceActivity而不是PreferenceActivity Activity(ActionbarActivity如果您希望您的Widgets被着色,则优选使用它).

按照一个非常基本的代码示例,您的设置活动应该如何.

public class MySettings extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);

        getFragmentManager().beginTransaction()
                .replace(R.id.container, new MyPreferenceFragment()).commit();
    }

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

            addPreferencesFromResource(R.xml.preferences_file);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意: 在这个例子中,我使用了FrameLayout作为PreferenceFragments的容器

结果:

示例显示首选项中的有色小部件

因此,您可以看到您的小部件将根据colorAccent您的设置正确着色.
有关developer.android.com上的 PreferenceFragments的更多信息(请单击).


dev*_*cca 2

到目前为止,我自己的(悲伤的)解决方法是从头开始创建我自己的复选框可绘制对象,使用复选框本来应该着色的颜色。

在 styles.xml 中:

<?xml version="1.0" encoding="utf-8"?>
<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
...
<!-- edit the checkbox appearance -->
<item name="android:listChoiceIndicatorMultiple">@drawable/my_checkbox</item>
...
</style>
Run Code Online (Sandbox Code Playgroud)

可绘制/my_checkbox.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:drawable="@drawable/checkbox_on" />
    <item android:drawable="@drawable/checkbox_off" />
</selector>
Run Code Online (Sandbox Code Playgroud)

checkbox_on" andcheckbox_off` 是选定和未选定状态的 PNG 可绘制对象,显然每个屏幕密度都有一个。如果您介意尺寸一致性,则可绘制对象的基线 (MDPI) 尺寸应为 32 像素完整资源和 18 像素光学正方形。