使用Canvas绘制矩形以适合指定的宽度屏幕

时间:2015-04-08 09:29:49

标签: android android-canvas pixel density-independent-pixel

使用下面给出的代码,我们可以检索特定屏幕尺寸的高度和宽度:

    DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
    float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
    float dpWidth = displayMetrics.widthPixels / displayMetrics.density;

我想绘制一行中的矩形,如图所示。我已经选择矩形宽度的默认值为100(在drawRect()中,我已经将右边和左边点之间的差值传递为100,因此每个矩形的宽度为100)。每个矩形包含如图所示的数字。现在,如果位数很小,矩形和数字就会很好。但如果位数很大,则矩形会移出屏幕。对于这种情况,我计算矩形(包括填充,逗号等)将采用的总宽度,并将其与屏幕宽度进行比较。我遇到代码问题,因为我得到的宽度是DP,而我计算的宽度不是。如何更改矩形覆盖的总宽度的计算,以便如果此宽度大于屏幕的宽度,我可以减小矩形的尺寸,以在阴影中渲染矩形。

另外,我想渲染矩形" Centrally Aligned"。我如何实现这一目标。

以下是图片:

enter image description here

该课程的代码如下:

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.StaticLayout;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;

public class CounterWidget extends View {

    private int DIGIT_SIZE = 120;
    private int TEXT_SIZE = 75;
    private int PADDING_LEFT=20;
    private int PADDING_RIGHT=20;
    private int RECT_HEIGHT=135;
    private int RECT_WIDTH=100;
    private int PADDING_BETWEEN_RECTS=10;
    private int PADDING_BETWEEN_RECTANGLE_DIGIT_HORIZONTAL=12;
    private int PADDING_BETWEEN_RECTANGLE_DIGIT_VERTICAL=25;

    private int number = 1200000, rectColor, numColor, counter, noOfCommas, totalPadding;
    private int digits[] = new int[15];
    private Paint widgetPaint, numberPaint, textPaint, commaPaint;
    private String defaultText;

    public CounterWidget(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CounterWidget, 0, 0);
        try {
            rectColor = a.getInteger(R.styleable.CounterWidget_rectColor, 0);
            numColor = a.getInteger(R.styleable.CounterWidget_numberColor, 1);
            defaultText=a.getString(R.styleable.CounterWidget_defaultText);
        } finally {
            a.recycle();
        }
        init();
    }

    private void init() {
        // Paint object for the rectangles.
        widgetPaint = new Paint();
        widgetPaint.setStyle(Paint.Style.FILL);
        widgetPaint.setAntiAlias(true);
        widgetPaint.setColor(rectColor);
        // Paint object for the number.
        numberPaint = new Paint();
        numberPaint.setAntiAlias(true);
        numberPaint.setColor(numColor);
        numberPaint.setTextSize(DIGIT_SIZE);
        // Paint object for the comma.
        commaPaint = new Paint();
        commaPaint.setAntiAlias(true);
        commaPaint.setColor(rectColor);
        commaPaint.setTextSize(DIGIT_SIZE);
        //Calculation for the total number of digits.
        int i = 0;
        while (number > 0) {
            digits[i] = number % 10;
            number = number / 10;
            i++;
        }
        counter = i - 1;
    }

    private void getNoOfCommas()
    {
        int a = counter+1;
        if(a>0&&a<=3)
            noOfCommas=0;
        else if(a>3&&a<=6)
            noOfCommas=1;
        else if(a>6&&a<=9)
            noOfCommas=2;
        else if(a>9&&a<=12)
            noOfCommas=3;
        else
            noOfCommas=4;
    }

    @Override
    protected void onDraw(Canvas canvas) {

        DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();

        float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
        float dpWidth = displayMetrics.widthPixels / displayMetrics.density;

        float pix = dpToPx(getContext(),(int) dpWidth);

        checkForWidth(pix);
        // The text passed in the layout.
        // Starting point for the rendering of the counter.
        Rect rect = new Rect(20, 20, (20+RECT_WIDTH), (20+RECT_HEIGHT)); // Calculation of the starting point.
        // Origin for rendering of the digit inside the rectangle.
        int xx = rect.left + PADDING_BETWEEN_RECTANGLE_DIGIT_HORIZONTAL;
        int yy = (rect.bottom - PADDING_BETWEEN_RECTANGLE_DIGIT_VERTICAL);
        // Origin for rendering the first comma.
        int xxx,yyy = (rect.bottom +10);

        for (int i = counter,j=0; i >= 0; i--,j++) {
            // Drawing the rectangle and using rectangle as reference, drawing the digit.
            drawColoredDigit(canvas, rect, String.valueOf(digits[i]),xx,yy);
            // Updating the reference values for the rectangle.
            rect.left += (PADDING_BETWEEN_RECTS + RECT_WIDTH);
            rect.right += (PADDING_BETWEEN_RECTS + RECT_WIDTH);
            // Updating the reference values for the digits inside the rectangle.
            xx = (rect.left+ PADDING_BETWEEN_RECTANGLE_DIGIT_HORIZONTAL);
            xxx = (rect.left - PADDING_BETWEEN_RECTS/2);

            if(((counter-j)%3==0)&&(counter!=j))
            {
                canvas.drawText(",",xxx,yyy,commaPaint);
                rect.left += (2*PADDING_BETWEEN_RECTS);
                rect.right += (2*PADDING_BETWEEN_RECTS);
                xx = (rect.left + PADDING_BETWEEN_RECTANGLE_DIGIT_HORIZONTAL);
            }
        }
    }

    private void drawColoredDigit(Canvas canvas, Rect rect, String digit, int xx, int yy) {
        canvas.drawRect(rect, widgetPaint);
        canvas.drawText(digit, xx, yy, numberPaint);
    }

    public static int dpToPx(Context context, int dp) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return px;
    }

    public static float convertPixelsToDp(float px, Context context){
        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float dp = px / (metrics.densityDpi / 160f);
        return dp;
    }

        private void checkForWidth(float width)
        {
        getNoOfCommas();
        totalPadding=(PADDING_BETWEEN_RECTS*(counter-1))+(noOfCommas*20)+PADDING_LEFT+PADDING_RIGHT;
        int x = ((counter+1)*RECT_WIDTH)+totalPadding;
        if( width<(x)) {
            DIGIT_SIZE /= 3;
            TEXT_SIZE /= 3;
            RECT_HEIGHT-=30;
            RECT_WIDTH-=30;
            PADDING_BETWEEN_RECTANGLE_DIGIT_VERTICAL/=2;
            PADDING_BETWEEN_RECTANGLE_DIGIT_HORIZONTAL/=2;
        }
        else {
            Continue using the same dimensions.
        }
    }
    public int convertToDp(int input)
    {
        float scale = getResources().getDisplayMetrics().density;
        return (int) (input * scale + 0.5f);
    }}

在上面的代码中,我试图缩小矩形和矩形内的文本。

0 个答案:

没有答案