27

I want to re-create the image below with a CardView. To achieve this, I created a gradient file (btn_gradient.xml) and then proceeded to create the CardView.

enter image description here

CardView implementation:

<android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="44dp"
        android:layout_margin="25dp"
        app:cardElevation="0dp"
        app:cardCornerRadius="4dp"
        app:cardPreventCornerOverlap="false">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:background="@drawable/btn_gradient"
            android:text="Create Account"
            android:textColor="#000000"
            android:textStyle="bold"
            android:textAllCaps="false"/>


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

Everything works fine this way except that the radius disappears and this is not what I want. Is there a way I can set the gradient directly on the CardView? The cardBackgroundColor attribute accepts only colors, not drawables.

Any help would be appreciated.



Addendum:
As requested, this is my btn_gradient.xml file:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
    android:type="linear"
    android:angle="0"
    android:startColor="#ffc200"
    android:endColor="#fca10b" />
</shape>
Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69

6 Answers6

21
<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/_10sdp"
    app:cardCornerRadius="@dimen/_10sdp"
    app:cardElevation="@dimen/_1sdp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="@drawable/gradient_16"
        android:padding="@dimen/_6sdp">

    </LinearLayout>
</androidx.cardview.widget.CardView>

and gradient be like

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="#5B86E5"
        android:endColor="#36D1DC"
        android:angle="180" />

    <corners
        android:radius="10dp">
    </corners>
</shape>

CardView card_radius and gradient radius should be same dimentions

  • 1
    Although this code snippet may answer the question, including an explanation of why and how it helps solve the problem improves the quality and longevity of your answer. See [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer) – ammportal Jul 13 '19 at 06:57
10

If I may ask, are you per-chance testing/running on a pre-lollipop Android device? Your code seems to work as you desire (curved corners showing with the gradient) except on Android 4.

To achieve the desired result on pre-lollipop devices, you can add <corners android:radius="4dp" /> to your @drawable/btn_gradient file, (you would have to set the corner radius to match the CardView's cardCornerRadius.

Michio
  • 297
  • 2
  • 7
2

I've tried integrating the gradient on card view dynamically & faced the issue that the corner radius got impacted that was set on the view property in xml file like app:cardCornerRadius="@dimen/margin_20".

Solution :

  • Implementing the gradient on card view. I'm getting 2 gradients from api that will be incorporated from left to right.

     `    try {
                 val startColor = sample?.gradient1
                 val endColor = sample?.gradient2
                 val colors =
                     intArrayOf(Color.parseColor(startColor), 
                     Color.parseColor(endColor))
                 val gradientDrawable = GradientDrawable(
                     GradientDrawable.Orientation.LEFT_RIGHT, colors
                 )
    
                 myCardView.background = gradientDrawable
             } catch (e: Exception) {
                 // default color to white
                 myCardView.setBackgroundColor(
                     ContextCompat.getColor(
                         mContext,
                         R.color.white
                     )
                 )
             }`
    
  • Now on running the code, the card view renders with the gradient value but the issue occurs with the corner radius of card view that was set statically at xml. The corner radius got removed. To solve the issue, we simply use to set the radius of the gradient drawable that holds the drawable color in gradient form. Just add below 3 lines before setting the background.

      gradientDrawable.colors = colors
      // setting the corner radius on gradient drawable
      gradientDrawable.cornerRadius = 40f
      myCardView.background = gradientDrawable
    

The final code with gradient configuration & setting the corner radius is :

         try {
                val startColor = sample?.gradient1
                val endColor = sample?.gradient2
                val colors =
                    intArrayOf(Color.parseColor(startColor), 
                    Color.parseColor(endColor))
                val gradientDrawable = GradientDrawable(
                    GradientDrawable.Orientation.LEFT_RIGHT, colors
                )
                gradientDrawable.colors = colors
                // setting the corner radius on gradient drawable
                gradientDrawable.cornerRadius = 40f
                myCardView.background = gradientDrawable
                
                myCardView.background = gradientDrawable
            } catch (e: Exception) {
                // default color to white
                myCardView.setBackgroundColor(
                    ContextCompat.getColor(
                        mContext,
                        R.color.white
                    )
                )
            }`

Screenshot for better view of code : enter image description here

Hope this will help. Happy Coding :) Cheers!

Abhijeet
  • 501
  • 4
  • 7
0

Move this line

android:background="@drawable/btn_gradient"

To the CardView object

UPDATE

My bad:

Inside the place a layout to wrap the content of the .

In this case, I'd go with a <FrameLayout> like this:

<androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLyout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/btn_gradient">
Luca Nicoletti
  • 2,265
  • 2
  • 18
  • 32
0
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
    android:startColor="#004e92"
    android:endColor="#614385"
    android:angle="90" />
    <corners
        android:topRightRadius="10dp"
        android:bottomLeftRadius="10dp"
        android:bottomRightRadius="10dp"
        android:topLeftRadius="10dp">
    </corners>
</shape>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    android:background="@drawable/color"
    tools:context=".MainActivity">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:orientation="vertical"
            android:layout_height="match_parent">
            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_marginLeft="20dp"
                android:layout_marginRight="20dp"
                android:layout_marginTop="10dp"
                app:cardCornerRadius="10dp"
                android:layout_height="100dp">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:background="@drawable/cardcolor"                    
                    android:layout_height="100dp">
                </LinearLayout>
            </androidx.cardview.widget.CardView>
        </LinearLayout>
    </ScrollView>
</LinearLayout>

enter image description here

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Aqif
  • 326
  • 3
  • 5
-6

Do not use android:background attribute in XML file. use app:cardBackground instead.

To wrap it up, first create a gradient background XML file in drawables. then assign it to the app:cardBackgroundColor like this:

app:cardBackgroundColor="@drawable/gradient_background"

if you don't know how to create the gradient_background.xml, write click on drawables directory, create new xml file and paste the code below.

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"  
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:startColor="@color/secondaryColor"
    android:endColor="@color/primaryColor"
    android:angle="90"/>
</shape>
  • 4
    Thanks for the efforts but I don't think you read my question properly. This would not work. `cardBackgroundColor ` can't take in a drawable argument. – Taslim Oseni Apr 16 '19 at 18:34
  • try setting cardview height to wrap content and set the text view height to 44dp. – farzad chatrsimab Apr 16 '19 at 18:45
  • You can also add a LinearLayout to the cardView, set the height and width to match parent, set the gradient background, then add the textview inside the LinearLayout. – farzad chatrsimab Apr 16 '19 at 18:47