AppCompatCheckedTextViewHelper.java
/*
* Copyright (C) 2021 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.appcompat.widget;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.CheckedTextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.appcompat.R;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.ViewCompat;
import androidx.core.widget.CheckedTextViewCompat;
/** @hide */
@RestrictTo(LIBRARY)
class AppCompatCheckedTextViewHelper {
@NonNull
private final CheckedTextView mView;
private ColorStateList mCheckMarkTintList = null;
private PorterDuff.Mode mCheckMarkTintMode = null;
private boolean mHasCheckMarkTint = false;
private boolean mHasCheckMarkTintMode = false;
private boolean mSkipNextApply;
AppCompatCheckedTextViewHelper(@NonNull CheckedTextView view) {
mView = view;
}
void loadFromAttributes(@Nullable AttributeSet attrs, int defStyleAttr) {
TintTypedArray a =
TintTypedArray.obtainStyledAttributes(mView.getContext(), attrs,
R.styleable.CheckedTextView, defStyleAttr, 0);
ViewCompat.saveAttributeDataForStyleable(mView, mView.getContext(),
R.styleable.CheckedTextView, attrs, a.getWrappedTypeArray(), defStyleAttr, 0);
try {
boolean checkMarkDrawableLoaded = false;
if (a.hasValue(R.styleable.CheckedTextView_checkMarkCompat)) {
final int resourceId = a.getResourceId(R.styleable.CheckedTextView_checkMarkCompat,
0);
if (resourceId != 0) {
try {
mView.setCheckMarkDrawable(
AppCompatResources.getDrawable(mView.getContext(), resourceId));
checkMarkDrawableLoaded = true;
} catch (Resources.NotFoundException ignore) {
// Animated checkMarkCompat relies on AAPT2 features. If not found then
// swallow this error and fall back to the regular drawable.
}
}
}
if (!checkMarkDrawableLoaded && a.hasValue(
R.styleable.CheckedTextView_android_checkMark)) {
final int resourceId = a.getResourceId(
R.styleable.CheckedTextView_android_checkMark, 0);
if (resourceId != 0) {
mView.setCheckMarkDrawable(
AppCompatResources.getDrawable(mView.getContext(), resourceId));
}
}
if (a.hasValue(R.styleable.CheckedTextView_checkMarkTint)) {
CheckedTextViewCompat.setCheckMarkTintList(mView,
a.getColorStateList(R.styleable.CheckedTextView_checkMarkTint));
}
if (a.hasValue(R.styleable.CheckedTextView_checkMarkTintMode)) {
CheckedTextViewCompat.setCheckMarkTintMode(mView,
DrawableUtils.parseTintMode(
a.getInt(R.styleable.CheckedTextView_checkMarkTintMode, -1),
null));
}
} finally {
a.recycle();
}
}
void setSupportCheckMarkTintList(ColorStateList tint) {
mCheckMarkTintList = tint;
mHasCheckMarkTint = true;
applyCheckMarkTint();
}
ColorStateList getSupportCheckMarkTintList() {
return mCheckMarkTintList;
}
void setSupportCheckMarkTintMode(@Nullable PorterDuff.Mode tintMode) {
mCheckMarkTintMode = tintMode;
mHasCheckMarkTintMode = true;
applyCheckMarkTint();
}
PorterDuff.Mode getSupportCheckMarkTintMode() {
return mCheckMarkTintMode;
}
void onSetCheckMarkDrawable() {
if (mSkipNextApply) {
mSkipNextApply = false;
return;
}
mSkipNextApply = true;
applyCheckMarkTint();
}
void applyCheckMarkTint() {
Drawable checkMarkDrawable = CheckedTextViewCompat.getCheckMarkDrawable(mView);
if (checkMarkDrawable != null && (mHasCheckMarkTint || mHasCheckMarkTintMode)) {
checkMarkDrawable = DrawableCompat.wrap(checkMarkDrawable);
checkMarkDrawable = checkMarkDrawable.mutate();
if (mHasCheckMarkTint) {
DrawableCompat.setTintList(checkMarkDrawable, mCheckMarkTintList);
}
if (mHasCheckMarkTintMode) {
DrawableCompat.setTintMode(checkMarkDrawable, mCheckMarkTintMode);
}
// The drawable (or one of its children) may not have been
// stateful before applying the tint, so let's try again.
if (checkMarkDrawable.isStateful()) {
checkMarkDrawable.setState(mView.getDrawableState());
}
mView.setCheckMarkDrawable(checkMarkDrawable);
}
}
}