Thursday, January 29, 2009

How to have a tiled background ( cont.)

Thanks to Romain Guy, I finally could add a repeating background in my Android application !

I'm still using in my layout definition the same way to define the background, with a androidbackground parameter, with the path to your repeating background ( actually that was the point : having a consistent way for background, let them be tiled or not )

xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/MainLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@drawable/backrepeat"
>
...

in my drawable directory, I have a back.png file (  the background I want to tile ), and I create this new backrepeat.xml file :
 <?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/back" 
    android:tileMode="repeat" />


Some points :
* I think my first tries failed because I forgot the 'xmlns:android' parameter.
* I tried without the xml version line, and it still works, but I think I will let it be there... Just in case !
* The tilemode can be repeat, mirror, or clamp.
* Although in Java, I could set a different repeat mode for X and Y, I don't think it is possible in the Xml file. Not that I really care for the moment :)

That's all !
Thanks again Romain ! 
I know it is your job, as a Android engineer, to evangelise and help us, but several times you really helped me, you were quick to answer, with concise and most useful answers...

36 comments:

ralphleon said...

Lots of syntax errors in your sample code, but thanks for the tip none-the-less.

AndroidBlogger said...

What syntax errors are you refering to ?
...
Ah, I caught a error in the file name I used.
Are there any other errors ?

Thanks for reporting !

Steve said...

In your description of the bitmap XML file, you have one opening bracket and two closing ones.

Also, where should I put that XML file? Should it go in the drawable directory? The Eclipse plugin seemed to balk at me putting it there; though I can refer to it with the other XML files. Also, I'm getting an XmlPullParserException when I try to load the view saying that the <bitmap> tag "requires a valid src attribute.

I've not ruled out foolishness on my part somewhere since this is my first app.

AndroidBlogger said...

You were right about the two closing bracket.
I just fixed it. I don't understand where this second bracket come from, as this code comes directly from my game ( Word Prospector ) code.

The second xml is a file from the drawable directory ( I just have :
<?xml version="1.0" encoding="utf-8"?>
as the first line, the rest is what is in the blog entry )
Along with this file, I have the picture file ( back.png ).

Then there is the first xml file, that reference my tiling picture.
This file is my activity description file that is found in the layout directory.

From the error you get, I would say the picture file - back.png- is missing in your drawable directory ?

Hope it helps...

Steve said...

Hello, thanks for getting back to me. The previous error somehow resolved itself.

I have the XML file that contains the single bitmap reference in my drawable directory. I also have the image that I want to tile. If I set the background property of a layout to that image, it displays correctly, but is stretched to fill the screen.

Now, when I set the background property to the bitmap XML file, I get a ResourcesNotFoundException. It says "Could not find the drawable resource matching value {correct ID value from R.java} (resolved name: {correct name}) in current configuration.

That also seems like there's a problem with the file not being around, but nevertheless, when I address it directly, it appears. R.java also finds it and correctly assigns it an ID.

(P.S. You also should probably put the "xmlns:" marker in front of the android declaration in the Bitmap example)

AndroidBlogger said...

Hum...

Strange...
Are you sure you don't forget to remove the .png extension when refrencing your picture ?

Do you have in your R.java file a value for both your tiled bitmap, and your real bitmap ?
In my case, I have :
public static final class drawable {
public static final int back=0x7f020000;
public static final int backrepeat=0x7f020001;
<...>

I don't really have any more clue...

Steve said...

Quite sure. Because when I add the ".png" it gives me an entirely different error! :-D I tried that as a means of troubleshooting already, and discovered that wasn't the way to go.

R.java does indeed have two entries for each of the bitmaps. Mine happen to be:
public static final int red_dot_wallpaper=0x7f020003;
public static final int repeating_red_dots_background=0x7f020004;


I wondered if it was just a problem with the Eclipse plugin not respecting the full power of the SDK, and so I tried to just load it onto the virtual device. It worked and showed the correct (but scaled) background. The rest of the layout was correct.

I'll keep poking at this and when I find out what's wrong I'll let you know.

Thomas said...

For me to get this to work, I had to change :

bitmap android=

from the second XML to

bitmap xmlns:android=

otherwise, I got an error about an unbound prefix.

But, other than that, thanks for the tip!

Matthew said...

This was really useful, Thanks!!!

Anonymous said...

I am able to tile the background with this method, but there is a spacing between each tile. Like there is a cellspacing attribute that needs to be set to zero. Is there any way to get rid of this spacing between each tile?

Thanks!

AndroidBlogger said...

@anonymous :

It is strange, I'm using this code in my code, and I don't have any space between my tiles... and my image is not even with a magic size ( it is a 276x326 image )
Are you sure the space is not IN the image ?

Leviathan said...

Hey, thanks for the code examples!

I only needed the general idea how to realize it, so I only used the second pieces of code. Worked fine when I added the "xmlns:", just like you said.

LapSuS said...

Thanks for the tip, but I still have a problem. No compilation problem, but the Layout Editor can't show the content of the frame. I have this error in replacement :
NotFoundException: Could not find drawable resource matching value 0x... in current config.

I checked on Google on read about somebody who experienced the same pb with the Demo Program LunarLander, and then said maybe the problem came from Eclipse workbench. I restarted Eclipse but no better result. Everything is ok when I remove the background property from the LinearLayout.

Here is a stack trace :

android.content.res.Resources$NotFoundException: Could not find drawable resource matching value 0x7F020001 (resolved name: spline) in current configuration.
at com.android.layoutlib.bridge.BridgeResources.throwException(BridgeResources.java:496)
at com.android.layoutlib.bridge.BridgeResources.getValue(BridgeResources.java:392)
at android.content.res.Resources.openRawResource(Resources.java:771)
...
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
at org.eclipse.equinox.launcher.Main.main(Main.java:1287)

Miguel said...

Hi, I'm experiencing the same problem as Steve did last year, the " requires a valid src attribute"

I thought it could have something to do with the file extension, so I tried using .bmp or .jpg files, but the problem remained. All of the resources exist in R.java.

2 lines of my stack trace:

org.xmlpull.v1.XmlPullParserException: Binary XML file line #4: requires a valid src attribute
at android.graphics.drawable.BitmapDrawable.inflate(BitmapDrawable.java:373)
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:788)

Any hint? Thanks!

Miguel said...

Hi, answering myself, the problem comes from Eclipse, not from Android. I deployed the app in a Nexus One and it showed exactly what I wanted.

AndroidBlogger said...

@Miguel :
Hum... This is really strange...
By an Eclipse issue, I suppose you mean an emulator issue ?
Can it be a problem with the SDK version ?

@Lapsus :
Obvious answer : it looks like your application can't find the image you provide.
Make sure the generated R.java file contains your resource ID.
The obvious part being said, I think I had some issues with resources it couldn't find, and R.java that wasn't generated correctly.
The sad news is I don't really kwow how I could get it to work fine : I change so many things wherever I could.
I just remember I lost a lot of time on this kind of issue, and that it was very frustrating :(

Miguel said...

@admin more like an swt error on the layout XML preview. I don't think it's a SDK version problem, I'm using 2.1 and I'm developing for API Level 7.

@Lapsus If the problem is R.java not noticing new resources, I had problems with it too. Cleaning the project did the trick for me, but I read about several other people having a similar problem.

endryha said...

I don't understand where I should place declaration of new bitmap, I did it in separeted xml file as recomended in blog entry, I did it in resources, but each time a receive error, can anyone show a whole file where bitmap is located and in which directory it is.

Miguel said...

@endryha the bitmap goes in the res/drawable folder (or drawable-hdpi if you're developing for high density).

The backrepeat.xml goes in res/drawable and it may be used as any other drawable.

It would help if you pasted the error.

Anonymous said...

if it just worked!!

Anonymous said...

FAIL!

Anonymous said...

How about a project sample where it actually WORKS?

AndroidBlogger said...

this is actual code from my game 'Word Prospector', and it is really working !
What is the trouble you have with it ?

Anonymous said...

Thanks for the quick reply and my bad for the rage post. It all works after a few fixes (although they were hard to figure for a complete beginner ;)

The first question mark is missing on the xml tag of the first xml, the second one doesnt have the tag at all and is missing the "xmlns:" before android as well.

I think that was all I had to fix and thanks again! ^^

AndroidBlogger said...

No problem. I know how it feels when it is not working :)

I tried to report your comments in order to have something that works without having to read all the comments !
Thanks for your input, and good luck with your developments !

Sree Sundaram said...

Any idea how to do the same for an imageview? I need to have a tiled image for an imageview instead of in the background...

Anonymous said...

It worked great. Thanks

emotionfree said...

hi,
thanks for the post. i tried this and it works on the AVD(1.6) but doesn't work on my Galaxy Tab. Any idea why?

Alok said...

I see that the repeat pattern sometimes does not get applied and i need to force stop and start the application again to view the repeat pattern.This generally happens after i install the app and run it for the 1st time.Any guesses to the problem?

ardialhaidar said...

nice tutorial. it helps. thanks... ;)

Richard Lalancette said...
This comment has been removed by the author.
Richard Lalancette said...

(wish there was a way to edit a comment :)

Hi all,

Enjoy free 9 patch drawable pngs here for your android projects.

Free of charge and can be used in commercial projects.

http://android9patch.blogspot.com/

Enjoy!

Richard.

Ken said...

Thanks for all your useful articles. I'm following your steps here and finally, when I set the xml drawable as the background for a LinearLayout I get this error:

org.xmlpull.v1.XmlPullParserException: Binary XML file line #5: requires a valid src attribute
at android.graphics.drawable.BitmapDrawable.inflate(BitmapDrawable.java:370)

The source is android:src="@drawable/pat1" which is an existing png file in the same drawable folder.

What may the problem be? Thank you

Prakash Nadar said...

Thanks solved my problem.

Pacior said...

Thanks. At least someone explained how to set file to background and that entire xml difficulties.

Anonymous said...

Thanks!