使用 unicode 值在 Android canvas 上绘制表情符号
Drawing emojis on Android canvas using unicode values
我正在尝试为我的 android 应用程序创建一个 自定义视图 。在 OnDraw
函数中,我试图通过使用其 unicode
值来绘制 表情符号 ,但这似乎不起作用。以下是代码:
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,我看到表情符号在 TextView
绘制在 Canvas
上,但与在普通 TextView 上设置的 Emojis 相比,它们显着 暗淡 ,如下所示:
知道我在这里错过了什么吗?
问题是您的表情符号字符超出了 0000 - FFFF 的范围
所以它不能表示为单个 unicode 字符。
如果您为表情符号正确编码 "unicode surrogate pairs" 可能是可能的。
有一个计算器可以确定正确的多字节 unicode 代理对
在:http://www.russellcottrell.com/greek/utilities/surrogatepaircalculator.htm
无论如何,我找到了一个 hack,我自己不太喜欢!在此,我创建一个 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();
}
}
如果有更好的解决办法请post
编辑
我发现 StaticLayout 是在 canvas 上绘制文本的更好选择,并且 没有 text/emoji 变暗的问题.
我修改后的代码(比之前少了行):
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();
}
}
这是结果,表情符号和 canvas 上绘图的其余部分一样亮:
我正在尝试为我的 android 应用程序创建一个 自定义视图 。在 OnDraw
函数中,我试图通过使用其 unicode
值来绘制 表情符号 ,但这似乎不起作用。以下是代码:
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,我看到表情符号在 TextView
绘制在 Canvas
上,但与在普通 TextView 上设置的 Emojis 相比,它们显着 暗淡 ,如下所示:
知道我在这里错过了什么吗?
问题是您的表情符号字符超出了 0000 - FFFF 的范围 所以它不能表示为单个 unicode 字符。
如果您为表情符号正确编码 "unicode surrogate pairs" 可能是可能的。
有一个计算器可以确定正确的多字节 unicode 代理对 在:http://www.russellcottrell.com/greek/utilities/surrogatepaircalculator.htm
无论如何,我找到了一个 hack,我自己不太喜欢!在此,我创建一个 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();
}
}
如果有更好的解决办法请post
编辑
我发现 StaticLayout 是在 canvas 上绘制文本的更好选择,并且 没有 text/emoji 变暗的问题.
我修改后的代码(比之前少了行):
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();
}
}
这是结果,表情符号和 canvas 上绘图的其余部分一样亮: