Android - Drawable repeat shape to create pattern

后端 未结 1 1700
情书的邮戳
情书的邮戳 2021-01-12 07:50

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 ima

相关标签:
1条回答
  • 2021-01-12 08:32

    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 View extending some kind of Layout, set the android:background attribute to any color in order to trigger the call to onDraw()
    • For many Views it may be easier to implement and at the same time better for performance to position your custom View below the other View (e.g. as two children in a RelativeLayout) and make the sizes match.
    • If you want to extend from ImageView you will need to draw the foreground drawable on top of the background pattern. In this case, you can modify onDraw() 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 View background transparent.
    • Create a custom layout using the pattern as background.
    • Wrap the View in the custom layout (set the layout width and height to wrap_content).
    0 讨论(0)
提交回复
热议问题