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

时间:2014-10-20 13:13:09

标签: android android-preferences android-appcompat material-design tint

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

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

screenshot 1 http://i59.tinypic.com/2qv9stj.png

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

screenshot 2 http://i61.tinypic.com/91bcly.png

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

更新:由于PreferenceActivity扩展了框架Activity,因此未应用着色。在工作案例中,我使用了支持库中的ActionBarActivity。现在的问题是:怎么回事?

5 个答案:

答案 0 :(得分:10)

编辑:从AppCompat 22.1开始,任何活动都可以使用AppCompatDelegate为主题。有色视图类的名称也从v7.internal.widget.TintXYZ更改为v7.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;
    }
}

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

请参阅ActionBarActivity.javaActionBarActivityDelegateBase.java了解原始代码。

答案 1 :(得分:6)

我知道这些问题有点陈旧,但我想留下一个解决方案来克服你遇到的这个问题。 首先,我想说PreferenceActivity是蜂窝时代之前的遗物,所以不要期望 Google 在这个非常古老的小部件中涂抹你的小部件活动子集。
您应该使用PreferenceFragments而不是PreferenceActivity,而Activity将包含在ActionbarActivity中(如果您希望对小部件进行着色,则最好为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); } } } 。)

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

实施例

colorAccent

注意: 在此示例中,我使用了FrameLayout作为PreferenceFragments的容器

结果:

example showing tinted widgets in preferences

因此,根据您设置的{{1}},您可以看到自己的小部件将被正确着色。
有关developer.android.com (click)上的PreferenceFragments的更多信息。

答案 2 :(得分:2)

到目前为止,我自己的(悲伤)解决方法是从头开始创建我自己的复选框drawables,使用复选框应该首先着色的颜色。

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

抽拉/ 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>

checkbox_on" and checkbox_off`是选定和未选定状态的PNG drawable,显然是每个屏幕密度的一个。 如果您考虑尺寸一致性,则可绘制的基线(MDPI)维度应为32px完整资产和18px光学平方。

答案 3 :(得分:2)

TamásSzincsák给出的解决方案效果很好,但如果使用appcompat-v7:22.1.1,则应更新,如下所示:

导入应更改为

In [146]: %timeit df.apply(lambda x: x.argmax(), axis=1)
1 loops, best of 3: 479 ms per loop

In [147]: %timeit df.idxmax(axis=1)
10 loops, best of 3: 47.3 ms per loop

分别应该是

import android.support.v7.widget.AppCompatCheckBox;
import android.support.v7.widget.AppCompatCheckedTextView;
import android.support.v7.widget.AppCompatEditText;
import android.support.v7.widget.AppCompatRadioButton;
import android.support.v7.widget.AppCompatSpinner;

答案 4 :(得分:1)

如果您使用的是AppCompat,请使用style.xml文件中的app compat项。

例如,使用:

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
</style>

NOT(注意&#34; android:&#34;):

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <item name="android:colorPrimary">@color/primary</item>
    <item name="android:colorPrimaryDark">@color/primary_dark</item>
    <item name="android:colorAccent">@color/accent</item>
</style>

这解决了我的问题。