如何在 canvas 中现有矩形的顶部添加矩形

How to add rectangles on top of existing rectangle in canvas

我正在尝试在特定框顶部的现有 canvas 中添加一些红色矩形,就像 预期结果 图像一样,但它们不会出现在当我部署我的应用程序时,我的代码显示了 当前的意外结果。我的代码是在顶行创建 4 个矩形,在底行创建 4 个矩形,但我只想将其添加到框 2-6 的顶部,但我知道需要为框顶部的红色矩形添加额外的代码1 & 7. 有谁知道我做错了什么以及如何解决这个问题?我们将不胜感激。

public class RectangleTextView extends View {
    private final Paint mBlackPaint = new Paint();
    private final Paint mRedPaint = new Paint();
    private final TextPaint mTextPaint;

    public RectangleTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        int valueInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
        int valueInSp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());

        mRedPaint.setColor(Color.parseColor("#CC3333"));

        mBlackPaint.setAntiAlias(false);
        mBlackPaint.setColor(Color.BLACK);
        mBlackPaint.setStrokeWidth(valueInDp);
        mBlackPaint.setStyle(Paint.Style.STROKE);

        mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(Color.BLACK);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setTextSize(valueInSp);

        mWindowPaint = new Paint();
        mWindowPaint.setColor(Color.parseColor("#CC3333"));
        mWindowPaint.setStrokeWidth(valueInDp);
    }

    private Paint mWindowPaint;

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (getWidth() == 0)
            return;

        //initialise red rectangles
        int w = canvas.getWidth();
        int h = canvas.getHeight();

        int rectWidth = w / 5;
        int space = w / 15;
        int topRectHeight = getPaddingTop();
        int bottomRectHeight = getPaddingBottom();


        //draw end rectangles
        int mSideRectWidth = 10;
        canvas.drawRect(0, 0, mSideRectWidth, getHeight(), mRedPaint); //draw left end rectangle
        canvas.drawRect(getWidth() - mSideRectWidth, 0, getWidth(), getHeight(), mRedPaint); //draw right end rectangle

        //draw grey boxes
        setBackgroundColor(Color.parseColor("#808080"));
        int boxWidth = (getWidth() - mSideRectWidth) / 7;

        //draw text views
        for (int i = 0; i < 7; i++) {
            canvas.drawText(Integer.toString(i + 1), (i * boxWidth + 10) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
        }

        //draw black lines
        for (int i = 1; i < 7; i++) {
            canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBlackPaint);
        }

        //draw red windows
        for (int i = 0; i < 4; i++) {
            mWindowPaint.setStyle(Paint.Style.STROKE);//add this
            int left = i * (rectWidth + space);
            int right = left + rectWidth;
            if (i == 1){
                mWindowPaint.setStyle(Paint.Style.FILL); // change to this
            }

            Rect rect = new Rect(left, 0, right, topRectHeight);
            canvas.drawRect(rect, mWindowPaint);
            Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
            canvas.drawRect(rect2, mWindowPaint);
        }
    }
}

预期结果

当前的不良结果

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <com.apptacularapps.car.RectangleTextView
        android:layout_width="100dp"
        android:layout_height="45dp"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:background="#808080"
        android:gravity="center"/>

</RelativeLayout>

MainActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

您正在绘制所有矩形,但看起来您想跳过所有 "odd" 个矩形 - 或者每隔一个矩形...并确保将颜色更改为 "red" - 像这样:

    //draw red windows
    for (int i = 0; i < 4; i++) {
        mWindowPaint.setStyle(Paint.Style.STROKE);//add this
        int left = i * rectWidth;
        int right = left + rectWidth;
        if (i == 1){
            mWindowPaint.setStyle(Paint.Style.FILL); // change to this
        }

        if (i % 2 == 0) {
            Rect rect = new Rect(left, 0, right, topRectHeight);
            canvas.drawRect(rect, mRedPaint);
            Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
            canvas.drawRect(rect2, mRedPaint);
        }
    }
}

编辑:

我认为底部的 "filled" 矩形应该更像:

    //draw red windows
    for (int i = 0; i < 4; i++) {
        int left = i * rectWidth;
        int right = left + rectWidth;

        mWindowPaint.setStyle(Paint.Style.STROKE);//add this
        if (i % 2 == 0) {
            Rect rect = new Rect(left, 0, right, topRectHeight);
            canvas.drawRect(rect, mRedPaint);
            if (i == 1){
                mWindowPaint.setStyle(Paint.Style.FILL); // change to this
            }
            Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
            canvas.drawRect(rect2, mRedPaint);
        }
    }
}

试试这个:

public class RectangleTextView extends View {
    private final Paint mBlackPaint = new Paint();
    private final Paint mRedPaint = new Paint();
    private final TextPaint mTextPaint;

    public RectangleTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        int valueInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
        int valueInSp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());

        mRedPaint.setColor(Color.parseColor("#CC3333"));

        mBlackPaint.setAntiAlias(false);
        mBlackPaint.setColor(Color.BLACK);
        mBlackPaint.setStrokeWidth(valueInDp);
        mBlackPaint.setStyle(Paint.Style.STROKE);

        mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(Color.BLACK);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setTextSize(valueInSp);

        mWindowPaint = new Paint();
        mWindowPaint.setColor(Color.parseColor("#CC3333"));
        mWindowPaint.setStrokeWidth(valueInDp);
    }

    private Paint mWindowPaint;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (getWidth() == 0)
            return;

        //initialise red rectangles
        int h = canvas.getHeight();


        int topRectHeight = getPaddingTop();
        int bottomRectHeight = getPaddingBottom();


        //draw end rectangles
        int mSideRectWidth = 10;
        canvas.drawRect(0, 0, mSideRectWidth, getHeight(), mRedPaint); //draw left end rectangle
        canvas.drawRect(getWidth() - mSideRectWidth, 0, getWidth(), getHeight(), mRedPaint); //draw right end rectangle

        //draw grey boxes
        setBackgroundColor(Color.parseColor("#808080"));
        int boxWidth = (getWidth() - mSideRectWidth) / 7;


        int redRectWidth = boxWidth / 5;
        int redRectSpace = redRectWidth / 3;

        //draw text views
        for (int i = 0; i < 7; i++) {
            canvas.drawText(Integer.toString(i + 1), (i * boxWidth + 10) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);

            int baseStartX = i * boxWidth;

            //draw red windows
            for (int j = 0; j < 4; j++) {
                mWindowPaint.setStyle(Paint.Style.STROKE);//add this
                int left = mSideRectWidth + baseStartX + (j * (redRectWidth + redRectSpace));
                int right = left + redRectWidth;
                if (j == 1) {
                    mWindowPaint.setStyle(Paint.Style.FILL); // change to this
                }

                Rect rect = new Rect(left, 0, right, topRectHeight);
                canvas.drawRect(rect, mWindowPaint);
                Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
                canvas.drawRect(rect2, mWindowPaint);
            }
        }

        //draw black lines
        for (int i = 1; i < 7; i++) {

            int startX = mSideRectWidth + boxWidth * i;
            int startY = 0;
            int stopX = mSideRectWidth + boxWidth * i;
            int stopY = getHeight();
            canvas.drawLine(startX, startY, stopX, stopY, mBlackPaint);

        }
    }
}

问题是您在屏幕上只创建了 4 个矩形,而不是数字单元格大小。 这是代码:

public class RectangleTextView extends View {
    private final Paint mBlackPaint = new Paint();
    private final Paint mRedPaint = new Paint();
    private final TextPaint mTextPaint;

    public RectangleTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        int valueInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
        int valueInSp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());

        mRedPaint.setColor(Color.parseColor("#CC3333"));

        mBlackPaint.setAntiAlias(false);
        mBlackPaint.setColor(Color.BLACK);
        mBlackPaint.setStrokeWidth(valueInDp);
        mBlackPaint.setStyle(Paint.Style.STROKE);

        mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(Color.BLACK);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setTextSize(valueInSp);

        mWindowPaint = new Paint();
        mWindowPaint.setColor(Color.parseColor("#CC3333"));
        mWindowPaint.setStrokeWidth(valueInDp);
    }

    private Paint mWindowPaint;
    Rect rect = new Rect();
    Rect rect2 = new Rect();

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (getWidth() == 0)
            return;

        //initialise red rectangles
        int w = canvas.getWidth();
        int h = canvas.getHeight();

        int rectWidth = ((w - 20) / 7) / 5;
        int space = ((w - 20) / 7) / 15;
        int topRectHeight = getPaddingTop();
        int bottomRectHeight = getPaddingBottom();


        //draw end rectangles
        int mSideRectWidth = 10;
        canvas.drawRect(0, 0, mSideRectWidth, getHeight(), mRedPaint); //draw left end rectangle
        canvas.drawRect(getWidth() - mSideRectWidth, 0, getWidth(), getHeight(), mRedPaint); //draw right end rectangle

        //draw grey boxes
        setBackgroundColor(Color.parseColor("#808080"));
        int boxWidth = (getWidth() - mSideRectWidth) / 7;

        //draw text views
        for (int i = 0; i < 7; i++) {
            canvas.drawText(Integer.toString(i + 1), (i * boxWidth + 10) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
        }

        //draw black lines
        for (int i = 1; i < 7; i++) {
            canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBlackPaint);
        }

        //draw red windows
        for (int index = 0; index < 7; index++) {

            if (index == 0 || index == 6) {
                for (int i = 0; i < 3; i++) {
                    mWindowPaint.setStyle(Paint.Style.STROKE);//add this

                    int left = (i * (rectWidth + space)) + (index * boxWidth) + 13 + rectWidth/2 + space/2;
                    int right = left + rectWidth;

                    rect.set(left, 0, right, topRectHeight);
                    canvas.drawRect(rect, mWindowPaint);

                    if (index == 0 && i == 1) {
                        mWindowPaint.setStyle(Paint.Style.FILL); // change to this
                    }
                    rect2.set(left, h - bottomRectHeight, right, h);
                    canvas.drawRect(rect2, mWindowPaint);

                }

            } else {
                for (int i = 0; i < 4; i++) {
                    mWindowPaint.setStyle(Paint.Style.STROKE);//add this
                    int left = (i * (rectWidth + space)) + (index * boxWidth) + 13;
                    int right = left + rectWidth;

                    rect.set(left, 0, right, topRectHeight);

                    canvas.drawRect(rect, mWindowPaint);

                    rect2.set(left, h - bottomRectHeight, right, h);
                    canvas.drawRect(rect2, mWindowPaint);
                }
            }
        }
    }
}

这是完全适合我的完整代码。如果您有任何问题或疑问,请随时 post :)

我是这样看他们的: