I have a ListView whose items have a tiled background. To accomplish this, I use the following drawable xml:
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/tile"
android:tileMode="repeat" />
Usually, this works. Sometimes, however, the src drawable isn't tiled, but stretched to fill the entire list item. (I've got several different tiles like this, and I use them mixed in one ListView. If there is stretching instead of tiling, it's never been in all of them at once, for what that's worth.)
I also tried to add android:dither="true" to that xml, since I read somewhere that without it there might be bugs. That didn't change anything.
Has anyone had the same problem? How did you fix it?
I also got bitten by this problem. Very hard to diagnose, even harder to find similar reports and usable solutions.
"Tapas" on the freenode #android-dev irc channel came with the following utility method:
public static void fixBackgroundRepeat(View view) {
Drawable bg = view.getBackground();
if (bg != null) {
if (bg instanceof BitmapDrawable) {
BitmapDrawable bmp = (BitmapDrawable) bg;
bmp.mutate(); // make sure that we aren't sharing state anymore
bmp.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
}
}
}
Apply it to all Views that have a tiled background set (e.g. findViewById them).
Also, I have the impression this bug started acting up after setting "anyDensity=true" in AndroidManifest.xml
I've just had the exact same issue except with CLAMP TileMode. I have a bitmap that I want to then just stretch away at the bottom and have it set up as an XML defined BitmapDrawable and in the Graphical Preview window all looks fine, no matter what size I make the ViewImage it draws my bitmap at the top and then repeats the last pixels to fill to the end.
Launching the app on various SDK builds on the emulator and on my own phone all then produced a straight 'fill' type distortion which is completely useless.
The solution turned out to simply be to re-apply the TileMode every time I changed the size of the ImageView within my code:
((BitmapDrawable)ascender.getDrawable()).setTileModeY(TileMode.CLAMP);
Now it's all drawing fine. So yes, this looks like a bug to me.
As I didn't see the link here, this was confirmed to be a bug in Android. It was fixed in ICS. See XML drawable Bitmap tileMode bug? for more details.
There is a lot of noise about this topic online, with various (and numerous) suggested solutions.
If you're still at a loss, my suggestion is to keep all tiled bitmap
resources to square, base-2 dimensions.
ie: 16px by 16px for an xhdpi tile asset.
I hoped that the Android platform would "over-tile" to fill a space if the bitmap did not tessellate perfectly - and then trim the waste. However trialling a 10px*10px tiled bitmap across mdpi, hdpi and xhdpi (and v2.3 to v4.0)'inconsistently' showed this stretching.
The base-2 dimension allows for whole and even division as you progress through the various resolutions and as each device tries to paint the tiles each time the view is created.
In Android development, we contest with the ranging hardware and the vendors dipping their fingers into the platform - sometimes this sort of trivial black magic just works.
This appears to have resolved the issue for me at least. Worth a shot.
This sounds like a bug, although I've never seen it myself. If you have a simple APK that reproduces the issue, please send it to me (romainguy /at/ android.com) or file a bug here.
This blog entry discusses the issue
combined with this solution from Tapas listed by Ivo van der Wijk, it works for me.
The key was to remove the tiled setting from the XML, then set it to tiled at runtime. It does not work for me if they are both set to tiled.
Edit: actually, I lied. Even with this it seems to sometimes fail to tile.
Would be very nice to have a reliable work-around.
Edit 2: setting it to something else (eg. CLAMPED) then setting it back so far seems to be working.
I moved my image from drawable-xhdpi to drawable folder and everything was fine.
I was also having the same issue. What I was missing was that we need to add scaletype to fitXY in the imageview for the xml bitmap to work properly.
tile_bitmap.xml
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/tile"
android:tileMode="repeat" />
layout.xml
<ImageView
android:layout_width="match_parent"
android:src="#drawable/tile_bitmap"
android:layout_height="match_parent"
android:scaleType="fitXY"/>
Related
I'm writing an app that requires displaying a semi-transparent PNG layer over a camera preview. Everything was fine until I wanted to publish it and make sure it works also on Android 2.x. It seems that on older versions of Android, the camera preview causes the drawable (in my case, a subclass of ImageView) to not show. When I get rid of the preview, it works just fine - the drawable is visible as it should. It works like this both on the emulator and on real devices.
Here how it looks like on Android 2.3:
and 4.2.2:
I think there would be too much code to paste here, so I've isolated the problematic parts into a small project: http://krzeminski.it/wp-content/uploads/2013/09/DrawableTest.zip. The most interesting and probably guilty class is CameraPreview.
Also, I'm not sure why the preview itself doesn't work. I've read that on Android 2.x emulators, the test image from the emulated camera is just this plain white, so I assumed it's ok. However, my friend tested the app on his phone with Android 2.3 and the preview appeared to be plain black. I guess it's a subject for a separate question, but maybe you'll notice something in the code.
I've spent probably 2 days now to solve these two problems, so any clues would be really helpful. Thank you!
I ran into this issue a while back. I remember that a post on SO recommended that you shouldn't use ImageView#getImageMatrix(). Reasoning given was:
public Matrix getImageMatrix ():
Return the view's optional matrix. This is applied to the view's
drawable when it is drawn. If there is not matrix, this method will
return an identity matrix. Do not change this matrix in place but make
a copy. If you want a different matrix applied to the drawable, be
sure to call setImageMatrix().
Even after reading through this, I couldn't/don't understand what difference this makes. I sorted the problem out by using:
Matrix matrix = new Matrix();
May be you're dealing with the same issue. Give this a try.
I don't have Android 2.3 device. But I think probably you can try two ways:
1. change FrameLayout to RelativeLayout
2. programmatically add views:
mLayout.addView(mPreview);
mLayout.addView(mImageView);
mLayout.addView(mTextView);
The designer has given me two PNG images and they are supposed to be the background for all the buttons of my app. I am not being able to transform then into 9-patch image. It seems like that one image has too much details to be a 9-patch, stretching it would make it lose the details.
Can you guys take a look and let me know what you think?
http://img211.imageshack.us/img211/1965/background1p.png
http://img845.imageshack.us/img845/676/background2a.png
Many thanks,
Felipe
//repeatimage.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/tileimage"
android:tileMode="repeat"
android:dither="true" >
</bitmap>
and set this image in your layout background as
android:background="#drawable/repeatimage"
//slice your image into small pieces
Try using this tool . It's a simple 9-patch generator that can be of use to you.
For both your questions:
1: I use images with shadows a lot and you can certainly convert them into a 9-patch image. I am not sure how I can explain the actual steps involved in creating this. Perhaps an example will help you work that bit out.
2: For an image with a pattern in it, a 9-patch of it as #Padma Kumar pointed out, will still distort your image. To fix that, you can follow the link attached. It is a nice tutorial on how to use tiled patterns as backgrounds. http://androidforbeginners.blogspot.in/2010/06/how-to-tile-background-image-in-android.html
A side note: The draw9patch can be quite an intimidating tool. Until you get the hang of it, you could consider using this website here: http://android-ui-utils.googlecode.com/hg/asset-studio/dist/nine-patches.html. It however, works only in Google Chrome.
Maybe you should check this tutorial: http://www.thesecretpie.com/2010/07/creating-custom-fancy-buttons-in.html
It explains how 9-patch actually works and how to use drow9patch tool which comes with Android SDK. It was really useful for me.
And for the shadows, you just need to save image with transparent background (of course) and with a little free space between shadow and edge of an image which you will use to draw lines for 9-patch
so im trying to make a game with just a simple static background at the moment, but when i draw it to the screen (no scaling being done as the resolution of the image is the same as the screen) it draws the bottom portion of the image incorrectly where the bottom few hundred pixels of the image are exactly the same going down the image. Sorry it's so difficult to explain but being new here i cant actually post an image of what is going wrong.
Now im just using a simple sprite to render this background image. Here is the code being used:
// background layer: another image
background = CCSprite.sprite("WaterBackground.png");
// change the transform anchor point (optional)
background.setPosition(CGPoint.make(GAME_WIDTH/2, GAME_HEIGHT/2));
addChild(background);
am i doing something wrong here? Does Cocos2D not support such large images for sprites? (resolution of 800*1280)
Any help would be greatly appreciated!
Since i am now able to upload images, here are visuals of what is going wrong:
And the problem in my game:
As you can see, the problem is hard to describe. The problem only exists with this larger image; i scaled it down manually in GIMP and then scaled it up for the game and it looked fine (except for being a lower resolution). I also tried scaling down this larger image which still resulted in the same problem. Hopefully you guys can help me as I have no clue what could possibly cause this error. Especially since i read that Cocos2D's max supported image size is 2048*2048 and my image is well within that.
Thanks for any help you guys can provide!
This is due to limitations on the size of textures. Coсos2d-android supports images with a maximum size of 1024 x 1024 pixels.
I faced the same problem and looking for a way to solve it.
EDIT
I found the solution
In cocos2d project open file CCTexture2d.java in org.cocos2d.opengl package and change kMaxTextureSize from 1024 to 2048
I'm not certain, as from your code and looking at the cocos2d code I can't see a definite reason why this would be happening, but given the number of sprites you've got on the screen, i'd definitely take a look at my answer to this question as you may well be hitting one of cocos2d's quirky little rendering faults around multiple sprites. can't hurt to try spritesheets, and it's certainly the correct way to actually do sprites in cocos.
also, definitely create yourself a helper utility to determine the scaling ratio of a device compared to your original image sizes, as unlike on iphone, android does have a pretty much unlimited variation of screen resolutions, and a simple bit of "scale as you load" utility code now will save you lots of time in the future if you want to use this on any other device.
you should try to make one method for adding background,i am doing this this like this way try this hope it will help full for you...here addBackGroundScene is my method and i am adding my background with this method,scrXScaleFactor is maintaining scaling part of my screen try this...
private void addBackGroundScene() {
CCSprite bgForLevel1 = addBackgroundAtOrigin("prelevel1/bgMenu.jpg");
bgForLevel1 .setScaleX(scrXScaleFactor);
bgForLevel1 .setAnchorPoint(0, 0);
addChild(bgForLevel1 );
}
For a splashscreen I use an image which contains a white background (pure white - checked in Photoshop). For some reason it shows a slight green bg vs. the activity's default white bg - as marked in the screenshot. Only in some devices, like the
I add this as single view in a frame layout to the activity:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
android:src="#drawable/splashscreen" />
</FrameLayout>
Any idea? I read about RGB888 vs. RGB565 issues, but couldn't find a proper solution.
Note: I sure could make change the white in the image to transparent, but would prefer to understand the problem and find a proper solution.
This is really annoying. I wonder, why so few people encountered this problem as it should appear on all 32-bit displays.
You mentioned right about RGB888 format. The cause of the problem is that regardless of the original bitmap format in the APK files all bitmaps are compressed (in my case into indexed 256-color! wtf?).
I couldn't find the way to prevent it, so if anyone knows the proper solution, please tell.
However, I found two solutions for the white color problem.
1) Per-bitmap: Say, we have a drawable bitmap resource called #drawable/mypng, which causes the problem. We need to add an additional XML drawable drawable/mypng_nofilter.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/mypng"
android:filter="false"
/>
and use #drawable/mypng_nofilter instead.
2) For entire activity: In activity onCreate method we need to add
getWindow().setFormat(PixelFormat.RGB_565);
Now the window has 16-bit color depth and all bitmaps appear "properly" white.
Again, I would prefer to have 32-bit color depth, but I don't know how to control compile-time image compression.
I have solved this issue by changing the Bitmap.CompressFormat type to PNG instead of JPEG:
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.nouv);
Bitmap bitmap = (Bitmap)((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
I encountered the same problem with network loaded images. I solved the issue by disabling bitmap filter. Since I do not have the issue on ICS and newer devices, I turned off the bitmap filter only for pre-ICS devices. Following is the code I used (setting network loaded bitmap to the ImageView.)
BitmapDrawable bitmapDrawable = new BitmapDrawable(imageView.getContext().getResources(), bitmap);
bitmapDrawable.setFilterBitmap(false);
imageView.setImageDrawable(bitmapDrawable);
After using all the solutions in the Stackoverflow.
From changing android:src to app:srcCompact and many other solutions.
The thing which helped me was my image was inside drawable-anydpi and I moved the image from drawable-anydpi to drawable and it worked for me after 2 hours of research.
P.S: It might help someone too that's why I put it over here. :)
As your image only have a picture in its middle, I would advise you to set:
android:scaleType="centerCrop"
It will crop some part of your picture, at left and right, but will use the whole screen...
You can also define a background to your FrameLayout or your ImageView using the color of your picture (which seems to be F8FCF8):
android:background="#F8FCF8"
I'm trying to add a background that includes a gradient (I do want to use an image, not an android xml declared gradient effect).
This image is remarkably ruined by Android, it add some crappy banding whatever I try the result is the same (two capture of approximately the same region the distorted/normal images) :
My image is used as a layout background inside my layout XML :
android:background="#drawable/background_gradient_dithered"
I've tried to used an intermediate drawable to force dither whose xml is :
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/background_gradient" android:dither="true" android:antialias="true" android:filter="true"/>
I've tried to have the following code in my onCreate() :
getWindow().setFormat(PixelFormat.RGBA_8888);
Both tries changed nothing.
Thanks
The correct solution was .... I bet you've guess it : restarting Eclipse. I've learned it, every problem on Android might be a "restart Eclipse problem".
After some test I can add that enabling dethering is not useful when Format is set to PixelFormat.RGBA_8888
Readers should give a look to the answer given by #TenFour04, this approach can avoid to make drawable just to enable dithering.
window.addFlags(WindowManager.LayoutParams.FLAG_DITHER);
EDIT :
I've found out that even with these tricks the problem can persist. You can try to modifiy your PNG to have an alpha layer in it (change a pixel to a transparency of 99% for example), this would force android compiler to not play with it.
Try adding this in onCreate(). Older versions of Android default to no dithering.
Window window = getWindow();
window.setFormat(PixelFormat.RGBA_8888);
window.addFlags(WindowManager.LayoutParams.FLAG_DITHER);
I worked it out, just change the size of the .png files. I put them in the mdpi and resized it with Irfanview <-open source image editor to 1024x7xx <- dont remember, this comes too handy
and I set it for 300 dpi. So they download it on a tablet and stuff, hope this helps :)