据我了解目标:有一个平铺的背景图像,带有一些弯曲的角落。
它不是像素完美,但它尽可能接近。
首先,这是我用来绘制该按钮的一些布局
the_button.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/wrapper_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/bg_curved_tiled"
android:padding="20dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Some Text" />
</FrameLayout>
这就是使用它作为它的背景
bg_curved_tiled.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@id/layer_needs_rounding">
<bitmap
android:src="@drawable/patch"
android:tileMode="repeat" />
</item>
<item>
<shape
android:shape="rectangle"
android:useLevel="false" >
<stroke
android:width="3dp"
android:color="#666666" />
<solid android:color="@null" />
<corners
android:bottomLeftRadius="@dimen/radius_corner_default"
android:bottomRightRadius="@dimen/radius_corner_default"
android:radius="@dimen/radius_corner_default"
android:topLeftRadius="@dimen/radius_corner_default"
android:topRightRadius="@dimen/radius_corner_default" />
</shape>
</item>
</layer-list>
此时,您有一个看起来像这样的图像
如您所见,平铺位图在角落处伸出覆盖在其顶部的弯曲形状。
所以现在你需要一个圆角位图的函数......我在stackoverflow的其他地方得到了这个
public static Bitmap createRoundedCornerBitmap(Context context,
Bitmap input, float roundPx, boolean squareTL, boolean squareTR,
boolean squareBR, boolean squareBL) {
if (input == null) {
return null;
}
final int w = input.getWidth(), h = input.getHeight();
Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
// draw rectangles over the corners we want to be square
if (squareTL) {
canvas.drawRect(0, 0, w / 2, h / 2, paint);
}
if (squareTR) {
canvas.drawRect(w / 2, 0, w, h / 2, paint);
}
if (squareBL) {
canvas.drawRect(0, h / 2, w / 2, h, paint);
}
if (squareBR) {
canvas.drawRect(w / 2, h / 2, w, h, paint);
}
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(input, 0, 0, paint);
return output;
}
差不多好了!我讨厌这部分——我还没有找到更好的方法来获取其中包含实际平铺位图的位图对象。例如,BitmapDrawable.getBitmap 只是为您提供单独的补丁位图,而不是平铺的重复补丁画布......真糟糕。因此,相反,我正在获取视图的绘图缓存。您需要首先确保视图已完全初始化(已计算出高度和宽度并适当地平铺),post
然后到视图并在那里进行处理。
private void shaveOffCorners(final ViewGroup view) {
view.post(new Runnable() {
@Override
public void run() {
// make all child views invisible before scraping the drawing cache
SparseIntArray viewStates = new SparseIntArray();
for(int index = 0; index < view.getChildCount(); ++index) {
View child = view.getChildAt(index);
viewStates.put(index, child.getVisibility());
child.setVisibility(View.INVISIBLE);
}
view.buildDrawingCache();
// this is the exact bitmap that is currently rendered to screen. hence, we wanted to
// hide all the children so that they don't permanently become part of the background
final Bitmap rounded = view.getDrawingCache();
// restore actual visibility states after getting the drawing cache
for(int index = 0; index < view.getChildCount(); ++index) {
View child = view.getChildAt(index);
child.setVisibility(viewStates.get(index));
}
view.setBackgroundDrawable(new BitmapDrawable(
getResources(),
MyImageUtil.createRoundedCornerBitmap(
view.getContext(),
rounded,
getResources().getDimensionPixelSize(R.dimen.radius_corner_default),
false, true, true, false)));
}
});
}
我就是这样做的,希望有帮助!
如果有人知道一种不那么可怕的方法来实现这一点,请分享。此外,如果有人知道除了抓取绘图缓存之外如何获取平铺位图,那也会很有帮助 - 整个隐藏和恢复子视图有点笨拙。