RoundRectShapeの引数について調査した

角丸画像をコードから生成したくて、ShapeDrawableを使うことになった。 角丸にするにはRoundRectShapeをShapeDrawableに食わせるんだけど、その引数がドキュメントだけだと分からなかったので検証した。

RoundRectShape(float outerRadii, RectF inset, float innerRadii) RoundRectShape constructor. Specifies an outer (round)rect and an optional inner (round)rect. outerRadii float: An array of 8 radius values, for the outer roundrect. The first two floats are for the top-left corner (remaining pairs correspond clockwise). For no rounded corners on the outer rectangle, pass null.

時計回りで指定すればいいんだよってことは分かるけど、8つ渡すのはよく分からなかった。

RoundRectShape | Android Developers

結論からいうと以下のようになっている

float[]{
  topLeft-x, topLeft-y,
  topRight-x, topRight-y,
  bottomRight-x, bottomRight-y,
  bottomLeft-x, bottomLeft-y
}

4つの角 + xとyで8つある理由ですね。 検証に使用したコードを載せておきます。

f:id:tomorrowkey:20160512132934p:plain:w200

import android.content.Context;
import android.databinding.DataBindingUtil;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import jp.tomorrowkey.android.roundrectshapeapp.databinding.ActivityMainBinding;
import jp.tomorrowkey.android.roundrectshapeapp.databinding.ListItemBinding;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        binding.recyclerView.setAdapter(new MyRecyclerViewAdapter(this));
    }

    private static class MyRecyclerViewAdapter extends RecyclerView.Adapter<ViewHolder> {

        private static float[][] PATTERNS = new float[][]{
                {50, 50, 0, 0, 0, 0, 0, 0},
                {0, 0, 50, 50, 0, 0, 0, 0},
                {0, 0, 0, 0, 50, 50, 0, 0},
                {0, 0, 0, 0, 0, 0, 50, 50},
                {50, 50, 50, 50, 0, 0, 0, 0},
                {25, 50, 25, 50, 0, 0, 0, 0},
                {25, 50, 25, 50, 25, 50, 25, 50},
        };

        private static final int SOLID_COLOR = Color.rgb(0x00, 0x80, 0x80);

        private static final int RECT_SIZE = 100;

        LayoutInflater inflater;

        public MyRecyclerViewAdapter(Context context) {
            inflater = LayoutInflater.from(context);
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new ViewHolder(inflater.inflate(R.layout.list_item, parent, false));
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            ListItemBinding binding = DataBindingUtil.bind(holder.itemView);

            float[] outerR = PATTERNS[position];
            binding.textView.setText("{" + Util.join(outerR, " ,") + "}");

            ShapeDrawable drawable = new ShapeDrawable(new RoundRectShape(outerR, null, null));
            drawable.getPaint().setColor(SOLID_COLOR);
            drawable.getPaint().setStyle(Paint.Style.FILL);
            drawable.setIntrinsicHeight(RECT_SIZE);
            drawable.setIntrinsicWidth(RECT_SIZE);
            binding.imageView.setImageDrawable(drawable);
        }

        @Override
        public int getItemCount() {
            return PATTERNS.length;
        }
    }

    private static class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View itemView) {
            super(itemView);
        }
    }

}