证明在Android的文字 [英] Justifying text in Android

查看:155
本文介绍了证明在Android的文字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要证明一些文字(RTL),这是从服务器字符串( S1 )。但的TextView 无法自圆其说的文字,所以我必须用一个的WebView ,现在我要创建一个HTML文件中 将显示 S1 。然后我存储在数据库中的HTML文件的地址,然后我显示HTML文件。我已经看到了这个问题的SO问过许多人建议使用第三方库,我已经尝试了所有的办法都无济于事(他们在90%的情况下工作,但没有完全可靠的)。

I need to justify some text (RTL), which is a string (S1) from the server. But a TextView can't justify text, so I have to use a WebView, now I have to create a HTML file in which will display S1. And then I store the address of that html file in the database and then I display that html file. I've seen this question asked before on SO and many have recommended to use a 3rd party library, I've tried all of those approaches to no avail (they work in 90% of scenarios but are no fully reliable).

我觉得这种做法似乎令人费解,我想知道是否有更好的方法吗?

I feel that this approach seems convoluted, I was wondering if there is a better approach?

推荐答案

我用下面的code表示非常人需要这个问题,我创建公式,支持每个显示答案。

I use the following code that answer with very people that need this subject and i create formula that support in every display.

    public class TextJustify {

final static String SYSTEM_NEWLINE = "\n";
final static float COMPLEXITY = 5.12f; // Reducing this will increase
                                        // efficiency but will decrease
                                        // effectiveness
final static Paint p = new Paint();

/* @author Mathew Kurian */

public static void run(final TextView tv, float origWidth, int paddingLeft, int paddingRight, int marginLeft, int marginRight) {


    origWidth-= paddingRight+marginRight+paddingLeft+marginLeft;
    String s = tv.getText().toString();
    p.setTypeface(tv.getTypeface());
    String[] splits = s.split(SYSTEM_NEWLINE);
    float width = origWidth - 5;
    for (int x = 0; x < splits.length; x++)
        if (p.measureText(splits[x]) > width) {
            splits[x] = wrap(splits[x], width, p);
            String[] microSplits = splits[x].split(SYSTEM_NEWLINE);
            for (int y = 0; y < microSplits.length - 1; y++)
                microSplits[y] = justify(removeLast(microSplits[y], " "),
                        width, p);
            StringBuilder smb_internal = new StringBuilder();
            for (int z = 0; z < microSplits.length; z++)
                smb_internal.append(microSplits[z]
                        + ((z + 1 < microSplits.length) ? SYSTEM_NEWLINE
                                : ""));
            splits[x] = smb_internal.toString();
        }
    final StringBuilder smb = new StringBuilder();
    for (String cleaned : splits)
        smb.append(cleaned + SYSTEM_NEWLINE);
    tv.setGravity(Gravity.RIGHT);
    tv.setText(smb);
}

private static String wrap(String s, float width, Paint p) {
    String[] str = s.split("\\s"); // regex
    StringBuilder smb = new StringBuilder(); // save memory
    smb.append(SYSTEM_NEWLINE);
    for (int x = 0; x < str.length; x++) {
        float length = p.measureText(str[x]);
        String[] pieces = smb.toString().split(SYSTEM_NEWLINE);
        try {
            if (p.measureText(pieces[pieces.length - 1]) + length > width)
                smb.append(SYSTEM_NEWLINE);
        } catch (Exception e) {
        }
        smb.append(str[x] + " ");
    }
    return smb.toString().replaceFirst(SYSTEM_NEWLINE, "");
}

private static String removeLast(String s, String g) {
    if (s.contains(g)) {
        int index = s.lastIndexOf(g);
        int indexEnd = index + g.length();
        if (index == 0)
            return s.substring(1);
        else if (index == s.length() - 1)
            return s.substring(0, index);
        else
            return s.substring(0, index) + s.substring(indexEnd);
    }
    return s;
}

private static String justifyOperation(String s, float width, Paint p) {
    float holder = (float) (COMPLEXITY * Math.random());
    while (s.contains(Float.toString(holder)))
        holder = (float) (COMPLEXITY * Math.random());
    String holder_string = Float.toString(holder);
    float lessThan = width;
    int timeOut = 100;
    int current = 0;
    while (p.measureText(s) < lessThan && current < timeOut) {
        s = s.replaceFirst(" ([^" + holder_string + "])", " "
                + holder_string + "$1");
        lessThan = p.measureText(holder_string) + lessThan
                - p.measureText(" ");
        current++;
    }
    String cleaned = s.replaceAll(holder_string, " ");
    return cleaned;
}

private static String justify(String s, float width, Paint p) {
    while (p.measureText(s) < width) {
        s = justifyOperation(s, width, p);
    }
    return s;
}
  }

和召开这次您每亩用以下code,我测试的波斯语和每一个显示器和设备正常工作。

and for calling this you mus use following code, I tested for Persian language and in every display and device worked fine.

     public static final int FinallwidthDp  = 320 ;
     public static final int widthJustify  = 223 ;

     DisplayMetrics metrics = new DisplayMetrics();
     getWindowManager().getDefaultDisplay().getMetrics(metrics);
     int widthPixels = metrics.widthPixels;

     float scaleFactor = metrics.density;
     float widthDp = widthPixels / scaleFactor;

     TextView tv = (TextView) findViewById(R.id.textView1);
     ViewGroup.MarginLayoutParams lp1 = (ViewGroup.MarginLayoutParams) tv.getLayoutParams();

     tv.setText(text);
     TextJustify.run(tv,widthDp / FinallwidthDp * widthJustify , tv.getPaddingLeft(),tv.getPaddingRight() , lp1.leftMargin, lp1.rightMargin);

这个算法测试各种设备和正常活动(不对话框)的罚款工作,包装含量宽度的TextView ,并与每一个填充工作,margin.if对你不好,你可以改变 widthJustify ,直到看起来对你很好,我希望这是有用的。 对于新更新请参见

this algorithm tested on various device and worked fine in normal activity (not dialog) and wrap-content width for TextView, and worked with every padding and margin.if not good for you, you can change widthJustify until look good to you, I hope this useful. for newly update see This

这篇关于证明在Android的文字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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