320

I have set a background image in my app, but the background image is small and I want it to be repeated and fill in the whole screen. What should I do?

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/bg"
    android:tileMode="repeat">
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
virsir
  • 15,159
  • 25
  • 75
  • 109

5 Answers5

433

Ok, here's what I've got in my app. It includes a hack to prevent ListViews from going black while scrolling.

drawable/app_background.xml:

<?xml version="1.0" encoding="utf-8"?>
    <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
        android:src="@drawable/actual_pattern_image"
        android:tileMode="repeat" />

values/styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <style name="app_theme" parent="android:Theme">
    <item name="android:windowBackground">@drawable/app_background</item>
    <item name="android:listViewStyle">@style/TransparentListView</item>
    <item name="android:expandableListViewStyle">@style/TransparentExpandableListView</item>
  </style>

  <style name="TransparentListView" parent="@android:style/Widget.ListView">
    <item name="android:cacheColorHint">@android:color/transparent</item>
  </style>

  <style name="TransparentExpandableListView" parent="@android:style/Widget.ExpandableListView">
    <item name="android:cacheColorHint">@android:color/transparent</item>
  </style>

</resources>

AndroidManifest.xml:

//
<application android:theme="@style/app_theme">
//
Michael
  • 3,982
  • 4
  • 30
  • 46
yanchenko
  • 56,576
  • 33
  • 147
  • 165
  • 1
    Try with this too: android:gravity="clip_horizontal" --- it avoid image deformation – Felipe Sep 30 '11 at 21:37
  • 2
    I've tried this but saw only single tile stretched to all the screen :( – Sergey Metlov Mar 02 '12 at 19:24
  • If I have a `ScrollView` and place a background to repeat on it and I have a long long list, won't I have problems with OutOfMemory exception when the `ScrollView` becomes very long? – AndreiBogdan Aug 31 '12 at 09:40
  • One thing to keep in mind is that you should have folders drawable-hdpi, drawable-mdpi & drawable-ldpi, you'll need to add this backrepeat.xml file and the relevant images to each of these to allow this functionality in high, medium and low dpi (dots per inch) screen sizes. – saber tabatabaee yazdi Nov 13 '13 at 14:29
  • 2
    @sabertabatabaeeyazdi You only need images in those folders. XML can be placed in `drawable` (withoud `-*dpi`) folder. – Jaroslav Mar 17 '14 at 08:58
  • Getting the error: requires a valid 'src' attribute – JPLauber Aug 13 '18 at 13:22
179

There is a property in the drawable xml to do it. android:tileMode="repeat"

See this site: http://androidforbeginners.blogspot.com/2010/06/how-to-tile-background-image-in-android.html

Laszlo Lugosi
  • 3,669
  • 1
  • 21
  • 17
  • 38
    I really don't know how is this so low rated. Herd instinct? This is the native implementation of tiled background – Michał Klimczak Apr 08 '12 at 13:00
  • 5
    This one works like a charm. Also this one seems like the right way to do it. – JCasso Jul 11 '12 at 03:02
  • 3
    I agree that this should be the accepted answer. It's really simple and works perfectly! – huong Feb 11 '13 at 06:07
  • 7
    +1 Only one thing must be corrected that is mentioned wrongly in the article: `you'll need to add this backrepeat.xml file and the relevant images to each of these to allow this functionality in high, medium and low dpi`. You only have to place the referenced drawables in all density buckets. The referencing XML drawable can be placed in `drawable` folder, that is enough. – caw Jun 03 '13 at 12:44
  • This is what you call explained by a pro – Muneeb Mirza Jul 12 '16 at 08:02
  • This works fine if "actual_pattern_image" was a bitmap but what about the vectors? – golkarm Jan 09 '21 at 16:37
72

Here is a pure-java implementation of background image repeating:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.bg_image);
    BitmapDrawable bitmapDrawable = new BitmapDrawable(bmp);
    bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
    LinearLayout layout = new LinearLayout(this);
    layout.setBackgroundDrawable(bitmapDrawable);
}

In this case, our background image would have to be stored in res/drawable/bg_image.png.

plowman
  • 13,335
  • 8
  • 53
  • 53
  • If I have a `ScrollView` and place a background to repeat on it and I have a long long list, won't I have problems with OutOfMemory exception when the `ScrollView` becomes very long? – AndreiBogdan Aug 31 '12 at 09:41
  • Why should this not be working anymore? Depreciation means these commands should not be used anymore because they may be retired some time in the future. In API 19, this still works as @plowman suggested. Also, not BitmapDrawable is deprecated, but only some of its methods. I have edited the code above so we don't have to use deprecated methods. – Oliver Hausler Jan 19 '15 at 00:44
16

Expanding on plowman's answer, here is the non-deprecated version of changing the background image with java.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bitmap bmp = BitmapFactory.decodeResource(getResources(),
            R.drawable.texture);
    BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(),bmp);
    bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT,
            Shader.TileMode.REPEAT);
    setBackground(bitmapDrawable);
}
user3763868
  • 161
  • 1
  • 2
4
// Prepared By Muhammad Mubashir.
// 26, August, 2011.
// Chnage Back Ground Image of Activity.

package com.ChangeBg_01;

import com.ChangeBg_01.R;

import android.R.color;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

public class ChangeBg_01Activity extends Activity
{
    TextView tv;
    int[] arr = new int[2];
    int i=0;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView)findViewById(R.id.tv);
        arr[0] = R.drawable.icon1;
        arr[1] = R.drawable.icon;

     // Load a background for the current screen from a drawable resource
        //getWindow().setBackgroundDrawableResource(R.drawable.icon1) ;

        final Handler handler=new Handler();
        final Runnable r = new Runnable()
        {
            public void run() 
            {
                //tv.append("Hello World");
                if(i== 2){
                    i=0;            
                }

                getWindow().setBackgroundDrawableResource(arr[i]);
                handler.postDelayed(this, 1000);
                i++;
            }
        };

        handler.postDelayed(r, 1000);
        Thread thread = new Thread()
        {
            @Override
            public void run() {
                try {
                    while(true) 
                    {
                        if(i== 2){
                            //finish();
                            i=0;
                        }
                        sleep(1000);
                        handler.post(r);
                        //i++;
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };


    }
}

/*android:background="#FFFFFF"*/
/*
ImageView imageView = (ImageView) findViewById(R.layout.main);
imageView.setImageResource(R.drawable.icon);*/

// Now get a handle to any View contained 
// within the main layout you are using
/*        View someView = (View)findViewById(R.layout.main);

// Find the root view
View root = someView.getRootView();*/

// Set the color
/*root.setBackgroundColor(color.darker_gray);*/
Muhammad Mubashir
  • 1,591
  • 1
  • 21
  • 18