You can get a pattern of repeating fragments based on drawing elements by creating a custom View and overriding onDraw() .
Let's start by creating a tile in the form of a list of layers consisting of drawing elements, 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 will need the drawableToBitmap() method to convert the fragment to a bitmap, for example 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 need additional steps.
- For a custom
View extension of some Layout set the android:background attribute to any color to cause the onDraw() call - For many, it may be easier to implement and at the same time improve performance to place your own
View below another View (for example, as two children in RelativeLayout ) and make the dimensions match. - If you want to switch from
ImageView , you need to draw a foreground selection on top of the background image. In this case, you can change onDraw() as follows:
onDraw () saving the selected foreground:
@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 can use a workaround:
- Make your
View background transparent. - Create your own layout using a template as a background.
- Wrap the
View in a custom layout (set the width and height of the layout to wrap_content ).
source share