【问题标题】:Drawing emojis on Android canvas using unicode values使用 unicode 值在 Android 画布上绘制表情符号
【发布时间】:2017-05-03 21:14:37
【问题描述】:

我正在尝试为我的 Android 应用创建一个 自定义视图。在OnDraw 函数中,我试图通过使用它的unicode 值来绘制一个emoji,但这似乎不起作用。以下是代码:

public class Scale extends View {
    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final static int LINE_WIDTH = 10;
    ...
    ...
    @Override
    protected void onDraw(final Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(LINE_WIDTH);
        mPaint.setColor(Color.BLUE);
        ...
        ...
        //This works
        canvas.drawText("My text", 0.05f*width, 0.80f*height, mPaint);
        //But this does NOT draw a doughnut!!
        String s = new String(Character.toChars(0x1F369)); //Doughnut
        canvas.drawText(s, 0.75f*width, 0.50f*height, mPaint);
    }
}

有人知道这里是否有解决方法吗?还是我做错了什么?

编辑 [第二个问题]: 通过我在下面提交的 hack,我看到 Emojis 在 Canvas 上绘制的 TextView 内呈现,但它们与在普通 TextView 上设置的 Emojis 相比,明显暗淡,如下所示:

知道我在这里缺少什么吗?

【问题讨论】:

    标签: java android canvas unicode emoji


    【解决方案1】:

    对于它的价值,我找到了一个黑客,我自己不太喜欢!在此,我创建一个Layout(例如LinearLayout)并添加一个包含我的表情符号的TextView,然后在Canvas 上绘制Layout

    public class Scale extends View {
        private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        private final LinearLayout layout;
        ...
        ...
        public Scale(final Context context, ...) {
            super(context);
            ...
            ...
            //Initialise the layout & add a TextView with the emoji in it
            layout = new LinearLayout(context);
            final TextView tv = new TextView(context);
            tv.setText(new String(Character.toChars(0x1F369))); //Doughnut
            layout.addView(tv);
            layout.measure(50, 50);
            layout.layout(0, 0, 50, 50);
        }
        @Override
        protected void onDraw(final Canvas canvas) {
            super.onDraw(canvas);
            ...
            ...
            canvas.translate(20, 20); //Translate if necessary
            //Draw the layout on the canvas, draws a doughnut!!
            layout.draw(canvas);
            canvas.save();
            canvas.restore();
        }
    }
    

    如果有更好的解决方案,请发布。

    编辑

    我发现StaticLayout 是在画布上绘制文本的更好选择,并且不会出现文本/表情符号变暗的问题

    我修改后的代码(比之前少了几行):

    public class Scale extends View {
        private final TextPaint tPaint = new TextPaint();
        private final StaticLayout lsLayout;
        ...
        ...
        public Scale(final Context context, ...) {
            super(context);
            ...
            ...
            //Initialise the layout & add a TextView with the emoji in it
            String emoji = new String(Character.toChars(0x1F369))); //Doughnut
            lsLayout = new StaticLayout(emoji, tPaint, 80, Layout.Alignment.ALIGN_CENTER, 1, 1, true);
        }
        @Override
        protected void onDraw(final Canvas canvas) {
            super.onDraw(canvas);
            ...
            ...
            canvas.translate(20, 20); //Translate if necessary
            //Draw the layout on the canvas, draws a doughnut as bright as the rest of the canvas!!
            lsLayout.draw(canvas);
            canvas.save();
            canvas.restore();
        }
    }
    

    这是结果,表情符号与画布上的其余部分一样亮:

    【讨论】:

      【解决方案2】:

      问题是您的表情符号超出了 0000 - FFFF 的范围 所以它不能表示为单个 unicode 字符。

      如果您为表情符号正确编码“unicode 代理对”,则可能是可能的。

      有一个计算器可以确定正确的多字节 unicode 代理对 在:http://www.russellcottrell.com/greek/utilities/surrogatepaircalculator.htm

      【讨论】:

      • 谢谢,但这似乎没有帮助:String s = new String(Character.toChars(0xD83C)) + new String(Character.toChars(0xDF69)) ; //Doughnut canvas.drawText(s, 0.75f*width, 0.50f*height, mPaint);
      猜你喜欢
      • 2020-07-06
      • 1970-01-01
      • 2016-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多