Android - Hand-drawn repeat pattern to create a drawing

I need to create a template to set some View as the background. I want the template to look something like this:

pattern

I don’t want to import any image for drawing, but instead I want to create my own shapes, a list of layers and the ultimate goal is to create a picture as a background.

Is it possible to achieve this without having to import any external image?

+6
source share
1 answer

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 ).
+5
source

Source: https://habr.com/ru/post/1247536/


All Articles