以编程方式更改Drawable的背景,并保持拐角半径

问题描述:

interview_timeline_row.xml

interview_timeline_row.xml

<LinearLayout
    android:id="@+id/interviewTimelineIconLayout"
    android:layout_width="52dp"
    android:layout_height="52dp"
    android:layout_marginTop="20dp"
    android:background="@drawable/timeline_row_icon_layout_bg"
    android:gravity="center"
    android:orientation="horizontal"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <ImageView
        android:id="@+id/interviewTimelineRowIcon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center"
        android:adjustViewBounds="false"
        android:cropToPadding="false"
        android:padding="6dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>

timeline_row_icon_layout_bg.xml

timeline_row_icon_layout_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <corners android:radius="@dimen/_50sdp" />

    <stroke android:width="1dp" android:color="@color/white" />

    <solid android:color="@color/ic_rescheduled"/> //need to add this programatically

</shape>

InterviewTimeline.java

InterviewTimeline.java

iconBg = row.findViewById(R.id.interviewTimelineIconLayout);

iconBg.setBackgroundColor(getResources().getColor(R.color.ic_rescheduled)); //this is the wrong way to go about it

我想在我的应用程序的各个位置使用timeline_row_icon_layout_bg.xml,并且每次都应使用不同的背景色.如果我使用iconBg.setBackgroundColor()方法,则它将忽略半径,并且背景颜色为方形.

I want to use the timeline_row_icon_layout_bg.xml in various places in my app, and it should have a different background color each time. If I use the iconBg.setBackgroundColor() method, then it ignores the radius and I have a square background color.

由于您只是使用形状来创建带有圆角和边框的布局,因此第一种选择是将LinearLayout包裹在CardView内然后在卡片上应用拐角半径,笔触和背景颜色.

Since you are just using the shape to create a layout with rounded corners and a border, the first option is to wrap your LinearLayout inside a CardView and then apply to the card the corner radius, the stroke and the background color.

否则,您可以使用 MaterialShapeDrawable 包含在材料组件库中,以绘制自定义形状.

Otherwise you could use the MaterialShapeDrawable included in the Material Components Library to draw custom shapes.

只需从LinearLayout中删除android:background:

Just remove from the LinearLayout the android:background:

<LinearLayout
    android:id="@+id/interviewTimelineIconLayout"
    android:layout_width=".."
    android:layout_height="..
    ..>

    <!-- ..... -->

</LinearLayout>

然后可以在代码中应用ShapeAppearanceModel.像这样:

Then in your code you can apply a ShapeAppearanceModel. Something like:

        float radius = getResources().getDimension(R.dimen.corner_radius);

        LinearLayout linearLayout= findViewById(R.id.interviewTimelineIconLayout);
        ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
            .toBuilder()
            .setAllCorners(CornerFamily.ROUNDED,radius)
            .build();

        MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel);
        //Fill the LinearLayout with your color
        shapeDrawable.setFillColor(ContextCompat.getColorStateList(this,R.color.yourColor));
        //Stroke color and width
        shapeDrawable.setStrokeWidth(2.0f);
        shapeDrawable.setStrokeColor(...);

        ViewCompat.setBackground(linearLayout,shapeDrawable);

通过这种方式,您可以轻松地更改和设置颜色背景和笔触.

In this way you easily change and set the color background and the stroke.