| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package androidx.core.widget; |
| |
| import android.content.res.ColorStateList; |
| import android.graphics.PorterDuff; |
| import android.graphics.drawable.Drawable; |
| import android.os.Build; |
| import android.util.Log; |
| import android.widget.CompoundButton; |
| |
| import androidx.annotation.NonNull; |
| import androidx.annotation.Nullable; |
| import androidx.core.graphics.drawable.DrawableCompat; |
| |
| import java.lang.reflect.Field; |
| |
| /** |
| * Helper for accessing {@link android.widget.CompoundButton}. |
| */ |
| public final class CompoundButtonCompat { |
| private static final String TAG = "CompoundButtonCompat"; |
| |
| private static Field sButtonDrawableField; |
| private static boolean sButtonDrawableFieldFetched; |
| |
| private CompoundButtonCompat() {} |
| |
| /** |
| * Applies a tint to the button drawable. Does not modify the current tint |
| * mode, which is {@link PorterDuff.Mode#SRC_IN} by default. |
| * <p> |
| * Subsequent calls to {@link CompoundButton#setButtonDrawable(Drawable)} should |
| * automatically mutate the drawable and apply the specified tint and tint |
| * mode using {@link DrawableCompat#setTintList(Drawable, ColorStateList)}. |
| * |
| * @param tint the tint to apply, may be {@code null} to clear tint |
| * |
| * @see #setButtonTintList(CompoundButton, ColorStateList) |
| */ |
| public static void setButtonTintList(@NonNull CompoundButton button, |
| @Nullable ColorStateList tint) { |
| if (Build.VERSION.SDK_INT >= 21) { |
| button.setButtonTintList(tint); |
| } else if (button instanceof TintableCompoundButton) { |
| ((TintableCompoundButton) button).setSupportButtonTintList(tint); |
| } |
| } |
| |
| /** |
| * Returns the tint applied to the button drawable |
| * |
| * @see #setButtonTintList(CompoundButton, ColorStateList) |
| */ |
| @Nullable |
| public static ColorStateList getButtonTintList(@NonNull CompoundButton button) { |
| if (Build.VERSION.SDK_INT >= 21) { |
| return button.getButtonTintList(); |
| } |
| if (button instanceof TintableCompoundButton) { |
| return ((TintableCompoundButton) button).getSupportButtonTintList(); |
| } |
| return null; |
| } |
| |
| /** |
| * Specifies the blending mode used to apply the tint specified by |
| * {@link #setButtonTintList(CompoundButton, ColorStateList)}} to the button drawable. The |
| * default mode is {@link PorterDuff.Mode#SRC_IN}. |
| * |
| * @param tintMode the blending mode used to apply the tint, may be |
| * {@code null} to clear tint |
| * |
| * @see #getButtonTintMode(CompoundButton) |
| * @see DrawableCompat#setTintMode(Drawable, PorterDuff.Mode) |
| */ |
| public static void setButtonTintMode(@NonNull CompoundButton button, |
| @Nullable PorterDuff.Mode tintMode) { |
| if (Build.VERSION.SDK_INT >= 21) { |
| button.setButtonTintMode(tintMode); |
| } else if (button instanceof TintableCompoundButton) { |
| ((TintableCompoundButton) button).setSupportButtonTintMode(tintMode); |
| } |
| } |
| |
| /** |
| * @return the blending mode used to apply the tint to the button drawable |
| * @attr name android:buttonTintMode |
| * @see #setButtonTintMode(CompoundButton, PorterDuff.Mode) |
| */ |
| @Nullable |
| public static PorterDuff.Mode getButtonTintMode(@NonNull CompoundButton button) { |
| if (Build.VERSION.SDK_INT >= 21) { |
| return button.getButtonTintMode(); |
| } |
| if (button instanceof TintableCompoundButton) { |
| return ((TintableCompoundButton) button).getSupportButtonTintMode(); |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the drawable used as the compound button image |
| * |
| * @see CompoundButton#setButtonDrawable(Drawable) |
| */ |
| @Nullable |
| public static Drawable getButtonDrawable(@NonNull CompoundButton button) { |
| if (Build.VERSION.SDK_INT >= 23) { |
| return button.getButtonDrawable(); |
| } |
| |
| if (!sButtonDrawableFieldFetched) { |
| try { |
| sButtonDrawableField = CompoundButton.class.getDeclaredField("mButtonDrawable"); |
| sButtonDrawableField.setAccessible(true); |
| } catch (NoSuchFieldException e) { |
| Log.i(TAG, "Failed to retrieve mButtonDrawable field", e); |
| } |
| sButtonDrawableFieldFetched = true; |
| } |
| |
| if (sButtonDrawableField != null) { |
| try { |
| return (Drawable) sButtonDrawableField.get(button); |
| } catch (IllegalAccessException e) { |
| Log.i(TAG, "Failed to get button drawable via reflection", e); |
| sButtonDrawableField = null; |
| } |
| } |
| return null; |
| } |
| } |