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

Programatically change background of Drawable, maintaining the corner radius

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

<?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

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() 方法,那么它会忽略半径并且我有一个正方形背景色。

以编程方式设置 LinearLayout 的背景。

val bgDrawable = resources.getDrawable(R.drawable.timeline_row_icon_layout_bg, null).apply{
    colorFilter = PorterDuffColorFilter(
            ResourcesCompat.getColor(resources, R.color.ic_rescheduled, null),
            PorterDuff.Mode.SRC_IN
        )

}

iconBg.background = bgDrawable

将可绘制形状 timeline_row_icon_layout_bg 移动到可绘制资源文件夹。

复制您的 "timeline_row_icon_layout_bg.xml" 文件并重命名 "timeline_row_icon_layout_bg_new.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/put_the_color_you_need" />

</shape>

并且您可以将背景设置为布局:

iconBg.setBackgroundResource(R.drawable.timeline_row_icon_layout_bg_new);

由于您只是使用形状来创建带有圆角和边框的布局,因此第一个选项是将 LinearLayout 包裹在 CardView 中,然后将圆角应用于卡片半径、笔划和背景颜色。

否则你可以使用 MaterialShapeDrawable included in the Material Components Library to draw custom shapes

只需从 LinearLayout 中删除 android:background:

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

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

</LinearLayout>

然后在您的代码中您可以应用 ShapeAppearanceModel。类似于:

        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);

通过这种方式,您可以轻松更改和设置颜色背景和描边。