15

複数のRelativeLayoutsを含む画面を作成したいのですが、上部のレイアウトと下部のレイアウトの角を丸くしたいので、上部のレイアウトでは上部の2つの角を丸め、下部のレイアウトでは下部の2つの角を丸めます。

私の問題は、オンラインで見つけたすべての例で、shape.xmlを使用して丸みを帯びた角を作成し、グラデーションを付けています。これは、relativeLayoutに背景画像を与え、その画像を丸みを帯びさせたいため、十分ではありません。そして、私は両方を行うことができないようです。

どんな助けでも大歓迎です!!

編集-報奨金が開始されました

さて、私はこれで何年もの間壁に頭をぶつけてきました。現在、UITableViewというサードパーティのツールを使用しており、主に何かをテストしています。

https://github.com/thiagolocatelli/android-uitableview

iPhoneのテーブルと同じようにtableViewを設定します。各行に背景画像を付け、上下の行を湾曲させたいと考えています。このUITableViewクラスでは、commitの下で、このコードは呼び出されます

public void commit()
    {
        mIndexController = 0;

        if (mItemList.size() > 1)
        {
            // when the list has more than one item
            for (IListItem obj : mItemList)
            {
                View tempItemView;
                if (mIndexController == 0)
                {
                    //tempItemView = new RoundedView(context_i, this);
                    tempItemView = mInflater.inflate(R.layout.list_item_top,null);


        } 
            else if (mIndexController == mItemList.size() - 1)
            {
                tempItemView = mInflater.inflate(R.layout.list_item_bottom,null);
            } 
            else
            {
                tempItemView = mInflater.inflate(R.layout.list_item_middle,null);
            }
            setupItem(tempItemView, obj, mIndexController);
            tempItemView.setClickable(obj.isClickable());
            mListContainer.addView(tempItemView);
            mIndexController++;

        }
    } 
    else if (mItemList.size() == 1)
    {
        // when the list has only one item
        View tempItemView = mInflater.inflate(R.layout.list_item_single,
                null);
        IListItem obj = mItemList.get(0);
        setupItem(tempItemView, obj, mIndexController);
        tempItemView.setClickable(obj.isClickable());
        mListContainer.addView(tempItemView);
    }
}

彼は上中央と下の行、上と下の丸みを帯びた使用済みXMLのレイアウトスタイルを持っていますが、問題は、各行に画像を与えたいということです。だから私はこのコードを追加しました

tempItemView.setBackgroundResource(R.drawable.background);

ただし、問題は、画像ではなくXMLと白いグラデーションを使用して角が丸められるため、上と下の行の湾曲した角が削除されることです。レイアウトを膨らませてから、上下の角を曲げることができる必要があります。角を切り取った例をたくさん見て、さまざまなサードパーティツールを試しましたが、背景画像をコンテナに適用してから角を丸める例はまだ1つも見つかりませんでした。

誰かがこれを行う方法について何かアイデアがありますか?

編集:

iPhoneでは、次のようなことができます

UIColor *color = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"image.png"]];

画像を色に変換する場所。Androidには同等のものがありますか?

編集:

答えてくれたACheeseのおかげで、私は彼のコードを変更し、3つのメソッドに分けました。1つは上部の丸い角、1つは完全に丸い角、もう1つは下部の丸い角です。

public void setBackgroundRounded(int resID, int w, int h, View v)
    {
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        double dH = (metrics.heightPixels / 100) * 1.5;
        int iHeight = (int)dH;

        Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmp);
        Shader shader = new BitmapShader(BitmapFactory.decodeResource(
                getResources(), resID), Shader.TileMode.MIRROR,
                Shader.TileMode.MIRROR);

        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
        paint.setAntiAlias(true);
        paint.setShader(shader);
        RectF rec = new RectF(0, 0, w, h);
        c.drawRoundRect(rec, iHeight, iHeight, paint);

        v.setBackgroundDrawable(new BitmapDrawable(getResources(), bmp));
    }

    public void setTopRounded(int resID, int w, int h, View v)
    {
        Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmp);
        Shader shader = new BitmapShader(BitmapFactory.decodeResource(
                getResources(), resID), Shader.TileMode.MIRROR,
                Shader.TileMode.MIRROR);

        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
        paint.setAntiAlias(true);
        paint.setShader(shader);
        RectF rec = new RectF(0, 0, w, h - 20);
        c.drawRect(new RectF(0, 20, w, h), paint);
        c.drawRoundRect(rec, 20, 20, paint);
        v.setBackgroundDrawable(new BitmapDrawable(getResources(), bmp));
    }

    public void setBottomRounded(int id, int w, int h, View v)
    {
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        double dH = (metrics.heightPixels / 100) * 1.5;
        int iHeight = (int)dH;

        Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmp);
        Shader shader = new BitmapShader(BitmapFactory.decodeResource(
                getResources(), id), Shader.TileMode.MIRROR,
                Shader.TileMode.MIRROR);
        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
        paint.setAntiAlias(true);
        paint.setShader(shader);
        RectF rec = new RectF(0, 0, w, h);
        c.drawRoundRect(rec, iHeight, iHeight, paint);
        c.drawRect(new RectF(0, 0, w, h-iHeight), paint);

        v.setBackgroundDrawable(new BitmapDrawable(getResources(), bmp));
    }

メトリックを使用してビューを丸める量を設定しているため、さまざまな画面サイズに合わせて拡大縮小します。

この問題を抱えていた他の人に役立つことを願っています!!

4

4 に答える 4

3

だからあなたはこのようなことを試みましたか:

たとえば、これがメインのレイアウトです。

RelativeLayout myMainRelLAyout = (RelativeLayout) findViewById(R.id.my_layout);

そして、やりますMyMainRelLAyout.setBackgroundResource(R.drawable.mydrawable);

mydrawable.xmlは次のようになります。

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <solid android:color="@android:color/white" />

    <corners
        android:bottomLeftRadius="0dip"
        android:bottomRightRadius="0dip"
        android:topLeftRadius="5dip"
        android:topRightRadius="5dip" />
    </shape>

以下のコメントに応じて、私はあなたにこのリンクを提案することができます:Romain Guy-角が丸い画像。ここで、これを行う方法に役立つと思う答えを見つけることができます。

また、ImageViewを使用している別の便利なライブラリがありますが、これを変更して、あらゆる種類のビューに使用できます。リンク:RoundedImageView

于 2013-03-13T12:10:31.430 に答える
2

私のソリューションがあなたのケースで機能するかどうかを確認してください:RelativeLayoutを拡張して独自のレイアウトを定義します。次のコードを追加するだけです

@SuppressWarnings("deprecation")
public void setBackground(int id){
    Bitmap bmp = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(bmp);
    Shader shader = new BitmapShader(BitmapFactory.decodeResource(getResources(), id), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);

    Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
    paint.setAntiAlias(true);
    paint.setShader(shader);
    RectF rec = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());
//  you may need this for only top round corner
//  RectF rec = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()-20);
//  c.drawRect(new RectF(0, 20, getMeasuredWidth(), getMeasuredHeight()),      paint);
    c.drawRoundRect(rec, 20, 20, paint);
    this.setBackgroundDrawable(new BitmapDrawable(getResources(), bmp));

}

アクティビティからこのメソッドを呼び出します。getMeasuredWidth()とgetMeasuredHeight()の準備ができていないため、onCreate()から呼び出すことはできません。独自のドローアブルIDを設定して、onWindowFocusChanged(boolean hasFocused)をオーバーライドして呼び出します。これにより、画像を角の丸い背景として設定することが繰り返されます。

于 2013-03-26T09:40:43.143 に答える
1

さて、私はついに解決策を見つけました。上部の角を丸めるには、この方法を使用します

public Bitmap getTopRoundedCorner(Bitmap bitmap, DisplayMetrics metrics) {

    //Using this so it scales with different screen sizes
    double dH = (metrics.heightPixels / 100.0) * 3;
    int iHeight = (int) dH;

    //Subtract this from bitmap height
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight()-iHeight, Config.ARGB_8888);

    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

    //Again used so it scales with diff screen sizes
    //Can play around with this value, depending on how rounded you wanted the corner
    dH = (metrics.heightPixels / 100.0) * 3.5;
   iHeight = (int) dH;

    final RectF rectF = new RectF(rect);
    final float roundPx = iHeight;

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);

    return output;
  }

下の角だけを丸めたい場合は、この方法を使用してください

public Bitmap getBottomRoundedCorner(Bitmap bitmap) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                    bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);

        //Again play around with this to get the rounded value you require
        double dH = (metrics.heightPixels / 100.0) * 2.5;
        int iHeight = (int) dH;
        final float roundPx = iHeight;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        //Draw second rectangle over the top of the first one
        //So it hides the top rounded corners
        iHeight = (int) dH;

        final int color2 = 0xff424242;
        final Paint paint2 = new Paint();
        Canvas canvas2 = new Canvas(output);
        final Rect testRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()-iHeight);
        final RectF testF = new RectF(testRect);

        paint2.setAntiAlias(true);
        canvas2.drawARGB(0, 0, 0, 0);
        paint2.setColor(color2);
        canvas2.drawRoundRect(testF, roundPx, roundPx, paint2);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas2.drawBitmap(bitmap, testRect, testRect, paint2);
        return output;
      }

また、サイズの異なるさまざまな画像を渡す場合は、最初にこの方法を使用することをお勧めします

public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
        return resizedBitmap;
    }

丸みを帯びた角の方法を適用する前に、画像を同じサイズに拡大縮小します。そうしないと、幅/高さが異なる別の画像を渡すと、渡される画像によって丸みを帯びた角がかなり異なって見えます。画像を拡大縮小するとまず、どの画像を渡しても、かなり一貫しているように見える必要があります。

次に、このようなことを行うことができます

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.tablebackground);
        bmp = getResizedBitmap(bmp, 200, 300);
        bmp = getTopRoundedCorner(bmp);
        BitmapDrawable backgroundDrawable = new BitmapDrawable(getResources(),bmp);
        subLayout = (RelativeLayout) findViewById(R.id.subLayout);
        subLayout.setBackgroundDrawable(backgroundDrawable);

同じ問題を抱えていた他の人の助けになることを願っています!!

于 2013-03-21T16:07:35.017 に答える
0

ビットマップとその角の丸めを設定し、それを相対レイアウトの背景として設定するLayerListを使用するのはどうですか?

ドキュメントには、それを行う方法のステップバイステップが含まれています。

于 2013-03-13T12:17:01.053 に答える