7

角が丸く、背景が繰り返しビットマップである長方形を作成しようとしています。私はこのように書いていますが、隅にビットマップがあります。

誰か助けてもらえますか?

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

ビューの背景ドローアブルをこれらの人の1人に設定するだけで、準備は完了です。

于 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 に答える