我正在尝试创建带圆角的矩形和背景作为重复的位图。我这样写,但是在角落里得到位图。
有人可以帮忙吗?
background.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<stroke
android:width="1dp"
android:color="#FFFFFF" />
<corners android:radius="50dp" />
</shape>
</item>
<item>
<bitmap
android:src="@drawable/carbon_4"
android:tileMode="repeat" />
</item>
</layer-list>
答案 0 :(得分:5)
我找到了Romain Guy的this post,这是一种在平铺位图上圆角更容易的方法。这是简短的回答:
class CurvedAndTiled extends Drawable {
private final float mCornerRadius;
private final RectF mRect = new RectF();
private final BitmapShader mBitmapShader;
private final Paint mTilePaint;
CurvedAndTiled(
Bitmap bitmap,
float cornerRadius) {
mCornerRadius = cornerRadius;
mBitmapShader = new BitmapShader(bitmap,
Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
mTilePaint = new Paint();
mTilePaint.setAntiAlias(true);
mTilePaint.setShader(mBitmapShader);
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRect.set(0, 0, bounds.width(), bounds.height());
}
@Override
public void draw(Canvas canvas) {
canvas.drawRoundRect(mRect, mCornerRadius, mCornerRadius, mTilePaint);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void setAlpha(int alpha) {
mTilePaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
mTilePaint.setColorFilter(cf);
}
}
你只是将你的视图背景画成了这些家伙之一,你就可以了。
答案 1 :(得分:4)
据我了解目标:有一个带有一些弯角的平铺背景图像。
它不完全像素,但它尽可能接近。
首先,这里有一些我用来绘制按钮的布局
<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>
并且那就是以此为背景
<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;
}
几乎就在那里!
我讨厌这个部分 - 我还没有找到任何更好的方法来获取其中包含实际平铺位图的Bitmap对象。例如,BitmapDrawable.getBitmap只为您提供单独的补丁位图,而不是平铺的重复补丁画布... bummer。所以相反,我得到了视图的绘图缓存。您需要确保视图已完全初始化(高度和宽度已经计算出并适当平铺),因此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)));
}
});
}
这就是我做到的,希望有所帮助!
如果有人知道一个不太可怕的方法来完成这个,请分享。此外,如果有人知道除了绘制绘图缓存之外如何获得平铺位图,那也是有用的 - 整个隐藏和恢复子视图有点笨拙。