以编程方式改变Switch的颜色

时间:2018-02-05 18:05:14

标签: android android-switch

我正在尝试创建一个简单的自定义切换小部件,用于侦听SharedPreferences中某个键值的变化。以下是我的代码:

public class CustomSwitch extends SwitchCompat implements SharedPreferences.OnSharedPreferenceChangeListener {

    private static final String TAG = CustomSwitch.class.getSimpleName();

    private boolean isSwitchTintColorPrimary;

    public CustomSwitch(Context context) {
        this(context, null);
    }

    public CustomSwitch(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    private void initializeView(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomSwitch, 0, 0);
        try {
            isSwitchTintColorPrimary = ta.getBoolean(R.styleable.CustomSwitch_tintColorPrimary, false);
        } finally {
            ta.recycle();
        }
        applyTheme();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        registerThemeChangeListener();
    }

    private void registerThemeChangeListener() {
        if (getContext() != null)
            ColoriyoPreference.getSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        unRegisterThemeChangeListener();
    }

    private void unRegisterThemeChangeListener() {
        if (getContext() != null)
            ColoriyoPreference.getSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
    }

    private void applyTheme() {
        ColorStateList thumbStates = new ColorStateList(
                new int[][]{
                        {android.R.attr.state_checked, android.R.attr.state_enabled},
                        {-android.R.attr.state_checked, android.R.attr.state_enabled},
                        {}
                },
                new int[]{
                        isSwitchTintColorPrimary ? ColoriyoPreference.getColor(getContext()) : ContextCompat.getColor(getContext(), R.color.colorPrimary),
                        ContextCompat.getColor(getContext(), R.color.grey_50),
                        ContextCompat.getColor(getContext(), R.color.grey_50)
                }
        );
        setThumbTintList(thumbStates);

        ColorStateList trackStates = new ColorStateList(
                new int[][]{
                        new int[]{-android.R.attr.state_enabled},
                        new int[]{}
                },
                new int[]{
                        Color.GRAY,
                        Color.LTGRAY
                }
        );
        setTrackTintList(trackStates);
        setTrackTintMode(PorterDuff.Mode.OVERLAY);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals(PREFERENCE_KEY_COLOR)) {
            applyTheme();
        }
    }
}

在布局中:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.chintansoni.android.themedemo.MainActivity"
    tools:showIn="@layout/activity_main">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.chintansoni.android.themedemo.customview.themeview.CustomTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView textColor"
            app:textColorPrimary="true" />

        <com.chintansoni.android.themedemo.customview.themeview.CustomButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button Background"
            app:backgroundColorPrimary="true" />

        <com.chintansoni.android.themedemo.customview.themeview.CustomSwitch
            android:id="@+id/switch_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textOff="Off"
            android:textOn="On"
            app:tintColorPrimary="true" />
    </LinearLayout>

    <uz.shift.colorpicker.LineColorPicker
        android:id="@+id/picker"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_margin="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:orientation="horizontal" />

</android.support.constraint.ConstraintLayout>

但是我的视图没有在UI中呈现。另外,我想知道这段代码是否会优先监听颜色变化并反映运行时的颜色变化?

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我唯一遗漏的是:

public CustomSwitch(Context context, AttributeSet attrs) {
    this(context, attrs, R.attr.switchStyle); // <--- passing default Style Attribute 
}

我的改进课程如下:

public class CustomSwitch extends SwitchCompat implements SharedPreferences.OnSharedPreferenceChangeListener {

    private boolean isSwitchTintColorPrimary;

    public CustomSwitch(Context context) {
        this(context, null);
    }

    public CustomSwitch(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.switchStyle);
    }

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

    private void initializeView(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomSwitch, 0, 0);
        try {
            isSwitchTintColorPrimary = ta.getBoolean(R.styleable.CustomSwitch_tintColorPrimary, false);
        } finally {
            ta.recycle();
        }
        applyTheme();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        registerThemeChangeListener();
    }

    private void registerThemeChangeListener() {
        if (getContext() != null)
            ColoriyoPreference.getSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        unRegisterThemeChangeListener();
    }

    private void unRegisterThemeChangeListener() {
        if (getContext() != null)
            ColoriyoPreference.getSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
    }

    private void applyTheme() {
        ColorStateList thumbStates = new ColorStateList(
                new int[][]{
                        {android.R.attr.state_checked, android.R.attr.state_enabled},
                        {-android.R.attr.state_checked, android.R.attr.state_enabled},
                        {}
                },
                new int[]{
                        isSwitchTintColorPrimary ? ColoriyoPreference.getColor(getContext()) : ContextCompat.getColor(getContext(), R.color.colorPrimary),
                        ContextCompat.getColor(getContext(), R.color.grey_50),
                        ContextCompat.getColor(getContext(), R.color.grey_50)
                }
        );
        setThumbTintList(thumbStates);

        ColorStateList trackStates = new ColorStateList(
                new int[][]{
                        new int[]{android.R.attr.state_enabled},
                        new int[]{-android.R.attr.state_enabled}
                },
                new int[]{
                        Color.LTGRAY,
                        Color.GRAY,
                        Color.LTGRAY
                }
        );
        setTrackTintList(trackStates);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals(ColoriyoPreference.PREFERENCE_KEY_COLOR)) {
            applyTheme();
        }
    }
}