mirror of
https://github.com/material-components/material-components-android.git
synced 2026-02-20 08:39:55 +08:00
Add support for percentages to ShapeAppearanceModel
PiperOrigin-RevId: 272946740 (cherry picked from commit a130a0c3e048a6311ff70a5bcb7d50b1809f7251)
This commit is contained in:
parent
5ff7b35e74
commit
c831ecc99d
@ -71,8 +71,7 @@
|
||||
</style>
|
||||
|
||||
<style name="ShapeAppearanceOverlay.MaterialComponents.Chip" parent="">
|
||||
<!-- Replace with 50% -->
|
||||
<item name="cornerSize">16dp</item>
|
||||
<item name="cornerSize">50%</item>
|
||||
</style>
|
||||
|
||||
<!-- Style for Chips that appear in text fields as a span.
|
||||
|
||||
@ -134,11 +134,6 @@ abstract class BaseMotionStrategy implements MotionStrategy {
|
||||
animators.add(spec.getAnimator("height", fab, ExtendedFloatingActionButton.HEIGHT));
|
||||
}
|
||||
|
||||
if (spec.hasPropertyValues("cornerRadius") && fab.isUsingPillCorner()) {
|
||||
animators
|
||||
.add(spec.getAnimator("cornerRadius", fab, ExtendedFloatingActionButton.CORNER_RADIUS));
|
||||
}
|
||||
|
||||
AnimatorSet set = new AnimatorSet();
|
||||
AnimatorSetCompat.playTogether(set, animators);
|
||||
return set;
|
||||
|
||||
@ -26,6 +26,7 @@ import android.animation.PropertyValuesHolder;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import androidx.annotation.AnimatorRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -48,7 +49,7 @@ import com.google.android.material.animation.MotionSpec;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.internal.DescendantOffsetUtils;
|
||||
import com.google.android.material.internal.ThemeEnforcement;
|
||||
import com.google.android.material.shape.MaterialShapeDrawable;
|
||||
import com.google.android.material.shape.CornerSize;
|
||||
import com.google.android.material.shape.ShapeAppearanceModel;
|
||||
import java.util.List;
|
||||
|
||||
@ -89,7 +90,6 @@ public class ExtendedFloatingActionButton extends MaterialButton implements Atta
|
||||
@NonNull private final Behavior<ExtendedFloatingActionButton> behavior;
|
||||
|
||||
private boolean isExtended = true;
|
||||
private boolean isUsingPillCorner = true;
|
||||
|
||||
/**
|
||||
* Callback to be invoked when the visibility or the state of an ExtendedFloatingActionButton
|
||||
@ -200,7 +200,17 @@ public class ExtendedFloatingActionButton extends MaterialButton implements Atta
|
||||
|
||||
ShapeAppearanceModel shapeAppearanceModel =
|
||||
ShapeAppearanceModel.builder(
|
||||
context, attrs, defStyleAttr, DEF_STYLE_RES, ShapeAppearanceModel.PILL)
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr,
|
||||
DEF_STYLE_RES,
|
||||
// TODO(b/121352029): Use ShapeAppearanceModel.PILL once this bug is fixed.
|
||||
new CornerSize() {
|
||||
@Override
|
||||
public float getCornerSize(@NonNull RectF bounds) {
|
||||
return getAdjustedRadius((int) bounds.height());
|
||||
}
|
||||
})
|
||||
.build();
|
||||
setShapeAppearanceModel(shapeAppearanceModel);
|
||||
}
|
||||
@ -215,45 +225,12 @@ public class ExtendedFloatingActionButton extends MaterialButton implements Atta
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
if (isUsingPillCorner) {
|
||||
setShapeAppearanceModel(createPillCornerShapeAppearance());
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Behavior<ExtendedFloatingActionButton> getBehavior() {
|
||||
return behavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShapeAppearanceModel(@NonNull ShapeAppearanceModel shapeAppearanceModel) {
|
||||
if (shapeAppearanceModel.isUsingPillCorner()) {
|
||||
isUsingPillCorner = true;
|
||||
shapeAppearanceModel = createPillCornerShapeAppearance();
|
||||
}
|
||||
super.setShapeAppearanceModel(shapeAppearanceModel);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private ShapeAppearanceModel createPillCornerShapeAppearance() {
|
||||
return getShapeAppearanceModel().withCornerRadius(getAdjustedRadius(getMeasuredHeight()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCornerRadius(int cornerRadius) {
|
||||
isUsingPillCorner = cornerRadius == ShapeAppearanceModel.PILL;
|
||||
if (isUsingPillCorner) {
|
||||
cornerRadius = getAdjustedRadius(getMeasuredHeight());
|
||||
} else if (cornerRadius < 0) {
|
||||
cornerRadius = 0;
|
||||
}
|
||||
super.setCornerRadius(cornerRadius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends or shrinks the fab depending on the value of {@param extended}.
|
||||
@ -554,10 +531,6 @@ public class ExtendedFloatingActionButton extends MaterialButton implements Atta
|
||||
setShrinkMotionSpec(MotionSpec.createFromResource(getContext(), id));
|
||||
}
|
||||
|
||||
boolean isUsingPillCorner() {
|
||||
return isUsingPillCorner;
|
||||
}
|
||||
|
||||
private void performMotion(
|
||||
@NonNull final MotionStrategy strategy, @Nullable final OnChangedCallback callback) {
|
||||
if (strategy.shouldCancel()) {
|
||||
@ -667,26 +640,6 @@ public class ExtendedFloatingActionButton extends MaterialButton implements Atta
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A Property wrapper around the <code>cornerRadius</code> functionality handled by the {@link
|
||||
* ExtendedFloatingActionButton#setCornerRadius(int)} and {@link
|
||||
* ExtendedFloatingActionButton#getCornerRadius()} methods.
|
||||
*/
|
||||
static final Property<View, Float> CORNER_RADIUS =
|
||||
new Property<View, Float>(Float.class, "cornerRadius") {
|
||||
@Override
|
||||
public void set(@NonNull View object, @NonNull Float value) {
|
||||
ExtendedFloatingActionButton efab = ((ExtendedFloatingActionButton) object);
|
||||
efab.setShapeAppearanceModel(
|
||||
efab.getShapeAppearanceModel().withCornerRadius(value.intValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(@NonNull View object) {
|
||||
return ((MaterialShapeDrawable) object.getBackground()).getTopRightCornerResolvedSize();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an adjusted radius value that corrects any rounding errors.
|
||||
*
|
||||
|
||||
@ -76,7 +76,6 @@ import com.google.android.material.internal.ViewUtils;
|
||||
import com.google.android.material.internal.VisibilityAwareImageButton;
|
||||
import com.google.android.material.resources.MaterialResources;
|
||||
import com.google.android.material.shadow.ShadowViewDelegate;
|
||||
import com.google.android.material.shape.AbsoluteCornerSize;
|
||||
import com.google.android.material.shape.ShapeAppearanceModel;
|
||||
import com.google.android.material.shape.Shapeable;
|
||||
import com.google.android.material.stateful.ExtendableSavedState;
|
||||
@ -245,7 +244,6 @@ public class FloatingActionButton extends VisibilityAwareImageButton
|
||||
context, attrs, defStyleAttr, DEF_STYLE_RES, ShapeAppearanceModel.PILL)
|
||||
.build();
|
||||
|
||||
boolean usingDefaultCorner = isUsingDefaultCorner(shapeAppearance);
|
||||
boolean ensureMinTouchTargetSize = a
|
||||
.getBoolean(R.styleable.FloatingActionButton_ensureMinTouchTargetSize, false);
|
||||
|
||||
@ -256,7 +254,7 @@ public class FloatingActionButton extends VisibilityAwareImageButton
|
||||
|
||||
expandableWidgetHelper = new ExpandableWidgetHelper(this);
|
||||
|
||||
getImpl().setShapeAppearance(shapeAppearance, usingDefaultCorner);
|
||||
getImpl().setShapeAppearance(shapeAppearance);
|
||||
getImpl()
|
||||
.initializeBackgroundDrawable(backgroundTint, backgroundTintMode, rippleColor, borderWidth);
|
||||
getImpl().setMinTouchTargetSize(minTouchTargetSize);
|
||||
@ -522,7 +520,7 @@ public class FloatingActionButton extends VisibilityAwareImageButton
|
||||
/** Sets the {@link ShapeAppearanceModel} for this {@link FloatingActionButton}. */
|
||||
@Override
|
||||
public void setShapeAppearanceModel(@NonNull ShapeAppearanceModel shapeAppearance) {
|
||||
getImpl().setShapeAppearance(shapeAppearance, isUsingDefaultCorner(shapeAppearance));
|
||||
getImpl().setShapeAppearance(shapeAppearance);
|
||||
}
|
||||
|
||||
/** Returns the {@link ShapeAppearanceModel} for this {@link FloatingActionButton}. */
|
||||
@ -691,7 +689,6 @@ public class FloatingActionButton extends VisibilityAwareImageButton
|
||||
customSize = NO_CUSTOM_SIZE;
|
||||
if (size != this.size) {
|
||||
this.size = size;
|
||||
getImpl().updateSize();
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
@ -752,7 +749,6 @@ public class FloatingActionButton extends VisibilityAwareImageButton
|
||||
|
||||
if (size != customSize) {
|
||||
customSize = size;
|
||||
getImpl().updateSize();
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
@ -1362,11 +1358,6 @@ public class FloatingActionButton extends VisibilityAwareImageButton
|
||||
getImpl().removeTransformationCallback(new TransformationCallbackWrapper(listener));
|
||||
}
|
||||
|
||||
private boolean isUsingDefaultCorner(@NonNull ShapeAppearanceModel shapeAppearance) {
|
||||
return ((AbsoluteCornerSize) shapeAppearance.getTopRightCornerSize()).getCornerSize()
|
||||
== ShapeAppearanceModel.PILL;
|
||||
}
|
||||
|
||||
class TransformationCallbackWrapper<T extends FloatingActionButton>
|
||||
implements InternalTransformationCallback {
|
||||
|
||||
|
||||
@ -86,7 +86,6 @@ class FloatingActionButtonImpl {
|
||||
@Nullable BorderDrawable borderDrawable;
|
||||
@Nullable Drawable contentBackground;
|
||||
|
||||
boolean usingDefaultCorner;
|
||||
boolean ensureMinTouchTargetSize;
|
||||
boolean shadowPaddingEnabled = true;
|
||||
float elevation;
|
||||
@ -305,14 +304,8 @@ class FloatingActionButtonImpl {
|
||||
}
|
||||
}
|
||||
|
||||
final void setShapeAppearance(
|
||||
@NonNull ShapeAppearanceModel shapeAppearance, boolean usingDefaultCorner) {
|
||||
if (usingDefaultCorner) {
|
||||
shapeAppearance = shapeAppearance.withCornerRadius(view.getSizeDimension() / 2);
|
||||
}
|
||||
|
||||
final void setShapeAppearance(@NonNull ShapeAppearanceModel shapeAppearance) {
|
||||
this.shapeAppearance = shapeAppearance;
|
||||
this.usingDefaultCorner = usingDefaultCorner;
|
||||
if (shapeDrawable != null) {
|
||||
shapeDrawable.setShapeAppearanceModel(shapeAppearance);
|
||||
}
|
||||
@ -645,16 +638,6 @@ class FloatingActionButtonImpl {
|
||||
// Ignore pre-v21
|
||||
}
|
||||
|
||||
void updateSize() {
|
||||
if (!usingDefaultCorner || shapeDrawable == null || shapeAppearance == null) {
|
||||
// Leave shape appearance as is.
|
||||
return;
|
||||
}
|
||||
|
||||
setShapeAppearance(
|
||||
shapeAppearance.withCornerRadius(view.getSizeDimension() / 2f), usingDefaultCorner);
|
||||
}
|
||||
|
||||
final void updatePadding() {
|
||||
Rect rect = tmpRect;
|
||||
getPadding(rect);
|
||||
@ -736,9 +719,6 @@ class FloatingActionButtonImpl {
|
||||
|
||||
MaterialShapeDrawable createShapeDrawable() {
|
||||
ShapeAppearanceModel shapeAppearance = checkNotNull(this.shapeAppearance);
|
||||
if (usingDefaultCorner) {
|
||||
shapeAppearance = shapeAppearance.withCornerRadius(view.getSizeDimension() / 2f);
|
||||
}
|
||||
return new MaterialShapeDrawable(shapeAppearance);
|
||||
}
|
||||
|
||||
|
||||
@ -229,9 +229,6 @@ class FloatingActionButtonImplLollipop extends FloatingActionButtonImpl {
|
||||
@Override
|
||||
MaterialShapeDrawable createShapeDrawable() {
|
||||
ShapeAppearanceModel shapeAppearance = checkNotNull(this.shapeAppearance);
|
||||
if (usingDefaultCorner) {
|
||||
shapeAppearance = shapeAppearance.withCornerRadius(view.getSizeDimension() / 2f);
|
||||
}
|
||||
return new AlwaysStatefulMaterialShapeDrawable(shapeAppearance);
|
||||
}
|
||||
|
||||
|
||||
@ -51,8 +51,7 @@
|
||||
</style>
|
||||
|
||||
<style name="ShapeAppearanceOverlay.MaterialComponents.FloatingActionButton" parent="">
|
||||
<!-- use @null to change to 50% programmatically. -->
|
||||
<item name="cornerSize">@null</item>
|
||||
<item name="cornerSize">50%</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.MaterialComponents.ExtendedFloatingActionButton" parent="Widget.MaterialComponents.Button">
|
||||
@ -82,10 +81,15 @@
|
||||
<item name="iconTint">@color/mtrl_extended_fab_text_color_selector</item>
|
||||
<item name="rippleColor">@color/mtrl_extended_fab_ripple_color</item>
|
||||
<item name="shapeAppearanceOverlay">
|
||||
@style/ShapeAppearanceOverlay.MaterialComponents.FloatingActionButton
|
||||
@style/ShapeAppearanceOverlay.MaterialComponents.ExtendedFloatingActionButton
|
||||
</item>
|
||||
</style>
|
||||
|
||||
<style name="ShapeAppearanceOverlay.MaterialComponents.ExtendedFloatingActionButton" parent="">
|
||||
<!-- TODO(b/121352029): ExtendedFloatingActionButton adds 1px to the height -->
|
||||
<item name="cornerSize">@null</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.MaterialComponents.ExtendedFloatingActionButton.Icon" parent="Widget.MaterialComponents.ExtendedFloatingActionButton">
|
||||
<item name="android:gravity">start|center_vertical</item>
|
||||
<item name="android:paddingStart" tools:ignore="NewApi">
|
||||
|
||||
@ -60,6 +60,7 @@ import android.util.AttributeSet;
|
||||
import com.google.android.material.color.MaterialColors;
|
||||
import com.google.android.material.elevation.ElevationOverlayProvider;
|
||||
import com.google.android.material.shadow.ShadowRenderer;
|
||||
import com.google.android.material.shape.ShapeAppearanceModel.CornerSizeUnaryOperator;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@ -1096,7 +1097,20 @@ public class MaterialShapeDrawable extends Drawable implements TintAwareDrawable
|
||||
private void calculateStrokePath() {
|
||||
// Adjust corner radius in order to draw the stroke so that the corners of the background are
|
||||
// drawn on top of the edges.
|
||||
strokeShapeAppearance = getShapeAppearanceModel().withAdjustedCorners(-getStrokeInsetLength());
|
||||
strokeShapeAppearance =
|
||||
getShapeAppearanceModel()
|
||||
.withTransformedCornerSizes(
|
||||
new CornerSizeUnaryOperator() {
|
||||
@NonNull
|
||||
@Override
|
||||
public CornerSize apply(@NonNull CornerSize cornerSize) {
|
||||
// Don't adjust for relative corners they will change by themselves when the
|
||||
// bounds change.
|
||||
return cornerSize instanceof RelativeCornerSize
|
||||
? cornerSize
|
||||
: new AdjustedCornerSize(-getStrokeInsetLength(), cornerSize);
|
||||
}
|
||||
});
|
||||
|
||||
pathProvider.calculatePath(
|
||||
strokeShapeAppearance,
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2019 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 android.graphics.RectF;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A {@link CornerSize} that takes a percent and computes the size used based on the height of the
|
||||
* shape.
|
||||
*/
|
||||
public final class RelativeCornerSize implements CornerSize {
|
||||
|
||||
private final float percent;
|
||||
|
||||
public RelativeCornerSize(float percent) {
|
||||
this.percent = percent;
|
||||
}
|
||||
|
||||
/** Returns the relative percent used for this {@link CornerSize} */
|
||||
public float getRelativePercent() {
|
||||
return percent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getCornerSize(@NonNull RectF bounds) {
|
||||
return percent * bounds.height();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof RelativeCornerSize)) {
|
||||
return false;
|
||||
}
|
||||
RelativeCornerSize that = (RelativeCornerSize) o;
|
||||
return percent == that.percent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
Object[] hashedFields = {percent};
|
||||
return Arrays.hashCode(hashedFields);
|
||||
}
|
||||
}
|
||||
@ -413,15 +413,6 @@ public class ShapeAppearanceModel {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adjusts all the corners by the offset. */
|
||||
@NonNull
|
||||
public Builder adjustCorners(@Dimension float offset) {
|
||||
return setTopLeftCornerSize(new AdjustedCornerSize(offset, topLeftCornerSize))
|
||||
.setTopRightCornerSize(new AdjustedCornerSize(offset, topRightCornerSize))
|
||||
.setBottomRightCornerSize(new AdjustedCornerSize(offset, bottomRightCornerSize))
|
||||
.setBottomLeftCornerSize(new AdjustedCornerSize(offset, bottomLeftCornerSize));
|
||||
}
|
||||
|
||||
/** Pulls the corner size from specific CornerTreatments for backwards compatibility */
|
||||
private static float compatCornerTreatmentSize(CornerTreatment treatment) {
|
||||
if (treatment instanceof RoundedCornerTreatment) {
|
||||
@ -563,13 +554,15 @@ public class ShapeAppearanceModel {
|
||||
// floats.
|
||||
return new AbsoluteCornerSize(
|
||||
TypedValue.complexToDimensionPixelSize(value.data, a.getResources().getDisplayMetrics()));
|
||||
} else if (value.type == TypedValue.TYPE_FRACTION) {
|
||||
return new RelativeCornerSize(value.getFraction(1.0f, 1.0f));
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Constant corner radius value to indicate that shape should use 50% height corner radii
|
||||
public static final Integer PILL = -1;
|
||||
public static final CornerSize PILL = new RelativeCornerSize(0.5f);
|
||||
|
||||
CornerTreatment topLeftCorner;
|
||||
CornerTreatment topRightCorner;
|
||||
@ -739,18 +732,6 @@ public class ShapeAppearanceModel {
|
||||
return bottomEdge;
|
||||
}
|
||||
|
||||
/** Checks if all four corners of this ShapeAppearanceModel are of size {@link #PILL}. */
|
||||
public boolean isUsingPillCorner() {
|
||||
return isCornerPill(getTopRightCornerSize())
|
||||
&& isCornerPill(getTopLeftCornerSize())
|
||||
&& isCornerPill(getBottomLeftCornerSize())
|
||||
&& isCornerPill(getBottomRightCornerSize());
|
||||
}
|
||||
|
||||
private boolean isCornerPill(CornerSize cornerSize) {
|
||||
return ((AbsoluteCornerSize) cornerSize).getCornerSize() == PILL;
|
||||
}
|
||||
|
||||
/** Returns a builder with the edges and corners from this {@link ShapeAppearanceModel} */
|
||||
@NonNull
|
||||
public Builder toBuilder() {
|
||||
@ -772,12 +753,31 @@ public class ShapeAppearanceModel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this {@link ShapeAppearanceModel} with the same edges and corners, but with
|
||||
* the corner radius for all corners offset by an adjustment.
|
||||
* A UnaryOperator that takes and returns a CornerSize.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RestrictTo(LIBRARY_GROUP)
|
||||
public interface CornerSizeUnaryOperator {
|
||||
@NonNull
|
||||
CornerSize apply(@NonNull CornerSize cornerSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this {@link ShapeAppearanceModel} with the same edges and corners, but with
|
||||
* the corner radius for all corners converted by a {@link CornerSizeUnaryOperator}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RestrictTo(LIBRARY_GROUP)
|
||||
@NonNull
|
||||
public ShapeAppearanceModel withAdjustedCorners(float offset) {
|
||||
return toBuilder().adjustCorners(offset).build();
|
||||
public ShapeAppearanceModel withTransformedCornerSizes(@NonNull CornerSizeUnaryOperator op) {
|
||||
return toBuilder()
|
||||
.setTopLeftCornerSize(op.apply(getTopLeftCornerSize()))
|
||||
.setTopRightCornerSize(op.apply(getTopLeftCornerSize()))
|
||||
.setBottomLeftCornerSize(op.apply(getBottomLeftCornerSize()))
|
||||
.setBottomRightCornerSize(op.apply(getBottomLeftCornerSize()))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -26,15 +26,15 @@
|
||||
|
||||
<declare-styleable name="ShapeAppearance">
|
||||
<!-- Corner size to be used in the ShapeAppearance. All corners default to this value -->
|
||||
<attr name="cornerSize" format="dimension"/>
|
||||
<attr name="cornerSize" format="dimension|fraction"/>
|
||||
<!-- Top left corner size to be used in the ShapeAppearance. -->
|
||||
<attr name="cornerSizeTopLeft" format="dimension"/>
|
||||
<attr name="cornerSizeTopLeft" format="dimension|fraction"/>
|
||||
<!-- Top right corner size to be used in the ShapeAppearance. -->
|
||||
<attr name="cornerSizeTopRight" format="dimension"/>
|
||||
<attr name="cornerSizeTopRight" format="dimension|fraction"/>
|
||||
<!-- Bottom right corner size to be used in the ShapeAppearance. -->
|
||||
<attr name="cornerSizeBottomRight" format="dimension"/>
|
||||
<attr name="cornerSizeBottomRight" format="dimension|fraction"/>
|
||||
<!-- Bottom left corner size to be used in the ShapeAppearance. -->
|
||||
<attr name="cornerSizeBottomLeft" format="dimension"/>
|
||||
<attr name="cornerSizeBottomLeft" format="dimension|fraction"/>
|
||||
|
||||
<!-- Corner family to be used in the ShapeAppearance. All corners default to this value -->
|
||||
<attr name="cornerFamily" format="enum">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user