如何为Android应用程序制作垂直的蒙古文脚本TextViews(用左至右的换行符)?
背景
Android对世界上许多语言提供了很好的支持,甚至包括阿拉伯文和希伯来文这样的RTL语言。但是,没有内置支持从上到下的语言,例如traditional Mongolian(在内蒙古仍然活跃,不要与Cyrillic Mongolian混淆)。下图显示了文本方向,为清楚起见添加了英语。
由于此功能不是Android内置的,因此几乎使应用程序开发的每个方面都极为困难。在线上也有非常少的信息。 (few related SO questions之一甚至没有一个很好的答案。)有很多使用传统蒙古语的应用程序开发人员,但是无论出于商业原因还是其他原因,他们似乎都没有将其代码开源。
由于这些困难,我想提出一系列StackOverflow问题,这些问题可以作为中心位置来收集与传统蒙古语应用程序开发相关的一些较困难的编程问题的答案。即使您不懂蒙古语,也可以帮助您检查代码,提出意见和问题,给出答案甚至投票赞成该问题。
蒙古语垂直TextView
蒙古文TextView需要具有以下要求:
(因为将来可以设置TypeFace,所以不是必须要支持TextView的蒙古字体,但是当使用许多TextView时,这是一种方便。)
我的答案在下面,但我欢迎其他解决此问题的方法。
本系列中的其他相关问题:
iOS:
最佳答案
更新
我最终从零开始开发了一个垂直脚本 MongolTextView
。它可以作为 mongol-library
的一部分使用。
以下解决方案的问题在于,镜像字体中未包括的任何字符(特别是中文)都将向后显示。
旧答案
蒙古字体全部以字形的方向与英语相同的方向制作,即从左到右。这样就可以将蒙古语单词添加到英语,中文或西里尔文字中(唯一的问题是单词正在“放下”而不是“站起来”)。
顺时针旋转TextView 90度将使其垂直,但是换行方向错误(旋转后从右向左而不是从左向右)。可以通过水平翻转或镜像TextView来解决换行方向问题,但是随后所有的字形都被镜像了。可以通过从垂直镜像的字体开始解决最后的问题(可以通过使用开源软件FontForge编辑现有字体来实现)。下图说明了该过程:
可以通过扩展TextView并覆盖onDraw()
和onMeasure()
方法来完成旋转和翻转:
public class MongolTextView extends TextView {
private TextPaint textPaint;
// Constructors
public MongolTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public MongolTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MongolTextView(Context context) {
super(context);
init();
}
// This class requires the mirrored Mongolian font to be in the assets/fonts folder
private void init() {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
"fonts/MongolFontMirrored.ttf");
setTypeface(tf);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// swap the height and width
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
@Override
protected void onDraw(Canvas canvas) {
textPaint = getPaint();
textPaint.setColor(getCurrentTextColor());
textPaint.drawableState = getDrawableState();
canvas.save();
// flip and rotate the canvas
canvas.translate(getWidth(), 0);
canvas.rotate(90);
canvas.translate(0, getWidth());
canvas.scale(1, -1);
canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());
getLayout().draw(canvas);
canvas.restore();
}
}
在您的xml布局中,使用扩展的TextView的全名:<com.example.MongolTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/title_string" />
已知的问题:如果您牢记旋转,
layout_margin
和layout_gravity
可以正常工作,但是padding
和gravity
的行为很奇怪。因此,似乎最好使用wrap_content
并避免使用padding
和gravity
。通过将MongolTextView放在FrameLayout中并使用layout_margin
和layout_gravity
可以实现相同的效果。