How to add colored border on cardview?
Asked Answered
L

9

124

I am new to Android and this is my first question here.

I am trying to add a colored vertical border at the beginning of the cardview. How can I achieve it on xml ? I tried adding it with empty textview but it is messing up the whole cardview itself. Please check the picture link posted below for example.

Colored boroder on cardview

activity_main.xml

<android.support.v7.widget.CardView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    card_view:contentPadding="16dp"
    card_view:cardElevation="2dp"
    card_view:cardCornerRadius="5dp">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            style="@style/Base.TextAppearance.AppCompat.Headline"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Title" />

        <TextView
            style="@style/Base.TextAppearance.AppCompat.Body1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Content here" />
            
    </LinearLayout>

</android.support.v7.widget.CardView>

Many thanks

Levin answered 12/2, 2016 at 18:26 Comment(2)
do you need to use a cardview here? what about just a plane linearlayout and adding an ItemDecoration to your recycler view?Merilyn
I am a beginner on Android and recyclerview is bit advanced for my curent skill set. So, I am using cardview here.Levin
M
48

try doing:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    card_view:cardElevation="2dp"
    card_view:cardCornerRadius="5dp">

    <FrameLayout
        android:background="#FF0000"
        android:layout_width="4dp"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:orientation="vertical">

        <TextView
            style="@style/Base.TextAppearance.AppCompat.Headline"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Title" />

        <TextView
            style="@style/Base.TextAppearance.AppCompat.Body1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Content here" />

    </LinearLayout>

</android.support.v7.widget.CardView>

this removes the padding from the cardview and adds a FrameLayout with a color. You then need to fix the padding in the LinearLayout then for the other fields

Update

If you want to preserve the card corner radius create card_edge.xml in drawable folder:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#F00" />
    <size android:width="10dp"/>
    <padding android:bottom="0dp" android:left="0dp" android:right="0dp" android:top="0dp"/>
    <corners android:topLeftRadius="5dp" android:bottomLeftRadius="5dp"
        android:topRightRadius="0.1dp" android:bottomRightRadius="0.1dp"/>
</shape>

and in the frame layout use android:background="@drawable/card_edge"

Merilyn answered 12/2, 2016 at 18:36 Comment(3)
@GeorgeForster updated to use a drawable background to preserve the card corners if you want to still have themMerilyn
did not work for me. why 4 dp width for the frame layout?Nerva
This answer should not be marked as the correct one anymore. Correct one is the one from Aung Myo Lwin.Suppress
S
277

Start From the material design update, it support app:strokeColor and also app:strokeWidth. see more

to use material design update. add following code to build.gradle(:app)

dependencies {
    // ...
    implementation 'com.google.android.material:material:1.0.0'
    // ...
  }

and Change CardView to MaterialCardView

Sydneysydnor answered 28/2, 2019 at 9:7 Comment(7)
Couldn't find strokeColor.Ayesha
@PrimožKralj change cardView to MaterialCardViewEmendation
app:strokeColor is private when using androidx.Yacov
change CardView to MaterialCardViewSydneysydnor
MaterialCardView's full name is com.google.android.material.card.MaterialCardViewGianna
Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant).Wonderment
Known issue in strokeWidth - github.com/material-components/material-components-android/…Heterochromatic
M
48

try doing:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    card_view:cardElevation="2dp"
    card_view:cardCornerRadius="5dp">

    <FrameLayout
        android:background="#FF0000"
        android:layout_width="4dp"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:orientation="vertical">

        <TextView
            style="@style/Base.TextAppearance.AppCompat.Headline"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Title" />

        <TextView
            style="@style/Base.TextAppearance.AppCompat.Body1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Content here" />

    </LinearLayout>

</android.support.v7.widget.CardView>

this removes the padding from the cardview and adds a FrameLayout with a color. You then need to fix the padding in the LinearLayout then for the other fields

Update

If you want to preserve the card corner radius create card_edge.xml in drawable folder:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#F00" />
    <size android:width="10dp"/>
    <padding android:bottom="0dp" android:left="0dp" android:right="0dp" android:top="0dp"/>
    <corners android:topLeftRadius="5dp" android:bottomLeftRadius="5dp"
        android:topRightRadius="0.1dp" android:bottomRightRadius="0.1dp"/>
</shape>

and in the frame layout use android:background="@drawable/card_edge"

Merilyn answered 12/2, 2016 at 18:36 Comment(3)
@GeorgeForster updated to use a drawable background to preserve the card corners if you want to still have themMerilyn
did not work for me. why 4 dp width for the frame layout?Nerva
This answer should not be marked as the correct one anymore. Correct one is the one from Aung Myo Lwin.Suppress
E
38

As the accepted answer requires you to add a Frame Layout, here how you can do it with material design.

Add this if you haven't already

implementation 'com.google.android.material:material:1.0.0'

Now change to Cardview to MaterialCardView

<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:cardCornerRadius="8dp"
app:cardElevation="2dp"

app:strokeWidth="1dp"
app:strokeColor="@color/black">

Now you need to change the activity theme to Theme.Material. If you are using Theme.Appcompact I will suggest you to move to Theme.Material for future projects for having better material design in you app.

    <style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
Epanorthosis answered 12/2, 2021 at 9:21 Comment(2)
this solution make black border on all card, not only left as requestedSmiley
@Smiley dear change the stroke color as required...Epanorthosis
E
18

I think this solution may not be efficient but it serves the purpose and adds flexibility with the border width.

 <android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="40dp"
    android:layout_gravity="center"
    card_view:cardBackgroundColor="@color/some_color"
    card_view:cardCornerRadius="20dp"
    card_view:contentPadding="5dp"> <!-- Change it to customize the border width -->

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        card_view:cardCornerRadius="20dp"
        card_view:contentPadding="5dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

         <!-- Add your UI elements -->

        </RelativeLayout>
    </android.support.v7.widget.CardView>
</android.support.v7.widget.CardView>
Edelweiss answered 2/8, 2016 at 8:18 Comment(3)
This is a bad solution. You are adding the view hierarchy level, which would have performance penalty.Aglet
Good idea there should be available inner featuresGotcher
this isn't the most performant however I haven't had a massive hit using thisSibilant
A
13

CardView extends FrameLayout, so it support foreground attribute. Using foreground attribute can also add border easily.

layout as follows:

<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/link_card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:foreground="@drawable/bg_roundrect_ripple_light_border"
    app:cardCornerRadius="23dp"
    app:cardElevation="0dp">
</androidx.cardview.widget.CardView>

bg_roundrect_ripple_light_border.xml

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

    <item>
        <shape android:shape="rectangle">
            <stroke
                android:width="0.5dp"
                android:color="#DDDDDD" />
            <corners android:radius="23dp" />
        </shape>
    </item>

    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <corners android:radius="23dp" />
            <solid android:color="@color/background" />
        </shape>
    </item>

</ripple>
Atiptoe answered 13/11, 2020 at 6:27 Comment(0)
R
9

my solution:

create a file card_view_border.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white_background"/>
<stroke android:width="2dp" 
    android:color="@color/red" />
<corners android:radius="20dip"/>
</shape>

and set programmatically

cardView.setBackgroundResource(R.drawable.card_view_border);
Redo answered 21/7, 2020 at 10:14 Comment(2)
This nicer because it can accomodate corner rounding if it's been applied to the cardviewInterceptor
Tks bro! This way can apply directly for the others like background for Linear/Relative/Constraint Layout, no need to put layout inside cardView :vCircassian
F
5

I would like to improve the solution proposed by Amit. I'm utilizing the given resources without adding additional shapes or Views. I'm giving CardView a background color and then nested layout, white color to overprint yet with some leftMargin...

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    card_view:cardElevation="2dp"
    card_view:cardBackgroundColor="@color/some_color"
    card_view:cardCornerRadius="5dp">


    <!-- The left margin decides the width of the border -->

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:layout_marginLeft="5dp"
        android:background="#fff"
        android:orientation="vertical">

        <TextView
            style="@style/Base.TextAppearance.AppCompat.Headline"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Title" />

        <TextView
            style="@style/Base.TextAppearance.AppCompat.Body1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Content here" />

    </LinearLayout>

</android.support.v7.widget.CardView>
Fulton answered 18/1, 2019 at 16:32 Comment(2)
This is an elegant solution! Thank you.Bellda
fill_parent was deprecated in android sdk 8, which was ages agoWhittle
A
1

I solved this by putting two CardViews in a RelativeLayout. One with background of the border color and the other one with the image. (or whatever you wish to use)

Note the margin added to top and start for the second CardView. In my case I decided to use a 2dp thick border.

            <android.support.v7.widget.CardView
            android:id="@+id/user_thumb_rounded_background"
            android:layout_width="36dp"
            android:layout_height="36dp"
            app:cardCornerRadius="18dp"
            android:layout_marginEnd="6dp">

            <ImageView
                android:id="@+id/user_thumb_background"
                android:background="@color/colorPrimaryDark"
                android:layout_width="36dp"
                android:layout_height="36dp" />

        </android.support.v7.widget.CardView>

        <android.support.v7.widget.CardView
            android:id="@+id/user_thumb_rounded"
            android:layout_width="32dp"
            android:layout_height="32dp"
            app:cardCornerRadius="16dp"
            android:layout_marginTop="2dp"
            android:layout_marginStart="2dp"
            android:layout_marginEnd="6dp">

        <ImageView
            android:id="@+id/user_thumb"
            android:src="@drawable/default_profile"
            android:layout_width="32dp"
            android:layout_height="32dp" />

        </android.support.v7.widget.CardView>
Apology answered 22/3, 2019 at 21:44 Comment(0)
S
0

You can keep <androidx.cardview.widget.CardView with android:foreground="@drawable/black_border"

black_border :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/white" />
    <stroke
        android:width="1dp"
        android:color="@android:color/black" />
</shape>
Serena answered 27/4, 2022 at 8:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.