Java源码示例:com.google.android.material.shape.ShapeAppearanceModel

示例1
private void createMaterialShapeDrawable(
        Context context,
        AttributeSet attrs,
        boolean hasBackgroundTint,
        @Nullable ColorStateList bottomSheetColor) {
    if (this.shapeThemingEnabled) {
        this.shapeAppearanceModelDefault =
                new ShapeAppearanceModel(context, attrs, R.attr.bottomSheetStyle, DEF_STYLE_RES);

        this.materialShapeDrawable = new MaterialShapeDrawable(shapeAppearanceModelDefault);
        this.materialShapeDrawable.initializeElevationOverlay(context);

        if (hasBackgroundTint && bottomSheetColor != null) {
            materialShapeDrawable.setFillColor(bottomSheetColor);
        } else {
            // If the tint isn't set, use the theme default background color.
            TypedValue defaultColor = new TypedValue();
            context.getTheme().resolveAttribute(android.R.attr.colorBackground, defaultColor, true);
            materialShapeDrawable.setTint(defaultColor.data);
        }
    }
}
 
示例2
private void setUpBottomAppBarShapeAppearance() {
  ShapeAppearanceModel fabShapeAppearanceModel = fab.getShapeAppearanceModel();
  boolean cutCornersFab =
      fabShapeAppearanceModel.getBottomLeftCorner() instanceof CutCornerTreatment
          && fabShapeAppearanceModel.getBottomRightCorner() instanceof CutCornerTreatment;

  BottomAppBarTopEdgeTreatment topEdge =
      cutCornersFab
          ? new BottomAppBarCutCornersTopEdge(
              bar.getFabCradleMargin(),
              bar.getFabCradleRoundedCornerRadius(),
              bar.getCradleVerticalOffset())
          : new BottomAppBarTopEdgeTreatment(
              bar.getFabCradleMargin(),
              bar.getFabCradleRoundedCornerRadius(),
              bar.getCradleVerticalOffset());

  MaterialShapeDrawable babBackground = (MaterialShapeDrawable) bar.getBackground();
  babBackground.setShapeAppearanceModel(
      babBackground.getShapeAppearanceModel().toBuilder().setTopEdge(topEdge).build());
}
 
示例3
private void createMaterialShapeDrawable(
    @NonNull Context context,
    AttributeSet attrs,
    boolean hasBackgroundTint,
    @Nullable ColorStateList bottomSheetColor) {
  if (this.shapeThemingEnabled) {
    this.shapeAppearanceModelDefault =
        ShapeAppearanceModel.builder(context, attrs, R.attr.bottomSheetStyle, DEF_STYLE_RES)
            .build();

    this.materialShapeDrawable = new MaterialShapeDrawable(shapeAppearanceModelDefault);
    this.materialShapeDrawable.initializeElevationOverlay(context);

    if (hasBackgroundTint && bottomSheetColor != null) {
      materialShapeDrawable.setFillColor(bottomSheetColor);
    } else {
      // If the tint isn't set, use the theme default background color.
      TypedValue defaultColor = new TypedValue();
      context.getTheme().resolveAttribute(android.R.attr.colorBackground, defaultColor, true);
      materialShapeDrawable.setTint(defaultColor.data);
    }
  }
}
 
示例4
void setShapeAppearanceModel(@NonNull ShapeAppearanceModel shapeAppearanceModel) {
  this.shapeAppearanceModel = shapeAppearanceModel;
  bgDrawable.setShapeAppearanceModel(shapeAppearanceModel);
  bgDrawable.setShadowBitmapDrawingEnable(!bgDrawable.isRoundRect());
  if (foregroundContentDrawable != null) {
    foregroundContentDrawable.setShapeAppearanceModel(shapeAppearanceModel);
  }

  if (foregroundShapeDrawable != null) {
    foregroundShapeDrawable.setShapeAppearanceModel(shapeAppearanceModel);
  }

  if (compatRippleDrawable != null) {
    compatRippleDrawable.setShapeAppearanceModel(shapeAppearanceModel);
  }
}
 
示例5
/**
 * Creates a {@link MaterialShapeDrawable} to use as the {@code itemBackground} and wraps it in an
 * {@link InsetDrawable} for margins.
 *
 * @param a The TintTypedArray containing the resolved NavigationView style attributes.
 */
@NonNull
private final Drawable createDefaultItemBackground(@NonNull TintTypedArray a) {
  int shapeAppearanceResId = a.getResourceId(R.styleable.NavigationView_itemShapeAppearance, 0);
  int shapeAppearanceOverlayResId =
      a.getResourceId(R.styleable.NavigationView_itemShapeAppearanceOverlay, 0);
  MaterialShapeDrawable materialShapeDrawable =
      new MaterialShapeDrawable(
          ShapeAppearanceModel.builder(
                  getContext(), shapeAppearanceResId, shapeAppearanceOverlayResId)
              .build());
  materialShapeDrawable.setFillColor(
      MaterialResources.getColorStateList(
          getContext(), a, R.styleable.NavigationView_itemShapeFillColor));

  int insetLeft = a.getDimensionPixelSize(R.styleable.NavigationView_itemShapeInsetStart, 0);
  int insetTop = a.getDimensionPixelSize(R.styleable.NavigationView_itemShapeInsetTop, 0);
  int insetRight = a.getDimensionPixelSize(R.styleable.NavigationView_itemShapeInsetEnd, 0);
  int insetBottom = a.getDimensionPixelSize(R.styleable.NavigationView_itemShapeInsetBottom, 0);
  return new InsetDrawable(materialShapeDrawable, insetLeft, insetTop, insetRight, insetBottom);
}
 
示例6
private static ShapeAppearanceModel getShapeAppearance(
    @NonNull View view, @Nullable ShapeAppearanceModel shapeAppearanceModelOverride) {
  if (shapeAppearanceModelOverride != null) {
    return shapeAppearanceModelOverride;
  }

  if (view.getTag(R.id.mtrl_motion_snapshot_view) instanceof ShapeAppearanceModel) {
    return (ShapeAppearanceModel) view.getTag(R.id.mtrl_motion_snapshot_view);
  }

  Context context = view.getContext();
  int transitionShapeAppearanceResId = getTransitionShapeAppearanceResId(context);
  if (transitionShapeAppearanceResId != -1) {
    return ShapeAppearanceModel.builder(context, transitionShapeAppearanceResId, 0).build();
  }

  if (view instanceof Shapeable) {
    return ((Shapeable) view).getShapeAppearanceModel();
  }

  return ShapeAppearanceModel.builder().build();
}
 
示例7
private void createMaterialShapeDrawable(
        @NonNull Context context,
        AttributeSet attrs,
        boolean hasBackgroundTint,
        @Nullable ColorStateList bottomSheetColor) {
    if (this.shapeThemingEnabled) {
        this.shapeAppearanceModelDefault =
                ShapeAppearanceModel.builder(context, attrs, R.attr.bottomSheetStyle, DEF_STYLE_RES)
                        .build();

        this.materialShapeDrawable = new MaterialShapeDrawable(shapeAppearanceModelDefault);
        this.materialShapeDrawable.initializeElevationOverlay(context);

        if (hasBackgroundTint && bottomSheetColor != null) {
            materialShapeDrawable.setFillColor(bottomSheetColor);
        } else {
            // If the tint isn't set, use the theme default background color.
            TypedValue defaultColor = new TypedValue();
            context.getTheme().resolveAttribute(android.R.attr.colorBackground, defaultColor, true);
            materialShapeDrawable.setTint(defaultColor.data);
        }
    }
}
 
示例8
/**
 * Creates a demo fragment with an image that can change shape and randomely makes the dog image
 * wink.
 */
@Override
public View onCreateDemoView(
    LayoutInflater layoutInflater, @Nullable ViewGroup viewGroup, @Nullable Bundle bundle) {
  View view =
      layoutInflater.inflate(R.layout.catalog_imageview, viewGroup, false /* attachToRoot */);
  MaterialButtonToggleGroup toggleGroup = view.findViewById(R.id.togglegroup);
  ShapeableImageView imageView = view.findViewById(R.id.image_view);

  SparseArray<ShapeAppearanceModel> shapes = new SparseArray<>();
  shapes.put(
      R.id.button_diamond,
      ShapeAppearanceModel.builder()
          .setAllCorners(CornerFamily.CUT, /*cornerSize=*/0f)
          .setAllCornerSizes(ShapeAppearanceModel.PILL)
          .build());
  shapes.put(
      R.id.button_circle,
      ShapeAppearanceModel.builder().setAllCornerSizes(ShapeAppearanceModel.PILL).build());
  shapes.put(R.id.button_square, ShapeAppearanceModel.builder().build());

  Random random = new Random();

  toggleGroup.addOnButtonCheckedListener(
      (group, checkedId, isChecked) -> {
        if (!isChecked) {
          return;
        }

        // Randomly makes dog wink.
        imageView.setImageResource(
            random.nextBoolean() ? R.drawable.dog_image : R.drawable.dog_image_wink);
        imageView.setShapeAppearanceModel(shapes.get(checkedId));
      });

  return view;
}
 
示例9
/**
 * Sets the radius of the thumb in pixels.
 *
 * @see #getThumbRadius()
 * @attr ref com.google.android.material.R.styleable#Slider_thumbRadius
 */
public void setThumbRadius(@IntRange(from = 0) @Dimension int radius) {
  if (radius == thumbRadius) {
    return;
  }

  thumbRadius = radius;

  thumbDrawable.setShapeAppearanceModel(
      ShapeAppearanceModel.builder().setAllCorners(CornerFamily.ROUNDED, thumbRadius).build());
  thumbDrawable.setBounds(0, 0, thumbRadius * 2, thumbRadius * 2);

  postInvalidate();
}
 
示例10
@Override
public void setShapeModel(@NotNull ShapeAppearanceModel model) {
    this.shapeModel = model;
    shadowDrawable = new MaterialShapeDrawable(shapeModel);
    if (getWidth() > 0 && getHeight() > 0)
        updateCorners();
    if (!Carbon.IS_LOLLIPOP_OR_HIGHER)
        postInvalidate();
}
 
示例11
@Override
public void setShapeModel(@NotNull ShapeAppearanceModel model) {
    this.shapeModel = model;
    shadowDrawable = new MaterialShapeDrawable(shapeModel);
    if (getWidth() > 0 && getHeight() > 0)
        updateCorners();
    if (!Carbon.IS_LOLLIPOP_OR_HIGHER)
        postInvalidate();
}
 
示例12
@Override
public void setShapeModel(@NotNull ShapeAppearanceModel model) {
    this.shapeModel = model;
    shadowDrawable = new MaterialShapeDrawable(shapeModel);
    if (getWidth() > 0 && getHeight() > 0)
        updateCorners();
    if (!Carbon.IS_LOLLIPOP_OR_HIGHER)
        postInvalidate();
}
 
示例13
final void setShapeAppearance(@NonNull ShapeAppearanceModel shapeAppearance) {
  this.shapeAppearance = shapeAppearance;
  if (shapeDrawable != null) {
    shapeDrawable.setShapeAppearanceModel(shapeAppearance);
  }

  if (rippleDrawable instanceof Shapeable) {
    ((Shapeable) rippleDrawable).setShapeAppearanceModel(shapeAppearance);
  }

  if (borderDrawable != null) {
    borderDrawable.setShapeAppearanceModel(shapeAppearance);
  }
}
 
示例14
private static ShapeAppearanceModel captureShapeAppearance(
    @NonNull View view,
    @NonNull RectF bounds,
    @Nullable ShapeAppearanceModel shapeAppearanceModelOverride) {
  ShapeAppearanceModel shapeAppearanceModel =
      getShapeAppearance(view, shapeAppearanceModelOverride);
  return convertToRelativeCornerSizes(shapeAppearanceModel, bounds);
}
 
示例15
@Override
public void setShapeModel(@NotNull ShapeAppearanceModel model) {
    this.shapeModel = model;
    shadowDrawable = new MaterialShapeDrawable(shapeModel);
    if (getWidth() > 0 && getHeight() > 0)
        updateCorners();
    if (!Carbon.IS_LOLLIPOP_OR_HIGHER)
        postInvalidate();
}
 
示例16
private void drawElevationShadowWithPaintShadowLayer(Canvas canvas) {
  ShapeAppearanceModel currentShapeAppearanceModel =
      maskEvaluator.getCurrentShapeAppearanceModel();
  if (currentShapeAppearanceModel.isRoundRect(currentMaskBounds)) {
    // Optimize for the common round rect case, should also account for regular rect
    float radius =
        currentShapeAppearanceModel.getTopLeftCornerSize().getCornerSize(currentMaskBounds);
    canvas.drawRoundRect(currentMaskBounds, radius, radius, shadowPaint);
  } else {
    // This will be less performant but should be a minority of cases
    canvas.drawPath(maskEvaluator.getPath(), shadowPaint);
  }
}
 
示例17
private static ShapeAppearanceModel captureShapeAppearance(
    @NonNull View view,
    @NonNull RectF bounds,
    @Nullable ShapeAppearanceModel shapeAppearanceModelOverride) {
  ShapeAppearanceModel shapeAppearanceModel =
      getShapeAppearance(view, shapeAppearanceModelOverride);
  return convertToRelativeCornerSizes(shapeAppearanceModel, bounds);
}
 
示例18
@Override
public void setShapeModel(@NotNull ShapeAppearanceModel model) {
    this.shapeModel = model;
    shadowDrawable = new MaterialShapeDrawable(shapeModel);
    if (getWidth() > 0 && getHeight() > 0)
        updateCorners();
    if (!Carbon.IS_LOLLIPOP_OR_HIGHER)
        postInvalidate();
}
 
示例19
static ShapeAppearanceModel transformCornerSizes(
    ShapeAppearanceModel shapeAppearanceModel1,
    ShapeAppearanceModel shapeAppearanceModel2,
    RectF shapeAppearanceModel1Bounds,
    CornerSizeBinaryOperator op) {

  // If all of shapeAppearanceModel's corner sizes are 0, consider the shape appearance
  // insignificant compared to shapeAppearanceModel2 and use shapeAppearanceModel2's
  // corner family instead.
  ShapeAppearanceModel shapeAppearanceModel =
      isShapeAppearanceSignificant(shapeAppearanceModel1, shapeAppearanceModel1Bounds)
          ? shapeAppearanceModel1
          : shapeAppearanceModel2;

  return shapeAppearanceModel.toBuilder()
      .setTopLeftCornerSize(
          op.apply(
              shapeAppearanceModel1.getTopLeftCornerSize(),
              shapeAppearanceModel2.getTopLeftCornerSize()))
      .setTopRightCornerSize(
          op.apply(
              shapeAppearanceModel1.getTopRightCornerSize(),
              shapeAppearanceModel2.getTopRightCornerSize()))
      .setBottomLeftCornerSize(
          op.apply(
              shapeAppearanceModel1.getBottomLeftCornerSize(),
              shapeAppearanceModel2.getBottomLeftCornerSize()))
      .setBottomRightCornerSize(
          op.apply(
              shapeAppearanceModel1.getBottomRightCornerSize(),
              shapeAppearanceModel2.getBottomRightCornerSize()))
      .build();
}
 
示例20
private static boolean isShapeAppearanceSignificant(
    ShapeAppearanceModel shapeAppearanceModel, RectF bounds) {
  return shapeAppearanceModel.getTopLeftCornerSize().getCornerSize(bounds) != 0
      || shapeAppearanceModel.getTopRightCornerSize().getCornerSize(bounds) != 0
      || shapeAppearanceModel.getBottomRightCornerSize().getCornerSize(bounds) != 0
      || shapeAppearanceModel.getBottomLeftCornerSize().getCornerSize(bounds) != 0;
}
 
示例21
static ShapeAppearanceModel lerp(
    ShapeAppearanceModel startValue,
    ShapeAppearanceModel endValue,
    final RectF startBounds,
    final RectF endBounds,
    final @FloatRange(from = 0.0, to = 1.0) float startFraction,
    final @FloatRange(from = 0.0, to = 1.0) float endFraction,
    final @FloatRange(from = 0.0, to = 1.0) float fraction) {
  if (fraction < startFraction) {
    return startValue;
  }
  if (fraction > endFraction) {
    return endValue;
  }

  return transformCornerSizes(
      startValue,
      endValue,
      startBounds,
      new CornerSizeBinaryOperator() {
        @NonNull
        @Override
        public CornerSize apply(
            @NonNull CornerSize cornerSize1, @NonNull CornerSize cornerSize2) {
          float startCornerSize = cornerSize1.getCornerSize(startBounds);
          float endCornerSize = cornerSize2.getCornerSize(endBounds);
          float cornerSize =
              lerp(startCornerSize, endCornerSize, startFraction, endFraction, fraction);

          return new AbsoluteCornerSize(cornerSize);
        }
      });
}
 
示例22
/** Update the mask used by this evaluator based on a given progress. */
void evaluate(
    float progress,
    ShapeAppearanceModel startShapeAppearanceModel,
    ShapeAppearanceModel endShapeAppearanceModel,
    RectF currentStartBounds,
    RectF currentStartBoundsMasked,
    RectF currentEndBoundsMasked,
    ProgressThresholds shapeMaskThresholds) {

  // Animate shape appearance corner changes over range of `progress` & use this when
  // drawing the container background & images
  float shapeStartFraction = shapeMaskThresholds.getStart();
  float shapeEndFraction = shapeMaskThresholds.getEnd();
  currentShapeAppearanceModel =
      lerp(
          startShapeAppearanceModel,
          endShapeAppearanceModel,
          currentStartBounds,
          currentEndBoundsMasked,
          shapeStartFraction,
          shapeEndFraction,
          progress);

  pathProvider.calculatePath(currentShapeAppearanceModel, 1, currentStartBoundsMasked, startPath);
  pathProvider.calculatePath(currentShapeAppearanceModel, 1, currentEndBoundsMasked, endPath);

  // Union the two paths on API 23 and above. API 21 and 22 have problems with this
  // call and instead use the start and end paths to clip.
  if (VERSION.SDK_INT >= VERSION_CODES.M) {
    path.op(startPath, endPath, Op.UNION);
  }
}
 
示例23
static ShapeAppearanceModel convertToRelativeCornerSizes(
    ShapeAppearanceModel shapeAppearanceModel, final RectF bounds) {
  return shapeAppearanceModel.withTransformedCornerSizes(
      new CornerSizeUnaryOperator() {
        @NonNull
        @Override
        public CornerSize apply(@NonNull CornerSize cornerSize) {
          return cornerSize instanceof RelativeCornerSize
              ? cornerSize
              : new RelativeCornerSize(cornerSize.getCornerSize(bounds) / bounds.height());
        }
      });
}
 
示例24
@Override
public void setShapeModel(@NotNull ShapeAppearanceModel model) {
    this.shapeModel = model;
    shadowDrawable = new MaterialShapeDrawable(shapeModel);
    if (getWidth() > 0 && getHeight() > 0)
        updateCorners();
    if (!Carbon.IS_LOLLIPOP_OR_HIGHER)
        postInvalidate();
}
 
示例25
private static boolean isShapeAppearanceSignificant(
    ShapeAppearanceModel shapeAppearanceModel, RectF bounds) {
  return shapeAppearanceModel.getTopLeftCornerSize().getCornerSize(bounds) != 0
      || shapeAppearanceModel.getTopRightCornerSize().getCornerSize(bounds) != 0
      || shapeAppearanceModel.getBottomRightCornerSize().getCornerSize(bounds) != 0
      || shapeAppearanceModel.getBottomLeftCornerSize().getCornerSize(bounds) != 0;
}
 
示例26
static ShapeAppearanceModel lerp(
    ShapeAppearanceModel startValue,
    ShapeAppearanceModel endValue,
    final RectF startBounds,
    final RectF endBounds,
    final @FloatRange(from = 0.0, to = 1.0) float startFraction,
    final @FloatRange(from = 0.0, to = 1.0) float endFraction,
    final @FloatRange(from = 0.0, to = 1.0) float fraction) {
  if (fraction < startFraction) {
    return startValue;
  }
  if (fraction > endFraction) {
    return endValue;
  }

  return transformCornerSizes(
      startValue,
      endValue,
      startBounds,
      new CornerSizeBinaryOperator() {
        @NonNull
        @Override
        public CornerSize apply(
            @NonNull CornerSize cornerSize1, @NonNull CornerSize cornerSize2) {
          float startCornerSize = cornerSize1.getCornerSize(startBounds);
          float endCornerSize = cornerSize2.getCornerSize(endBounds);
          float cornerSize =
              lerp(startCornerSize, endCornerSize, startFraction, endFraction, fraction);

          return new AbsoluteCornerSize(cornerSize);
        }
      });
}
 
示例27
@Override
public void setShapeModel(@NotNull ShapeAppearanceModel model) {
    this.shapeModel = model;
    shadowDrawable = new MaterialShapeDrawable(shapeModel);
    if (getWidth() > 0 && getHeight() > 0)
        updateCorners();
    if (!Carbon.IS_LOLLIPOP_OR_HIGHER)
        postInvalidate();
}
 
示例28
public static void initCornerCutRadius(ShapeModelView shapeModelView, TypedArray a, int[] ids) {
    int carbon_cornerRadiusTopStart = ids[0];
    int carbon_cornerRadiusTopEnd = ids[1];
    int carbon_cornerRadiusBottomStart = ids[2];
    int carbon_cornerRadiusBottomEnd = ids[3];
    int carbon_cornerRadius = ids[4];
    int carbon_cornerCutTopStart = ids[5];
    int carbon_cornerCutTopEnd = ids[6];
    int carbon_cornerCutBottomStart = ids[7];
    int carbon_cornerCutBottomEnd = ids[8];
    int carbon_cornerCut = ids[9];

    float cornerRadius = Math.max(a.getDimension(carbon_cornerRadius, 0), 0.1f);
    float cornerRadiusTopStart = a.getDimension(carbon_cornerRadiusTopStart, cornerRadius);
    float cornerRadiusTopEnd = a.getDimension(carbon_cornerRadiusTopEnd, cornerRadius);
    float cornerRadiusBottomStart = a.getDimension(carbon_cornerRadiusBottomStart, cornerRadius);
    float cornerRadiusBottomEnd = a.getDimension(carbon_cornerRadiusBottomEnd, cornerRadius);
    float cornerCut = a.getDimension(carbon_cornerCut, 0);
    float cornerCutTopStart = a.getDimension(carbon_cornerCutTopStart, cornerCut);
    float cornerCutTopEnd = a.getDimension(carbon_cornerCutTopEnd, cornerCut);
    float cornerCutBottomStart = a.getDimension(carbon_cornerCutBottomStart, cornerCut);
    float cornerCutBottomEnd = a.getDimension(carbon_cornerCutBottomEnd, cornerCut);
    ShapeAppearanceModel model = ShapeAppearanceModel.builder()
            .setTopLeftCorner(cornerCutTopStart >= cornerRadiusTopStart ? new CutCornerTreatment(cornerCutTopStart) : new RoundedCornerTreatment(cornerRadiusTopStart))
            .setTopRightCorner(cornerCutTopEnd >= cornerRadiusTopEnd ? new CutCornerTreatment(cornerCutTopEnd) : new RoundedCornerTreatment(cornerRadiusTopEnd))
            .setBottomLeftCorner(cornerCutBottomStart >= cornerRadiusBottomStart ? new CutCornerTreatment(cornerCutBottomStart) : new RoundedCornerTreatment(cornerRadiusBottomStart))
            .setBottomRightCorner(cornerCutBottomEnd >= cornerRadiusBottomEnd ? new CutCornerTreatment(cornerCutBottomEnd) : new RoundedCornerTreatment(cornerRadiusBottomEnd))
            .build();
    shapeModelView.setShapeModel(model);
}
 
示例29
@Override
public void setShapeModel(@NotNull ShapeAppearanceModel model) {
    this.shapeModel = model;
    shadowDrawable = new MaterialShapeDrawable(shapeModel);
    if (getWidth() > 0 && getHeight() > 0)
        updateCorners();
    if (!Carbon.IS_LOLLIPOP_OR_HIGHER)
        postInvalidate();
}
 
示例30
private static void updateBuilderWithCornerData(
    ShapeAppearanceModel.Builder shapeAppearanceModelBuilder, @Nullable CornerData cornerData) {
  if (cornerData == null) {
    shapeAppearanceModelBuilder.setAllCornerSizes(0);
    return;
  }

  shapeAppearanceModelBuilder
      .setTopLeftCornerSize(cornerData.topLeft)
      .setBottomLeftCornerSize(cornerData.bottomLeft)
      .setTopRightCornerSize(cornerData.topRight)
      .setBottomRightCornerSize(cornerData.bottomRight);
}