cketcham 3de44ca7ac Add shapes theming infrastructure.
Add shapeAppearance and shapeAppearanceOverlay attributes. These attributes combine to support shapes theming. ShapeAppearance is modeled after TextAppearance. A shapeAppearance attribute contains a style reference that is meant to be defined at the theme level. Since changing anything defined in the shapeAppearance would clobber everything else in the ShapeAppearance, the shapeAppearanceOverlay attribute is provided for clients to modify the shapeAppearance.

PiperOrigin-RevId: 215273652
2018-10-02 14:53:40 -04:00

371 lines
12 KiB
Java

/*
* Copyright 2018 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 com.google.android.material.shape;
import com.google.android.material.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.AttrRes;
import android.support.annotation.Dimension;
import android.support.annotation.StyleRes;
import com.google.android.material.internal.Experimental;
import com.google.android.material.internal.ThemeEnforcement;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
/**
* This class models the edges and corners of a shape, which are used by {@link
* MaterialShapeDrawable} to generate and render the shape for a view's background.
*/
@Experimental("The shapes API is currently experimental and subject to change")
public class ShapeAppearanceModel {
private static final CornerTreatment DEFAULT_CORNER_TREATMENT = new RoundedCornerTreatment(0);
private static final EdgeTreatment DEFAULT_EDGE_TREATMENT = new EdgeTreatment();
private CornerTreatment topLeftCorner;
private CornerTreatment topRightCorner;
private CornerTreatment bottomRightCorner;
private CornerTreatment bottomLeftCorner;
private EdgeTreatment topEdge;
private EdgeTreatment rightEdge;
private EdgeTreatment bottomEdge;
private EdgeTreatment leftEdge;
/** Constructs a default path generator with default edge and corner treatments. */
public ShapeAppearanceModel() {
topLeftCorner = DEFAULT_CORNER_TREATMENT;
topRightCorner = DEFAULT_CORNER_TREATMENT;
bottomRightCorner = DEFAULT_CORNER_TREATMENT;
bottomLeftCorner = DEFAULT_CORNER_TREATMENT;
topEdge = DEFAULT_EDGE_TREATMENT;
rightEdge = DEFAULT_EDGE_TREATMENT;
bottomEdge = DEFAULT_EDGE_TREATMENT;
leftEdge = DEFAULT_EDGE_TREATMENT;
}
public ShapeAppearanceModel(ShapeAppearanceModel shapeAppearanceModel) {
topLeftCorner = shapeAppearanceModel.getTopLeftCorner();
topRightCorner = shapeAppearanceModel.getTopRightCorner();
bottomRightCorner = shapeAppearanceModel.getBottomRightCorner();
bottomLeftCorner = shapeAppearanceModel.getBottomLeftCorner();
topEdge = shapeAppearanceModel.getTopEdge();
rightEdge = shapeAppearanceModel.getRightEdge();
leftEdge = shapeAppearanceModel.getLeftEdge();
bottomEdge = shapeAppearanceModel.getBottomEdge();
}
public ShapeAppearanceModel(
Context context, AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
TypedArray a =
ThemeEnforcement.obtainStyledAttributes(
context, attrs, R.styleable.MaterialShape, defStyleAttr, defStyleRes);
int shapeAppearanceResId = a.getResourceId(R.styleable.MaterialShape_shapeAppearance, 0);
int shapeAppearanceOverlayResId =
a.getResourceId(R.styleable.MaterialShape_shapeAppearanceOverlay, 0);
a.recycle();
// The attributes in shapeAppearanceOverlay should be applied on top of shapeAppearance.
if (shapeAppearanceOverlayResId != 0) {
context = new ContextThemeWrapper(context, shapeAppearanceResId);
shapeAppearanceResId = shapeAppearanceOverlayResId;
}
a = context.obtainStyledAttributes(shapeAppearanceResId, R.styleable.ShapeAppearance);
int cornerFamily = a.getInt(R.styleable.ShapeAppearance_cornerFamily, CornerFamily.ROUNDED);
int cornerFamilyTopLeft =
a.getInt(R.styleable.ShapeAppearance_cornerFamilyTopLeft, cornerFamily);
int cornerFamilyTopRight =
a.getInt(R.styleable.ShapeAppearance_cornerFamilyTopRight, cornerFamily);
int cornerFamilyBottomRight =
a.getInt(R.styleable.ShapeAppearance_cornerFamilyBottomRight, cornerFamily);
int cornerFamilyBottomLeft =
a.getInt(R.styleable.ShapeAppearance_cornerFamilyBottomLeft, cornerFamily);
int cornerSize = a.getDimensionPixelSize(R.styleable.ShapeAppearance_cornerSize, 0);
int cornerSizeTopLeft =
a.getDimensionPixelSize(R.styleable.ShapeAppearance_cornerSizeTopLeft, cornerSize);
int cornerSizeTopRight =
a.getDimensionPixelSize(R.styleable.ShapeAppearance_cornerSizeTopRight, cornerSize);
int cornerSizeBottomRight =
a.getDimensionPixelSize(R.styleable.ShapeAppearance_cornerSizeBottomRight, cornerSize);
int cornerSizeBottomLeft =
a.getDimensionPixelSize(R.styleable.ShapeAppearance_cornerSizeBottomLeft, cornerSize);
setTopLeftCorner(cornerFamilyTopLeft, cornerSizeTopLeft);
setTopRightCorner(cornerFamilyTopRight, cornerSizeTopRight);
setBottomRightCorner(cornerFamilyBottomRight, cornerSizeBottomRight);
setBottomLeftCorner(cornerFamilyBottomLeft, cornerSizeBottomLeft);
a.recycle();
}
/**
* Sets all corner treatments.
*
* @param cornerTreatment the corner treatment to use in all four corners.
*/
public void setAllCorners(CornerTreatment cornerTreatment) {
topLeftCorner = cornerTreatment;
topRightCorner = cornerTreatment;
bottomRightCorner = cornerTreatment;
bottomLeftCorner = cornerTreatment;
}
public void setAllCorners(@CornerFamily int cornerFamily, @Dimension int cornerSize) {
setAllCorners(MaterialShapeUtils.createCornerTreatment(cornerFamily, cornerSize));
}
/**
* Sets all edge treatments.
*
* @param edgeTreatment the edge treatment to use for all four edges.
*/
public void setAllEdges(EdgeTreatment edgeTreatment) {
leftEdge = edgeTreatment;
topEdge = edgeTreatment;
rightEdge = edgeTreatment;
bottomEdge = edgeTreatment;
}
/**
* Sets corner treatments.
*
* @param topLeftCorner the corner treatment to use in the top-left corner.
* @param topRightCorner the corner treatment to use in the top-right corner.
* @param bottomRightCorner the corner treatment to use in the bottom-right corner.
* @param bottomLeftCorner the corner treatment to use in the bottom-left corner.
*/
public void setCornerTreatments(
CornerTreatment topLeftCorner,
CornerTreatment topRightCorner,
CornerTreatment bottomRightCorner,
CornerTreatment bottomLeftCorner) {
this.topLeftCorner = topLeftCorner;
this.topRightCorner = topRightCorner;
this.bottomRightCorner = bottomRightCorner;
this.bottomLeftCorner = bottomLeftCorner;
}
/**
* Sets edge treatments.
*
* @param leftEdge the edge treatment to use on the left edge.
* @param topEdge the edge treatment to use on the top edge.
* @param rightEdge the edge treatment to use on the right edge.
* @param bottomEdge the edge treatment to use on the bottom edge.
*/
public void setEdgeTreatments(
EdgeTreatment leftEdge,
EdgeTreatment topEdge,
EdgeTreatment rightEdge,
EdgeTreatment bottomEdge) {
this.leftEdge = leftEdge;
this.topEdge = topEdge;
this.rightEdge = rightEdge;
this.bottomEdge = bottomEdge;
}
/**
* Sets the corner treatment for the top-left corner.
*
* @param cornerFamily the family to use to create the corner treatment
* @param cornerSize the size to use to create the corner treatment
*/
public void setTopLeftCorner(@CornerFamily int cornerFamily, @Dimension int cornerSize) {
setTopLeftCorner(MaterialShapeUtils.createCornerTreatment(cornerFamily, cornerSize));
}
/**
* Sets the corner treatment for the top-left corner.
*
* @param topLeftCorner the desired treatment.
*/
public void setTopLeftCorner(CornerTreatment topLeftCorner) {
this.topLeftCorner = topLeftCorner;
}
/**
* Gets the corner treatment for the top-left corner.
*
* @return the corner treatment for the top-left corner.
*/
public CornerTreatment getTopLeftCorner() {
return topLeftCorner;
}
/**
* Sets the corner treatment for the top-right corner.
*
* @param cornerFamily the family to use to create the corner treatment
* @param cornerSize the size to use to create the corner treatment
*/
public void setTopRightCorner(@CornerFamily int cornerFamily, @Dimension int cornerSize) {
setTopRightCorner(MaterialShapeUtils.createCornerTreatment(cornerFamily, cornerSize));
}
/**
* Sets the corner treatment for the top-right corner.
*
* @param topRightCorner the desired treatment.
*/
public void setTopRightCorner(CornerTreatment topRightCorner) {
this.topRightCorner = topRightCorner;
}
/**
* Gets the corner treatment for the top-right corner.
*
* @return the corner treatment for the top-right corner.
*/
public CornerTreatment getTopRightCorner() {
return topRightCorner;
}
/**
* Sets the corner treatment for the bottom-right corner.
*
* @param cornerFamily the family to use to create the corner treatment
* @param cornerSize the size to use to create the corner treatment
*/
public void setBottomRightCorner(@CornerFamily int cornerFamily, @Dimension int cornerSize) {
setBottomRightCorner(MaterialShapeUtils.createCornerTreatment(cornerFamily, cornerSize));
}
/**
* Sets the corner treatment for the bottom-right corner.
*
* @param bottomRightCorner the desired treatment.
*/
public void setBottomRightCorner(CornerTreatment bottomRightCorner) {
this.bottomRightCorner = bottomRightCorner;
}
/**
* Gets the corner treatment for the bottom-right corner.
*
* @return the corner treatment for the bottom-right corner.
*/
public CornerTreatment getBottomRightCorner() {
return bottomRightCorner;
}
/**
* Sets the corner treatment for the bottom-left corner.
*
* @param cornerFamily the family to use to create the corner treatment
* @param cornerSize the size to use to create the corner treatment
*/
public void setBottomLeftCorner(@CornerFamily int cornerFamily, @Dimension int cornerSize) {
setBottomLeftCorner(MaterialShapeUtils.createCornerTreatment(cornerFamily, cornerSize));
}
/**
* Sets the corner treatment for the bottom-left corner.
*
* @param bottomLeftCorner the desired treatment.
*/
public void setBottomLeftCorner(CornerTreatment bottomLeftCorner) {
this.bottomLeftCorner = bottomLeftCorner;
}
/**
* Gets the corner treatment for the bottom-left corner.
*
* @return the corner treatment for the bottom-left corner.
*/
public CornerTreatment getBottomLeftCorner() {
return bottomLeftCorner;
}
/**
* Sets the edge treatment for the top edge.
*
* @param topEdge the desired treatment.
*/
public void setTopEdge(EdgeTreatment topEdge) {
this.topEdge = topEdge;
}
/**
* Gets the edge treatment for the top edge.
*
* @return the edge treatment for the top edge.
*/
public EdgeTreatment getTopEdge() {
return topEdge;
}
/**
* Sets the edge treatment for the right edge.
*
* @param rightEdge the desired treatment.
*/
public void setRightEdge(EdgeTreatment rightEdge) {
this.rightEdge = rightEdge;
}
/**
* Gets the edge treatment for the right edge.
*
* @return the edge treatment for the right edge.
*/
public EdgeTreatment getRightEdge() {
return rightEdge;
}
/**
* Sets the edge treatment for the bottom edge.
*
* @param bottomEdge the desired treatment.
*/
public void setBottomEdge(EdgeTreatment bottomEdge) {
this.bottomEdge = bottomEdge;
}
/**
* Gets the edge treatment for the bottom edge.
*
* @return the edge treatment for the bottom edge.
*/
public EdgeTreatment getBottomEdge() {
return bottomEdge;
}
/**
* Sets the edge treatment for the left edge.
*
* @param leftEdge the desired treatment.
*/
public void setLeftEdge(EdgeTreatment leftEdge) {
this.leftEdge = leftEdge;
}
/**
* Gets the edge treatment for the left edge.
*
* @return the edge treatment for the left edge.
*/
public EdgeTreatment getLeftEdge() {
return leftEdge;
}
}