7

我正在尝试创建具有圆角和背景的矩形作为重复的位图。我正在这样写,但是在角落里得到位图。

有人可以帮忙吗?

背景.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>
4

2 回答 2

6

我发现Romain Guy 的这篇文章是在平铺位图上圆角的一种更简单的方法。这是简短的答案:

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

您只需将视图的背景可绘制对象设置为这些人之一,您就可以开始了。

于 2013-03-13T18:43:45.097 回答
4

据我了解目标:有一个平铺的背景图像,带有一些弯曲的角落。 平铺和弯曲

它不是像素完美,但它尽可能接近。

首先,这是我用来绘制该按钮的一些布局

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

我就是这样做的,希望有帮助!

如果有人知道一种不那么可怕的方法来实现这一点,请分享。此外,如果有人知道除了抓取绘图缓存之外如何获取平铺位图,那也会很有帮助 - 整个隐藏和恢复子视图有点笨拙。

于 2013-03-01T00:35:40.600 回答