【问题标题】:Bitmap repeat + rounded corners位图重复+圆角
【发布时间】:2012-10-01 14:23:38
【问题描述】:

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

有人可以帮忙吗?

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

【问题讨论】:

    标签: android background bitmap rounded-corners repeat


    【解决方案1】:

    我发现 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);
        }       
    }
    

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

      【讨论】:

      • 这是迄今为止我能找到的最好的解决方案,谢谢!至于突出的角,我设法在位图和角矩形之间添加另一个没有角的矩形来“填充”它。看起来像这样:.
      猜你喜欢
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-09
      • 2013-08-16
      相关资源
      最近更新 更多