如何使Android的传统蒙古文的ListView [英] How to make a traditional Mongolian script ListView in Android

查看:550
本文介绍了如何使Android的传统蒙古文的ListView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你如何让垂直蒙古文水平滚动的ListView在Android应用?

How do you make a horizontally scrolling ListView for vertical Mongolian script in Android apps?

Android有许多世界上的语言,甚至RTL语言,如阿拉伯语和希伯来语的相当不错的支持。然而,在支持没有内置像蒙古族传统顶部至底部的语言(这是仍然非常活跃在内蒙古,而不是与西里尔蒙古混淆)。下图显示了添加了清晰度英文文本方向。

Android has fairly good support for many of the world's languages, even RTL languages like Arabic and Hebrew. However, there is no built in support for top-to-bottom languages like traditional Mongolian (which is still very much alive in Inner Mongolia and not to be confused with Cyrillic Mongolian). The following graphic shows the text direction with English added for clarity.

由于此功能没有内置的Andr​​oid,它使应用开发非常困难的,几乎每一个方面。这是横向列表视图,这是不支持出的Andr​​oid盒子expecially如此。还有一个非常非常小的信息可在网上。有许多的应用程序开发人员为蒙古族传统,但无论是出于商业原因或其他方式,他们似乎不是让自己的code开源。

Since this functionality is not built into Android, it makes almost every single aspect of app development extremely difficult. This is expecially true with horizontal ListViews, which are not supported out of the box in Android. There is also very, very little information available online. There are a number of app developers for traditional Mongolian, but whether it is for commercial reasons or otherwise, they do not seem to make their code open source.

由于这些困难,我想提出的一系列问题计算器,可以作为一个集中的地方,收集了解答相关的一些蒙古族传统应用程序开发更困难的规划问题。即使你是不是在蒙识字,你的​​帮助审查code,提出意见和问题,给予解答甚至高达投票权的问题将是AP preciated。

Because of these difficulties I would like to make a series of StackOverflow questions that can serve as a central place to collect answers for some of the more difficult programming problems related to traditional Mongolian app development. Even if you are not literate in Mongolian, your help reviewing the code, making comments and questions, giving answers or even up-voting the question would be appreciated.

一个蒙古族的ListView需要有以下要求:

A Mongolian ListView needs to have the following requirements:


  • 水平滚动由左到右

  • 触摸事件的工作方式相同与正常的ListView

  • 自定义布局支持一样在正常的ListView

还需要支持的一切,一<一href=\"http://stackoverflow.com/questions/29739720/how-to-make-a-traditional-mongolian-script-textview-in-android\">Mongolian TextView的将支持:

Also needs to support everything that a Mongolian TextView would support:


  • 支持传统的蒙古字体

  • 显示文本垂直从顶部到底部

  • 换行去从左至右。

  • 发生在一个空间换行(同英文)

下图显示了基本的功能,蒙古的ListView应该有:

The image below shows the basic functionality a Mongolian ListView should have:

我的回答是下面的,但我欢迎解决这一问题的其他途径。

My answer is below, but I welcome other ways of solving this problem.

iOS的:

  • How do you make a vertical text UILabel and UITextView for iOS in Swift?

推荐答案

这是很不幸的是,横向列表视图不是由Android的API提供。有许多的StackOverflow Q&放大器;作为该说说该怎么办他们,虽然。这里有几个样本:

It is quite unfortunate that horizontal ListViews are not provided by the Android API. There are a number of StackOverflow Q&As that talk about how to do them, though. Here are a couple samples:

  • How can I make a horizontal ListView in Android?
  • Horizontal ListView in Android?

但是当我真正试图执行这些建议以及蒙古纳入垂直文本,我有一个可怕的时间。某处在我的搜索,我发现一个稍微不同的答案。这是是旋转的整个布局的一类。它这样做是通过扩展的ViewGroup。以这种方式的任何(包括一个ListView)可以被放置在的ViewGroup和它被转动。所有触摸事件的工作了。

But when I actually tried to implement these suggestions as well as incorporate Mongolian vertical text, I was having a terrible time. Somewhere in my search I found a slightly different answer. It was a class that rotated an entire layout. It did so by extending ViewGroup. In this way anything (including a ListView) can be put in the ViewGroup and it gets rotated. All the touch events work, too.

我在我对蒙古TextViews 的答案,这是不够的,只需旋转蒙古文字。这将是不够的,如果每个ListView项(或其他的ViewGroup文本元素),只有一个单一的线,但旋转的多条线路进行换行走偏方向。然而,水平镜像布局和也使用垂直镜像字体可以克服这个问题,如下图中所示。

As I explained in my answer about Mongolian TextViews, it is not enough to simply rotate Mongolian text. That would be enough if every ListView item (or other text element in the ViewGroup) was only a single line, but rotating multiple lines make the line wrap go the wrong direction. However, mirroring the layout horizontally and also using a vertically mirrored font can overcome this, as is shown in the following image.

我适应旋转的ViewGroup code也做了水平镜像。

I adapted the rotated ViewGroup code to also do the horizontal mirroring.

public class MongolViewGroup extends ViewGroup {

    private int angle = 90;
    private final Matrix rotateMatrix = new Matrix();
    private final Rect viewRectRotated = new Rect();
    private final RectF tempRectF1 = new RectF();
    private final RectF tempRectF2 = new RectF();
    private final float[] viewTouchPoint = new float[2];
    private final float[] childTouchPoint = new float[2];
    private boolean angleChanged = true;

    public MongolViewGroup(Context context) {
        this(context, null);
    }

    public MongolViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        setWillNotDraw(false);
    }

    public View getView() {
        return getChildAt(0);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final View view = getView();
        if (view != null) {
            measureChild(view, heightMeasureSpec, widthMeasureSpec);
            setMeasuredDimension(resolveSize(view.getMeasuredHeight(), widthMeasureSpec),
                    resolveSize(view.getMeasuredWidth(), heightMeasureSpec));
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (angleChanged) {
            final RectF layoutRect = tempRectF1;
            final RectF layoutRectRotated = tempRectF2;
            layoutRect.set(0, 0, right - left, bottom - top);
            rotateMatrix.setRotate(angle, layoutRect.centerX(), layoutRect.centerY());
            rotateMatrix.postScale(-1, 1);
            rotateMatrix.mapRect(layoutRectRotated, layoutRect);
            layoutRectRotated.round(viewRectRotated);
            angleChanged = false;
        }
        final View view = getView();
        if (view != null) {
            view.layout(viewRectRotated.left, viewRectRotated.top, viewRectRotated.right,
                    viewRectRotated.bottom);
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {

        canvas.save();
        canvas.rotate(-angle, getWidth() / 2f, getHeight() / 2f);
        canvas.scale(-1, 1);
        super.dispatchDraw(canvas);
        canvas.restore();
    }

    @Override
    public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
        invalidate();
        return super.invalidateChildInParent(location, dirty);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        viewTouchPoint[0] = event.getX();
        viewTouchPoint[1] = event.getY();
        rotateMatrix.mapPoints(childTouchPoint, viewTouchPoint);
        event.setLocation(childTouchPoint[0], childTouchPoint[1]);
        boolean result = super.dispatchTouchEvent(event);
        event.setLocation(viewTouchPoint[0], viewTouchPoint[1]);
        return result;
    }


}

蒙古垂直镜像字体还需要在其他地方设置,虽然。我觉得最容易使自定义TextView的做到这一点:

The Mongolian vertically mirrored font still needs to be set somewhere else, though. I find it easiest to make a custom TextView to do it:

public class MongolNonRotatedTextView extends TextView {

    // This class does not rotate the textview. It only displays the Mongol font.
    // For use with MongolLayout, which does all the rotation and mirroring.

    // Constructors
    public MongolNonRotatedTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public MongolNonRotatedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MongolNonRotatedTextView(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/MongolMirroredFont.ttf");
         setTypeface(tf);

    }
}

然后自定义ListView项XML布局可以是这个样子:

Then the custom ListView item xml layout can look something like this:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rlListItem"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

        <com.example.MongolNonRotatedTextView
            android:id="@+id/tvListViewText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"/>

</RelativeLayout>

已知问题:


  • 如果您在图像仔细看下面你可以看到周围的文字淡淡的水平和垂直线条。虽然这个形象来自其他开发者的应用程序,我得到我的应用程序相同的工件时,我使用的是旋转的ViewGroup(而不是当我使用的旋转的TextView )。如果有谁知道在哪里,这些都是从哪里来的,请给我留下了评论!

  • Known issues:

    • If you look carefully at the image below you can see faint horizontal and vertical lines around the text. Although this image comes from another developer's app, I am getting the same artifacts in my app when I use the rotated ViewGroup (but not when I use the rotated TextView). If anyone knows where these are coming from, please leave me a comment!

      • 这个方案不涉及呈现统一code文本。要么你需要使用非统一code文本(灰心),或者你需要在你的应用程序渲染引擎。 (Android不支持OpenType字体smartfont在这个时候进行渲染。希望这将改变未来。的iOS,相比之下不支持复杂的文本渲染字体。)请参阅 UNI端口code蒙渲染引擎,例如此链接

      • This solution does not deal with rendering the Unicode text. Either you need to use non-Unicode text (discouraged) or you need to include a rendering engine in your app. (Android does not support OpenType smartfont rendering at this time. Hopefully this will change in the future. iOS, by comparison does support complex text rendering fonts.) See this link for a Unicode Mongolian rendering engine example.

      这篇关于如何使Android的传统蒙古文的ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆