How to make border more smooth
Asked Answered
S

4

5

I want to add border for view, border width, color, radius can be set by user. So I try to draw a rect for it. When I use drawRoundRect to draw, the line at the corner is not smooth, it is thicker than the other places too. I don't know how to fix it. Please give me some instruction. Is there any other way to do it? I have to use code to draw it.

Thanks very much. attached code: red corner of rect. past code:

public class MPCTextView extends TextView {
    // private Context context;
    private final static String TAG = "MPCTextView";
    public final static int DEFAULT_BACKGROUND_COLOR = Color
            .parseColor("#28FF28");
    public final static int DEFAULT_BORDER_COLOR = Color.parseColor("#FF0000");

    public int mBoderWidth = 2;
    public int mBoderColor;
    public int mBoderRadius = 20;
    public int mbackgroundColor;
    public boolean isHaveBorder = true;
    public boolean isHaveBackground = true;
    RectF mRectF = new RectF();
    Rect mRec = new Rect();
    Paint mPaint = new Paint();

    public MPCTextView(Context context) {
        super(context);
        // this.context = context;
    }

    @Override
    protected void onDraw(Canvas canvas) {

        // try to add a boder for this view.
        canvas.getClipBounds(mRec);

        // draw background
        // canvas.drawColor(mbackgroundColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(DEFAULT_BACKGROUND_COLOR);
        if (mBoderRadius > 0) {
            mRectF.set(mRec);
            canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);

        } else {
            canvas.drawRect(mRec, mPaint);
        }

        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mBoderWidth);
        mPaint.setColor(DEFAULT_BORDER_COLOR);
                mPaint.setAntiAlias(true);

        if (mBoderRadius > 0) {
            mRectF.set(mRec);
            canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);

        } else {
            canvas.drawRect(mRec, mPaint);
        }

        super.onDraw(canvas);

    }

enter image description here

Swayback answered 19/7, 2013 at 15:49 Comment(0)
C
9

The core of the problem is the padding, not AntiAliasing. The corner is not thicker, rather, it is the normal width. But, the straight line is clipped.

If you set the stroke width to 2, the really straight line width is 1 because the stroke is rectangular and the axis is the line x = 0. This means the rectangle is (left=0,up=-1,right=length,bottom=1), but the up -1 is outside of the canvas, so it will not be painted. And the corner is full width, because it is in the canvas.

So, you just to need set the padding.

Here is the code to make the rounded rect draw completely inside the canvas:

float pad = 1f;
mRectF.set(new RectF(mRec.left + pad, mRec.top + pad, mRec.right - pad, mRec.bottom - pad));
canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);
Complementary answered 12/11, 2015 at 8:58 Comment(1)
Saved me a lot of headache, works like a charm and perfectly explained, hero!Caustic
S
1

Set the antialias to the paint you are using to draw the red rectangle . For instance

mPaint.setAntiAlias(true);
Slotnick answered 19/7, 2013 at 15:51 Comment(2)
Thanks you very much. In fact, i had add it in my code. But it is not good enough for me. Do you have any other idea?Swayback
the mPaint.setDither(true);Slotnick
D
0

I want this code to be help you.

public int mBoderWidth = 2;
public int mBoderColor;
public int mBoderRadius = 20;
public int mbackgroundColor;
public boolean isHaveBorder = true;
public boolean isHaveBackground = true;
RectF mRectF = new RectF();
Rect mRec = new Rect();
Paint mPaint = new Paint();

public MPCTextView(Context context) {
    super(context);
    // this.context = context;
}

@Override
protected void onDraw(Canvas canvas) {

    // try to add a boder for this view.
    canvas.getClipBounds(mRec);

    // draw background
    // canvas.drawColor(mbackgroundColor);
    mPaint.setStyle(Paint.Style.FILL);
    mPaint.setColor(DEFAULT_BACKGROUND_COLOR);
    if (mBoderRadius > 0) {
        mRectF.set(mRec);
        canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);

    } else {
        canvas.drawRect(mRec, mPaint);
    }

    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(mBoderWidth);
    mPaint.setColor(DEFAULT_BORDER_COLOR);
    mPaint.setAntiAlias(true);

    if (mBoderRadius > 0) {
        mRectF.set(mRec);

        ///////////// look at this code
        mRectF.left += mBorderWidth/2;
        mRectF.right -= mBorderWidth/2;
        mRectF.top += mBorderWidth/2;
        mRectF.bottom -= mBorderWidth/2;

        canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);

        mRectF.left -= mBorderWidth/2;
        mRectF.right += mBorderWidth/2;
        mRectF.top -= mBorderWidth/2;
        mRectF.bottom += mBorderWidth/2;
    } else {
        canvas.drawRect(mRec, mPaint);
    }

    super.onDraw(canvas);
}
Demosthenes answered 15/1, 2014 at 12:22 Comment(0)
H
0

I know I am answering this question very late but it may help others modify your code like below will work

Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
Hinge answered 21/9, 2018 at 10:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.