【发布时间】:2016-04-20 15:14:44
【问题描述】:
我需要创建一个图案来设置为一些View 的背景。我希望模式看起来像这样:
我不想将任何图像导入可绘制对象,而是想创建自己的形状、图层列表,最终目标是将图案作为背景。
是否可以在不导入任何外部图像的情况下实现这一目标?
【问题讨论】:
标签: android android-drawable shapes
我需要创建一个图案来设置为一些View 的背景。我希望模式看起来像这样:
我不想将任何图像导入可绘制对象,而是想创建自己的形状、图层列表,最终目标是将图案作为背景。
是否可以在不导入任何外部图像的情况下实现这一目标?
【问题讨论】:
标签: android android-drawable shapes
您可以通过创建自定义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 的类型,您可能需要采取额外的步骤。
Layout 的自定义View,将android:background 属性设置为任何颜色以触发对onDraw() 的调用
Views,将您的自定义View 置于另一个View 下方(例如作为RelativeLayout 中的两个孩子)可能更容易实现,同时性能更好尺寸匹配。ImageView 扩展,您需要在背景图案的顶部绘制前景可绘制对象。这种情况下,你可以修改onDraw()如下:onDraw() 保留前景可绘制对象:
@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);
}
编辑
如上所述,在某些情况下(例如TextView、ProgressBar)您可能需要使用解决方法:
View 背景透明。View 包裹在自定义布局中(将布局宽度和高度设置为wrap_content)。【讨论】: