问题
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
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.
回答1:
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.
Otherwise you could use the MaterialShapeDrawable included in the Material Components Library to draw custom shapes.
Just remove from the LinearLayout the android:background
:
<LinearLayout
android:id="@+id/interviewTimelineIconLayout"
android:layout_width=".."
android:layout_height="..
..>
<!-- ..... -->
</LinearLayout>
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.
回答2:
Copy your "timeline_row_icon_layout_bg.xml" file and rename it "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>
And you can set background to layout:
iconBg.setBackgroundResource(R.drawable.timeline_row_icon_layout_bg_new);
回答3:
set the background of LinearLayout
programmatically.
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
move the shape drawable timeline_row_icon_layout_bg
to the drawable resource folder.
来源:https://stackoverflow.com/questions/61144528/programatically-change-background-of-drawable-maintaining-the-corner-radius