Issue
I need to create a pattern to set as a background of some View. I want the pattern to look something like this:
I don't want to import any image to drawable, but instead, I want to create my own shapes, layer-list and the ultimate goal is to have a pattern as a background.
Is is possible to achieve this without having to import any external image?
Solution
You can get a pattern of repeating tiles based upon shape drawables by creating a custom View and overriding onDraw().
Let's start by creating the tile as a layer list made of shape drawables, in this case alternating squares of black and white:
my_background.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<layer-list>
<item >
<shape >
<solid android:color="#ffffff"/>
<size
android:height="8dp"
android:width="8dp"
/>
</shape>
</item>
<item android:left="4dp" android:top="4dp" android:bottom="0dp" android:right="0dp" >
<shape >
<solid android:color="#ff000000"/>
<size
android:height="4dp"
android:width="4dp"
/>
</shape>
</item>
<item android:left="0dp" android:top="0dp" android:bottom="4dp" android:right="4dp">
<shape>
<solid android:color="#ff000000"/>
<size
android:height="4dp"
android:width="4dp"
/>
</shape>
</item>
</layer-list>
</item>
You need a method drawableToBitmap() to transform the tile into a Bitmap like here.
Override onDraw():
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Drawable d = getResources().getDrawable(R.drawable.my_background);
if (d != null)
{
Bitmap b = drawableToBitmap(d);
BitmapDrawable bm = new BitmapDrawable(getResources(), b);
bm.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
bm.setBounds(canvas.getClipBounds());
bm.draw(canvas);
}
}
Depending on the type of View, you may have to take additional steps.
- For a custom
Viewextending some kind ofLayout, set theandroid:backgroundattribute to any color in order to trigger the call toonDraw() - For many
Views it may be easier to implement and at the same time better for performance to position your customViewbelow the otherView(e.g. as two children in aRelativeLayout) and make the sizes match. - If you want to extend from
ImageViewyou will need to draw the foreground drawable on top of the background pattern. In this case, you can modifyonDraw()as follows:
onDraw() preserving foreground drawable:
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
// preserve foreground drawable if there is one:
Drawable fd = getDrawable();
Drawable d = getResources().getDrawable(R.drawable.my_background);
if (d != null)
{
Bitmap b = drawableToBitmap(d);
BitmapDrawable bm = new BitmapDrawable(getResources(), b);
bm.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
bm.setBounds(canvas.getClipBounds());
bm.draw(canvas);
}
if (fd == null)
return;
// set bounds as needed
fd.setBounds(0, 0, 100, 100);
fd.draw(canvas);
}
EDIT
As mentioned above, in some cases (e.g. TextView, ProgressBar) you may want to use a workaround:
- Make your
Viewbackground transparent. - Create a custom layout using the pattern as background.
- Wrap the
Viewin the custom layout (set the layout width and height towrap_content).
Answered By - Bö macht Blau

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.