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

Android 使用画布绘制矩形以适合指定宽度的屏幕,android,android-canvas,pixel,density-independent-pixel,Android,Android Canvas,Pixel,Density Independent Pixel,使用下面给出的代码,我们可以检索特定屏幕大小的高度和宽度: DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics(); float dpHeight = displayMetrics.heightPixels / displayMetrics.density; float dpWidth = displayMetrics.widthPixels / displayMetr

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

    DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
    float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
    float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
我想画一行矩形,如图所示。我为矩形宽度选择了默认值100(在drawRect()中,我将左右点之间的差值传递为100,因此每个矩形的宽度为100)。每个矩形包含如图所示的数字。现在,如果数字的数量很小,则矩形和数字将被精细渲染。但是,如果数字的数量很大,矩形就会出现在屏幕之外。对于这种情况,我计算矩形(包括填充、逗号等)的总宽度,并将其与屏幕宽度进行比较。我对代码有问题,因为我得到的宽度是DP,而我计算的宽度不是DP。如何更改矩形覆盖的总宽度的计算,以便在该宽度大于屏幕宽度时,可以减小矩形的尺寸,以在屏幕中渲染矩形

此外,我还希望渲染“中心对齐”的矩形。我如何做到这一点

下图所示为:

该类代码如下所示:

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);
    }}
导入android.content.Context;
导入android.content.res.Resources;
导入android.content.res.TypedArray;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.Rect;
导入android.text.StaticLayout;
导入android.util.AttributeSet;
导入android.util.DisplayMetrics;
导入android.util.Log;
导入android.view.Display;
导入android.view.view;
导入android.view.ViewGroup;
公共类CounterWidget扩展视图{
专用整数位数_SIZE=120;
私有整数文本大小=75;
私有int PADDING_LEFT=20;
私有整数PADDING_RIGHT=20;
私有整数矩形高度=135;
私有整数矩形宽度=100;
矩形之间的私有整数填充=10;
矩形与数字之间的私有整数填充=12;
矩形与数字之间的私有整数填充=25;
私有整数=1200000,矩形颜色,numColor,计数器,noOfCommas,totalPadding;
私有整数位数[]=新整数[15];
私人油漆widgetPaint、numberPaint、textPaint、commaPaint;
私有字符串默认文本;
公共计数器小部件(上下文、属性集属性){
超级(上下文,attrs);
TypedArray a=context.getTheme().ActainStyledAttributes(attrs,R.styleable.CounterWidget,0,0);
试一试{
rectColor=a.getInteger(R.styleable.CounterWidget\u rectColor,0);
numColor=a.getInteger(R.styleable.CounterWidget_numberColor,1);
defaultText=a.getString(R.styleable.CounterWidget\u defaultText);
}最后{
a、 回收();
}
init();
}
私有void init(){
//为矩形绘制对象。
widgetPaint=新绘制();
widgetPaint.setStyle(Paint.Style.FILL);
widgetPaint.setAntiAlias(true);
setColor(rectColor);
//为数字绘制对象。
numberPaint=新油漆();
numberPaint.setAntiAlias(真);
numberPaint.setColor(numColor);
numberPaint.setTextSize(数字大小);
//为逗号绘制对象。
commaPaint=新油漆();
commaPaint.setAntiAlias(真);
commaPaint.setColor(rectColor);
commaPaint.setTextSize(数字大小);
//计算总位数。
int i=0;
而(数量>0){
数字[i]=数字%10;
数字=数字/10;
i++;
}
计数器=i-1;
}
私有void getNoOfCommas()
{
INTA=计数器+1;
如果(a>0&&a3&&a6&&a9&&a=0;i--,j++){
//绘制矩形,并使用矩形作为参考,绘制数字。
drawColoredDigit(canvas、rect、String.valueOf(数字[i])、xx、yy);
//更新矩形的参考值。
rect.left+=(矩形之间的填充+矩形宽度);
rect.right+=(矩形之间的填充+矩形宽度);
//更新矩形内数字的参考值。
xx=(矩形左+矩形和数字之间的填充);
xxx=(rect.left-在_RECTS/2之间填充_);
如果(((计数器-j)%3==0)和(&(计数器!=j))
{
canvas.drawText(“,”,xxx,yyy,commaPaint);
rect.left+=(2*矩形之间的填充);
rect.right+=(2*矩形之间的填充);
xx=(矩形左+矩形和数字之间的填充);
}
}
}
私有void drawColoredDigit(画布、矩形、字符串数字、整数xx、整数yy){
canvas.drawRect(rect,widgetPaint);
画布.绘图文本(数字,xx,yy,数字绘画);
}
公共静态int-dpToPx(上下文,int-dp){
DisplayMetrics DisplayMetrics=context.getResources().getDisplayMetrics();
int px=Math.round(dp*(displayMetrics.xdpi/displayMetrics.DENSITY_默认值));
返回px;
}
公共静态浮点转换器PIXELSTODP(浮点px,上下文){
Resources=context.getResources();
DisplayMetrics=resources.getDisplayMetrics();
浮点数dp=px/(公制密度dpi/160f);
返回dp;
}
专用void checkForWidth(浮动宽度)
{
getNoOfCommas();
totalPadding=(在两个矩形之间填充*(计数器-1))+(noOfCommas*20)+左填充+右填充;
INTX=((计数器+1)*矩形宽度)+总填充;

如果你能发布你的班级代码吗?我已经在问题中添加了代码。到目前为止,这些值已经硬编码。但是为了使代码适用于所有手机尺寸,我想根据