293

I am having trouble applying a gradient background to a LinearLayout.

This should be relatively simple from what I have read but it just doesn't seem to work. For reference sakes I am developing on 2.1-update1.

header_bg.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:angle="90"
        android:startColor="#FFFF0000"
        android:endColor="#FF00FF00"
        android:type="linear"/>
</shape>

main_header.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="50dip"
    android:orientation="horizontal"
    android:background="@drawable/header_bg">
</LinearLayout>

If I change @drawable/header_bg to a color - e.g. #FF0000 it works perfectly fine. Am I missing something obvious here?

daksh21ubuntu
  • 276
  • 2
  • 4
  • 14
Genesis
  • 8,038
  • 3
  • 21
  • 22

10 Answers10

455

Ok I have managed to solve this using a selector. See code below:

main_header.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="50dip"
    android:orientation="horizontal"
    android:background="@drawable/main_header_selector">
</LinearLayout>

main_header_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape>
        <gradient
            android:angle="90"
            android:startColor="#FFFF0000"
            android:endColor="#FF00FF00"
            android:type="linear" />
    </shape>
</item>
</selector>

Hopefully this helps someone who has the same problem.

Genesis
  • 8,038
  • 3
  • 21
  • 22
  • 5
    Great. FYI, see other gradient types: http://developer.android.com/reference/android/graphics/drawable/GradientDrawable.html#attr_android:type – Bamaco Apr 07 '16 at 21:36
110

It is also possible to have the third color (center). And different kinds of shapes.

For example in drawable/gradient.xml:

<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="#000000"
        android:centerColor="#5b5b5b"
        android:endColor="#000000"
        android:angle="0" />
</shape>

This gives you black - gray - black (left to right) which is my favorite dark background atm.

Remember to add gradient.xml as background in your layout xml:

android:background="@drawable/gradient"

It is also possible to rotate, with:

angle="0"

gives you a vertical line

and with

angle="90"

gives you a horizontal line

Possible angles are:

0, 90, 180, 270.

Also there are few different kind of shapes:

android:shape="rectangle"

Rounded shape:

android:shape="oval"

and problably a few more.

starball
  • 20,030
  • 7
  • 43
  • 238
Sindri Þór
  • 2,887
  • 3
  • 26
  • 32
49

In XML Drawable File:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <gradient android:angle="90"
                android:endColor="#9b0493"
                android:startColor="#38068f"
                android:type="linear" />
        </shape>
    </item>
</selector>

In your layout file: android:background="@drawable/gradient_background"

  <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/gradient_background"
        android:orientation="vertical"
        android:padding="20dp">
        .....

</LinearLayout>

enter image description here

Pacific P. Regmi
  • 1,607
  • 19
  • 15
  • Hi, how did you achieve transparent status bar? If I set it transparent in styles.xml it becomes black .. – kironet Jan 12 '19 at 10:03
  • @kironet - to make the status bar transparent you need to add this in you MainActivity Java file inside the onCreate() method but after the setContentView(): getWindow().setFlags( WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS ); – Liraz Shaka Amir Oct 12 '20 at 06:18
21

Try removing android:gradientRadius="90". Here is one that works for me:

<shape 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
>
    <gradient
        android:startColor="@color/purple"
        android:endColor="@color/pink"
        android:angle="270" />
</shape>
Vincent Mimoun-Prat
  • 28,208
  • 16
  • 81
  • 124
  • Unfortunately that is not working for me. I have updated the original question with what I have now. – Genesis May 12 '11 at 11:07
  • Does it still not work when you add a widget in the layout (for instance a TextView? – Vincent Mimoun-Prat May 12 '11 at 11:32
  • Correct - it still does not work with a TextView inside the layout. Again, if I apply a static color rather than a drawable it works just fine. One thing I have noticed is I can (sometimes) get it to work using a selector but that shouldn't be necessary from my understanding. – Genesis May 12 '11 at 13:54
16

With Kotlin you can do that in just 2 lines

Change color values in the array

                  val gradientDrawable = GradientDrawable(
                        GradientDrawable.Orientation.TOP_BOTTOM,
                        intArrayOf(Color.parseColor("#008000"),
                                   Color.parseColor("#ADFF2F"))
                    );
                    gradientDrawable.cornerRadius = 0f;

                   //Set Gradient
                   linearLayout.setBackground(gradientDrawable);

Result

enter image description here

Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
6

My problem was the .xml extension was not added to the filename of the newly created XML file. Adding the .xml extension fixed my problem.

kwahn
  • 2,118
  • 2
  • 21
  • 17
0

I don't know if this will help anybody, but my problem was I was trying to set the gradient to the "src" property of an ImageView like so:

<ImageView 
    android:id="@+id/imgToast"
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:src="@drawable/toast_bg"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"/>

Not 100% sure why that didn't work, but now I changed it and put the drawable in the "background" property of the ImageView's parent, which is a RelativeLayout in my case, like so: (this worked successfully)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:id="@+id/custom_toast_layout_id"
    android:layout_height="match_parent"
    android:background="@drawable/toast_bg">
instanceof
  • 1,404
  • 23
  • 30
0

You can used a custom view to do that. With this solution, it's finished the gradient shapes of all colors in your projects:

class GradientView(context: Context, attrs: AttributeSet) : View(context, attrs) {

    // Properties
    private val paint: Paint = Paint()
    private val rect = Rect()

    //region Attributes
    var start: Int = Color.WHITE
    var end: Int = Color.WHITE
    //endregion

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        // Update Size
        val usableWidth = width - (paddingLeft + paddingRight)
        val usableHeight = height - (paddingTop + paddingBottom)
        rect.right = usableWidth
        rect.bottom = usableHeight
        // Update Color
        paint.shader = LinearGradient(0f, 0f, width.toFloat(), 0f,
                start, end, Shader.TileMode.CLAMP)
        // ReDraw
        invalidate()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawRect(rect, paint)
    }

}

I also create an open source project GradientView with this custom view:

https://github.com/lopspower/GradientView

implementation 'com.mikhaellopez:gradientview:1.1.0'
lopez.mikhael
  • 9,943
  • 19
  • 67
  • 110
  • Looks interesting. Does this work with later versions of Android. I was having issues with the other answers as they now seem to be deprecated: https://issuetracker.google.com/issues/37114374 – trees_are_great Oct 15 '19 at 09:14
0

I would check your alpha channel on your gradient colors. For me, when I was testing my code out I had the alpha channel set wrong on the colors and it did not work for me. Once I got the alpha channel set it all worked!

Ray Hunter
  • 15,137
  • 5
  • 53
  • 51
-1
<?xml version="1.0" encoding="utf-8"?>

<gradient
    android:angle="90"
    android:startColor="@color/colorPrimary"
    android:endColor="@color/colorPrimary"
    android:centerColor="@color/white"
    android:type="linear"/>

<corners android:bottomRightRadius="10dp"
    android:bottomLeftRadius="10dp"
    android:topRightRadius="10dp"
    android:topLeftRadius="10dp"/>

enter image description here

AK IJ
  • 492
  • 4
  • 10