[Android] [Android] custom fillet image. You can set whether any corner is fillet in xml

Keywords: Android xml encoding

[Android] [Android] custom fillet image. You can set whether any corner is fillet in xml

This blog has been included in my android development summary - Click [Android development summary]
  • This blog has a reference blog[ android customize a fillet ImageView]
  • Compared with the original blog, this blog has the following improvements:
    1. You can set whether any of the four corners is a fillet in xml.
    2. Change px to dp.
    2. Add principle description.

The revised code is as follows:

1. In the values folder, create a new attrs.xml resource file.
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="C2RoundAngleImageView">
        <attr name="roundWidth2" format="dimension" />
        <attr name="roundHeight2" format="dimension" />
        <attr name="leftUpCorner" format="boolean" />
        <attr name="rightUpCorner" format="boolean" />
        <attr name="leftDownCorner" format="boolean" />
        <attr name="rightDownCorner" format="boolean" />
    </declare-styleable>
</resources>
2. Customize the View.
public class C2RoundAngleImageView extends ImageView {

    private Paint paint;
    private int roundWidth = 10;
    private int roundHeight = 10;
    private boolean rightUpCorner = true;
    private boolean leftUpCorner = true;
    private boolean rightDownCorner = true;
    private boolean leftDownCorner = true;
    private Paint paint2;
    private static Context context;

    public C2RoundAngleImageView(Context context) {
        super(context);
        init(context, null);
    }

    public C2RoundAngleImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public C2RoundAngleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        this.context = context;
        if(attrs != null) {
            //Point1
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.C2RoundAngleImageView);
            roundWidth= a.getDimensionPixelSize(R.styleable.C2RoundAngleImageView_roundWidth2, roundWidth);
            roundHeight= a.getDimensionPixelSize(R.styleable.C2RoundAngleImageView_roundHeight2, roundHeight);
            rightUpCorner = a.getBoolean(R.styleable.C2RoundAngleImageView_rightUpCorner,true);
            rightDownCorner = a.getBoolean(R.styleable.C2RoundAngleImageView_rightDownCorner,true);
            leftUpCorner = a.getBoolean(R.styleable.C2RoundAngleImageView_leftUpCorner,true);
            leftDownCorner = a.getBoolean(R.styleable.C2RoundAngleImageView_leftDownCorner,true);
        }else {
            //Point2
            float density = context.getResources().getDisplayMetrics().density;
            roundWidth = (int) (roundWidth*density);
            roundHeight = (int) (roundHeight*density);
        }

        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        //Point3
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));

        paint2 = new Paint();
        paint2.setXfermode(null);
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    public void draw(Canvas canvas) {
        //Point4
        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_4444);
        try {
            Canvas canvas2 = new Canvas(bitmap);
            //Point5
            super.draw(canvas2);
            if(leftUpCorner){
                //Point6
                drawLiftUp(canvas2);
            }
            if(leftDownCorner){
                drawLiftDown(canvas2);
            }
            if(rightUpCorner){
                drawRightUp(canvas2);
            }
            if(rightDownCorner){
                drawRightDown(canvas2);
            }
            //Point7
            canvas.drawBitmap(bitmap, 0, 0, paint2);
            bitmap.recycle();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    private void drawLiftUp(Canvas canvas) {
        Path path = new Path();
        path.moveTo(0, roundHeight);
        path.lineTo(0, 0);
        path.lineTo(roundWidth, 0);
        path.arcTo(new RectF(
                        0,
                        0,
                        roundWidth * 2,
                        roundHeight * 2),
                -90,
                -90);
        path.close();
        canvas.drawPath(path, paint);
    }

    private void drawLiftDown(Canvas canvas) {
        Path path = new Path();
        path.moveTo(0, getHeight()-roundHeight);
        path.lineTo(0, getHeight());
        path.lineTo(roundWidth, getHeight());
        path.arcTo(new RectF(
                        0,
                        getHeight()-roundHeight*2,
                        0+roundWidth*2,
                        getHeight()),
                90,
                90);
        path.close();
        canvas.drawPath(path, paint);
    }

    private void drawRightDown(Canvas canvas) {
        Path path = new Path();
        path.moveTo(getWidth()-roundWidth, getHeight());
        path.lineTo(getWidth(), getHeight());
        path.lineTo(getWidth(), getHeight()-roundHeight);
        path.arcTo(new RectF(
                getWidth()-roundWidth*2,
                getHeight()-roundHeight*2,
                getWidth(),
                getHeight()), 0, 90);
        path.close();
        canvas.drawPath(path, paint);
    }

    private void drawRightUp(Canvas canvas) {
        Path path = new Path();
        path.moveTo(getWidth(), roundHeight);
        path.lineTo(getWidth(), 0);
        path.lineTo(getWidth()-roundWidth, 0);
        path.arcTo(new RectF(
                        getWidth()-roundWidth*2,
                        0,
                        getWidth(),
                        0+roundHeight*2),
                -90,
                90);
        path.close();
        canvas.drawPath(path, paint);
    }

}
  • Point1: receive the parameters set in xml here.
  • Point2: convert px to dp here.
  • Point3: set the Xfermode type of the brush to porterduff.mode.dst'ou out, which can be understood as drawing the source image where there is no intersection
  • Point4: create a Bitmap object that can be modified according to the size of canvas.
  • Point5: create a canvas of canvas2 according to the bitmap object, and let the View drawn to the canvas be drawn to the bitmap of canvas2. See the source code:
    public void draw(Canvas canvas) {
        final int privateFlags = mPrivateFlags;
        final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
                (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
        mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;

        /*
         * Draw traversal performs several drawing steps which must be executed
         * in the appropriate order:
         *
         *      1. Draw the background
         *      2. If necessary, save the canvas' layers to prepare for fading
         *      3. Draw view's content
         *      4. Draw children
         *      5. If necessary, draw the fading edges and restore layers
         *      6. Draw decorations (scrollbars for instance)
         */
         ... ...
         }
  • Point6: draw a Path closed Path to be cut in the upper left corner, and make Xfermode processing with the canvas to cut out the fillet. The contour of bitmap changes with canvas 2.
  • Point7: draw the bitmap with the rounded corners to the canvas canvas to be displayed.
3. Used in xml.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:round="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">
    <!-- List pictures -->
    <com.example.weihy.mygithubproject.C2RoundAngleImageView
        android:id="@+id/c2lamp_recipe_img"
        android:layout_width="300dp"
        android:layout_height="160dp"
        android:scaleType="centerCrop"
        android:src="@drawable/coffee"
        round:leftUpCorner="false"
        round:rightDownCorner="false"
        round:roundHeight2="50dp"
        round:roundWidth2="50dp"
        />
</LinearLayout>
4. Renderings.

Posted by eddy556 on Sat, 28 Mar 2020 10:19:36 -0700