【问题标题】:How to prevent EditText from breaking a line after punctuation如何防止EditText在标点符号后换行
【发布时间】:2011-05-26 06:17:35
【问题描述】:

默认情况下,如果行长于视图,Android EditText 将换行,如下所示:

Thisisalineanditisveryverylongs (end of view)
othisisanotherline

或者如果该行包含标点符号,如下所示:

Thisisalineanditsnotsolong;     (several characters from the end of view)
butthisisanotherline

作为我的工作要求,只有当行长于视图时,文本才需要换行,如下所示:

Thisisalineanditsnotsolong;andt (end of view)
hisisanotherline

一定有办法实现这一点,对吗?到目前为止,我还没有找到这样做的方法。

【问题讨论】:

    标签: android text line android-edittext punctuation


    【解决方案1】:

    TextView(和 EditText)打破文本的方式是通过内部对 BoringLayout 的私有函数调用。因此,最好的方法是子类化 EditText 并重写这些函数。但这不会是一项微不足道的任务。

    因此,在TextView class 中创建了不同的文本样式类。我们看的是DynamicLayout。在这个类中,我们到达类StaticLayout 的引用(在一个名为reflowed 的变量中)。在这个类的构造函数中你会发现文本换行算法:

    /*
    * From the Unicode Line Breaking Algorithm:
    * (at least approximately)
    *  
    * .,:; are class IS: breakpoints
    *      except when adjacent to digits
    * /    is class SY: a breakpoint
    *      except when followed by a digit.
    * -    is class HY: a breakpoint
    *      except when followed by a digit.
    *
    * Ideographs are class ID: breakpoints when adjacent,
    * except for NS (non-starters), which can be broken
    * after but not before.
    */
    
    if (c == ' ' || c == '\t' ||
    ((c == '.'  || c == ',' || c == ':' || c == ';') &&
    (j - 1 < here || !Character.isDigit(chs[j - 1 - start])) &&
    (j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
    ((c == '/' || c == '-') &&
    (j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
    (c >= FIRST_CJK && isIdeographic(c, true) &&
    j + 1 < next && isIdeographic(chs[j + 1 - start], false))) {
    okwidth = w;
    ok = j + 1;
    

    这里是所有包装的地方。因此,您需要对 StaticLayout、DynamicLayout、TextView 和最后的 EditText 进行子类化处理,我敢肯定,这将是一场噩梦 :( 我什至不确定所有流程是如何进行的。如果您愿意,请先查看 TextView并检查 getLinesCount 调用 - 这将是起点。

    【讨论】:

    • 非常有趣...因为我已经在我的工作中对 EditText 进行了子类化。您能否指出正确的方向,我应该重写哪些方法来完成这项工作?
    • 不知道有没有其他的办法,反正这么小的问题,这就是一个巨大的解决方案。如果找不到其他解决方案,我将对此进行调查。非常感谢。
    • 我遇到了类似的问题并提出了以下解决方案:groups.google.com/forum/?fromgroups=#!topic/android-discuss/… 我希望他们只是公开那段代码,而不是隐藏它。
    【解决方案2】:

    Android 中的这种换行算法真的很糟糕,它甚至在逻辑上都不正确——逗号不能是一行的最后一个字符。它只会产生不必要的换行符,从而导致极其奇怪的文本布局。

    【讨论】:

      【解决方案3】:

      您好,这是我先从另一个人那里得到的一种方法,然后进行一些更改,它确实对我有用,您可以尝试一下。

      //half ASCII transfer to full ASCII
      public static String ToSBC(String input) { 
          char[] c = input.toCharArray(); 
          for (int i = 0; i< c.length; i++) { 
          if (c[i] == 32) { 
          c[i] = (char) 12288; 
          continue; 
          } 
          if (c[i]<=47 && c[i]>32 ) 
          c[i] = (char) (c[i] + 65248); 
          } 
          return new String(c); 
          }
      }
      

      在这里。我把一些特殊字符从半角改成全角,比如“、”、“.”,效果还不错。你可以试试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-07
        相关资源
        最近更新 更多