Android - 可绘制的重复形状来创建图案

时间:2016-04-20 15:14:44

标签: android android-drawable shapes

我需要创建一个模式来设置为某些ACTION_DATE_CHANGED的背景。我希望模式看起来像这样:

pattern

我不想将任何图像导入drawable,但我想创建自己的形状,图层列表,最终目标是将图案作为背景。

是否可以实现这一点而无需导入任何外部图像?

1 个答案:

答案 0 :(得分:5)

您可以通过创建自定义View并覆盖onDraw()来获得基于形状绘制重复切片的模式。

让我们首先将图块创建为由图形绘制的图层列表,在这种情况下交替使用黑色和白色的正方形:

<强> 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>

您需要使用方法drawableToBitmap()将切片转换为类似here的位图。

覆盖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);
    }
}

根据View的类型,您可能需要采取其他步骤。

  • 对于扩展某种View的自定义Layout,请将android:background属性设置为任意颜色,以便触发对onDraw()的调用
  • 对于许多View来说,实施起来可能更容易,同时更有效地将自定义View定位在另一个View之下(例如,作为RelativeLayout中的两个孩子{1}})并使尺寸匹配。
  • 如果您想从ImageView延伸,则需要在背景图案的顶部绘制前景可绘制。在这种情况下,您可以按如下方式修改onDraw()

onDraw()保留前景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);
}

修改

如上所述,在某些情况下(例如TextViewProgressBar),您可能需要使用变通方法:

  • 让您的View背景透明。
  • 使用图案作为背景创建自定义布局。
  • 将自定义布局中的View换行(将布局宽度和高度设置为wrap_content)。