Material Design Team 0534bfb96a Automated g4 rollback of changelist 184611618
PiperOrigin-RevId: 184658131
2018-03-12 12:35:05 -04:00

205 lines
8.0 KiB
Java

/*
* Copyright (C) 2017 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 android.support.design.button;
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import android.annotation.TargetApi;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.RippleDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import android.support.design.resources.MaterialResources;
import android.support.design.ripple.RippleUtils;
import android.support.v4.graphics.ColorUtils;
import android.support.v4.view.ViewCompat;
/** @hide */
@RestrictTo(LIBRARY_GROUP)
class MaterialButtonHelper {
private static final int[] STATE_PRESSED =
new int[] {android.R.attr.state_enabled, android.R.attr.state_pressed};
private static final int[] STATE_ENABLED = new int[] {android.R.attr.state_enabled};
private static final int[] STATE_EMPTY = new int[] {};
private final MaterialButton materialButton;
private int insetLeft;
private int insetRight;
private int insetTop;
private int insetBottom;
private float cornerRadius;
@Nullable private ColorStateList backgroundTint;
@Nullable private ColorStateList strokeColor;
@Nullable private ColorStateList rippleColor;
@Nullable private GradientDrawable pressedBackgroundCompat;
@Nullable private GradientDrawable enabledBackgroundCompat;
@Nullable private GradientDrawable disabledBackgroundCompat;
@Nullable private GradientDrawable backgroundDrawable;
private int strokeWidth;
public MaterialButtonHelper(MaterialButton button) {
materialButton = button;
}
public void loadFromAttributes(TypedArray attributes) {
insetLeft = attributes.getDimensionPixelOffset(R.styleable.MaterialButton_android_insetLeft, 0);
insetRight =
attributes.getDimensionPixelOffset(R.styleable.MaterialButton_android_insetRight, 0);
insetTop = attributes.getDimensionPixelOffset(R.styleable.MaterialButton_android_insetTop, 0);
insetBottom =
attributes.getDimensionPixelOffset(R.styleable.MaterialButton_android_insetBottom, 0);
cornerRadius = attributes.getDimensionPixelSize(R.styleable.MaterialButton_cornerRadius, 0);
backgroundTint =
MaterialResources.getColorStateList(
materialButton.getContext(),
attributes,
R.styleable.MaterialButton_buttonBackgroundTint);
strokeColor =
MaterialResources.getColorStateList(
materialButton.getContext(), attributes, R.styleable.MaterialButton_strokeColor);
rippleColor =
MaterialResources.getColorStateList(
materialButton.getContext(), attributes, R.styleable.MaterialButton_rippleColor);
strokeWidth = attributes.getDimensionPixelSize(R.styleable.MaterialButton_strokeWidth, 0);
ViewCompat.setBackground(
materialButton,
VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP
? createBackgroundLollipop()
: createBackgroundCompat());
}
/**
* Create StateListDrawable background for KitKat (API 19) and earlier API versions
*
* @return Drawable representing background for this button.
*/
private Drawable createBackgroundCompat() {
ColorStateList backgroundColorStateList = createBackgroundColorCompat();
pressedBackgroundCompat =
createGradientDrawableForState(STATE_PRESSED, backgroundColorStateList);
enabledBackgroundCompat =
createGradientDrawableForState(STATE_ENABLED, backgroundColorStateList);
disabledBackgroundCompat =
createGradientDrawableForState(STATE_EMPTY, backgroundColorStateList);
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(
STATE_PRESSED, wrapGradientDrawableWithInset(pressedBackgroundCompat));
stateListDrawable.addState(
STATE_ENABLED, wrapGradientDrawableWithInset(enabledBackgroundCompat));
stateListDrawable.addState(
STATE_EMPTY, wrapGradientDrawableWithInset(disabledBackgroundCompat));
return stateListDrawable;
}
private InsetDrawable wrapGradientDrawableWithInset(GradientDrawable gradientDrawable) {
return new InsetDrawable(gradientDrawable, insetLeft, insetTop, insetRight, insetBottom);
}
private GradientDrawable createGradientDrawableForState(
int[] state, ColorStateList backgroundColor) {
GradientDrawable bgDrawable = new GradientDrawable();
bgDrawable.setCornerRadius(cornerRadius);
bgDrawable.setColor(backgroundColor.getColorForState(state, 0));
if (strokeColor != null) {
bgDrawable.setStroke(strokeWidth, strokeColor.getColorForState(state, 0));
}
return bgDrawable;
}
private ColorStateList createBackgroundColorCompat() {
int pressedBackgroundColor =
ColorUtils.compositeColors(
rippleColor != null ? rippleColor.getColorForState(STATE_PRESSED, 0) : 0,
backgroundTint != null ? backgroundTint.getColorForState(STATE_PRESSED, 0) : 0);
int enabledBackgroundColor = backgroundTint.getColorForState(STATE_ENABLED, 0);
int disabledBackgroundColor = backgroundTint.getColorForState(STATE_EMPTY, 0);
return new ColorStateList(
new int[][] {STATE_PRESSED, STATE_ENABLED, STATE_EMPTY},
new int[] {pressedBackgroundColor, enabledBackgroundColor, disabledBackgroundColor});
}
private void updateBackgroundColorCompat() {
ColorStateList backgroundColorStateList = createBackgroundColorCompat();
if (pressedBackgroundCompat != null) {
pressedBackgroundCompat.setColor(backgroundColorStateList.getColorForState(STATE_PRESSED, 0));
}
if (enabledBackgroundCompat != null) {
enabledBackgroundCompat.setColor(backgroundColorStateList.getColorForState(STATE_ENABLED, 0));
}
if (disabledBackgroundCompat != null) {
disabledBackgroundCompat.setColor(backgroundColorStateList.getColorForState(STATE_EMPTY, 0));
}
}
void setSupportBackgroundTintList(@Nullable ColorStateList tintList) {
backgroundTint = tintList;
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
if (backgroundDrawable != null) {
backgroundDrawable.setColor(backgroundTint);
}
} else {
updateBackgroundColorCompat();
}
}
ColorStateList getSupportBackgroundTintList() {
return backgroundTint;
}
/**
* Create RippleDrawable background for Lollipop (API 21) and later API versions
*
* @return Drawable representing background for this button.
*/
@TargetApi(VERSION_CODES.LOLLIPOP)
private Drawable createBackgroundLollipop() {
backgroundDrawable = new GradientDrawable();
backgroundDrawable.setCornerRadius(cornerRadius);
backgroundDrawable.setColor(backgroundTint);
if (strokeColor != null) {
backgroundDrawable.setStroke(strokeWidth, strokeColor);
}
InsetDrawable bgInsetDrawable =
new InsetDrawable(backgroundDrawable, insetLeft, insetTop, insetRight, insetBottom);
GradientDrawable maskDrawable = new GradientDrawable();
maskDrawable.setCornerRadius(cornerRadius);
maskDrawable.setColor(Color.WHITE);
InsetDrawable maskInsetDrawable = new InsetDrawable(maskDrawable, 0);
return new RippleDrawable(
RippleUtils.convertToRippleDrawableColor(rippleColor), bgInsetDrawable, maskInsetDrawable);
}
}