繁体   English   中英

可绘制的最佳实践(密度)

[英]Best practice for drawable(density)

我写了一个小类,可用于创建自定义可绘制对象。 在大多数情况下,一切都按预期工作,但是当显示可绘制对象接近“像素完美”时,我真的不知道如何找到合适的解决方案。 适当的解决方案是在基础形状上获得100%居中的字符/文本。 欢迎任何建议。 提前致谢。

这是课程:

public class DrawableSquareLetter extends Drawable {

    private final Paint paint;
    private Paint textPaint;
    private final Builder builder;


    public DrawableSquareLetter(Builder builder) {
        this.builder = builder;
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(builder.color);

        if (builder.applySurfaceShadow) {
            paint.setShadowLayer(
                    DeviceUtils.dp2px(4),
                    DeviceUtils.dp2px(2),
                    DeviceUtils.dp2px(2),
                    Color.parseColor(MaterialColor.GREY_900));
        }


        textPaint = new Paint();
        textPaint.setColor(builder.textColor);
        textPaint.setAntiAlias(true);
        textPaint.setFakeBoldText(builder.isBold);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setTypeface(builder.typeface);
        textPaint.setTextAlign(Paint.Align.CENTER);

        if (builder.applyTextShadow) {
            textPaint.setShadowLayer(
                    DeviceUtils.dp2px(2),
                    DeviceUtils.dp2px(1),
                    DeviceUtils.dp2px(1),
                    Color.parseColor(MaterialColor.GREY_800));
        }

    }


    @Override
    public void draw(Canvas canvas) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            canvas.drawRoundRect(0, 0, builder.size, builder.size, builder.rounded, builder.rounded, paint);
        } else canvas.drawRect(0, 0, builder.size, builder.size, paint);

        if (builder.textSize == -1) {
            textPaint.setTextSize(builder.size * .80f);
        } else textPaint.setTextSize(builder.textSize);

        float width = builder.size;
        float height = builder.size;

        String text = builder.isUpperCase ? builder.text.toUpperCase() : builder.text;
        canvas.drawText(text, width / 2f, height / 2f - (((textPaint.descent() + textPaint.ascent())) / 2f), textPaint);
    }


    @Override
    public void setAlpha(int alpha) {
        paint.setAlpha(alpha);
    }


    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        paint.setColorFilter(colorFilter);
    }


    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }


    public static class Builder {

        private final float size;
        private final int color;
        private String tag = "";
        private float rounded;
        private final String text;
        private int textColor = Color.BLACK;
        private float textSize = -1;
        private Typeface typeface = Typeface.DEFAULT;

        private boolean isUpperCase = true;
        private boolean isBold = true;
        private boolean applyTextShadow = true;
        private boolean applySurfaceShadow = true;


        public Builder(int sizeDp, int color, String text) {
            this.text = text;
            this.size = DeviceUtils.dp2px(sizeDp);
            this.color = color;
        }


        public Builder(int sizeDp, String color, String text) {
            this.text = text;
            this.size = DeviceUtils.dp2px(sizeDp);
            this.color = Color.parseColor(color);
        }


        public Builder textSize(float textSize) {
            this.textSize = DeviceUtils.sp2px(textSize);
            return this;
        }


        public Builder rounded(int radiusDp) {
            this.rounded = DeviceUtils.dp2px(radiusDp);
            return this;
        }


        public Builder textColor(int textColor) {
            this.textColor = textColor;
            return this;
        }


        public Builder textColor(String textColor) {
            this.textColor = Color.parseColor(textColor);
            return this;
        }


        public Builder typeface(Typeface typeface) {
            this.typeface = typeface;
            return this;
        }


        public Builder disableUpperCase() {
            this.isUpperCase = false;
            return this;
        }


        public Builder disableBold() {
            this.isBold = false;
            return this;
        }


        public Builder disableShadowOnSurface() {
            this.applySurfaceShadow = false;
            return this;
        }


        public Builder disableShadowOnText() {
            this.applyTextShadow = false;
            return this;
        }


        public Builder setTag(String tag) {
            this.tag = tag;
            return this;
        }


        public DrawableSquareLetter build() {
            return new DrawableSquareLetter(this);
        }


        public void show(ImageView imageView) {
            imageView.setImageDrawable(this.build());
        }
    }


    public String getTag() { return builder.tag; }

}

连结5 genymotion 在此处输入图片说明

如果要使文本在基础形状中居中,则需要在正确的位置绘制文本,为此,需要使用Paint.getTextBounds (String text, int start, int end, Rect bounds)

public void getTextBounds(字符串文本,int开头,int结束,Rect范围)

返回(由调用方分配的)边界,该矩形包围所有字符,并且其默认来源为(0,0)。

一旦执行此方法,您将在bounds获得信息。 您需要做的就是在Drawabledraw方法中编写逻辑,在其中您可以计算x / y坐标以执行drawText() (基于此bounds rect)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM