如何find每行android字符数的字符?

所以我有一个在android中的TextView具有整个屏幕的长度和倾angular5的宽度。我怎样才能计算出适合屏幕上单行的字符数? 换句话说,我想要得到一个textview的列的数量?

我认为手动计算取决于文本大小和宽度,但是1)不知道相关性和2)由于以dip为单位的填充,不同的屏幕将使用不同数量的实际像素来填充。

总的问题:我想用这个来解决:如果给定一个string,我怎么能手动编辑string,使得当textviewstring打印字符,我会知道什么时候开始一个单词不适合一个在下一行。 注意:我知道textview会自动将不适合放到下一行的单词,但是,由于我正在按字符打印字符,如键入animation,textview不知道该单词将不适合,直到它打印出这个词的字符溢出。

到处寻找这个…

谢谢!

新增解决scheme

可能的解决scheme

public String measure2 (TextView t, String s) { String u = ""; int start = 0; int end = 1; int space = 0; boolean ellipsized = false; float fwidth = t.getMeasuredWidth(); for(;;) { //t.setText(s.substring(start, end)); float twidth = t.getPaint().measureText(s.substring(start, end)); if (twidth < fwidth){ if (end < s.length()) end++; else { if (!ellipsized) return s; return u + s.subSequence(start, end); } } else { ellipsized = true; space = (u + s.substring(start, end)).lastIndexOf(" "); if (space == -1) space = end - 1; u += s.subSequence(start, space) + "\n"; start = space + 1; end = start + 1; } } } 

解决scheme2,但有时仍使用solution1:

 public String measure3 (TextView t, String s) { List<String> wlist = Arrays.asList(s.split(" ")); if (wlist.size() == 1) return measure2(t, s); String u = ""; int end = 1; float fwidth = t.getMeasuredWidth(); for(;;) { //t.setText(s.substring(start, end)); if (wlist.isEmpty()) return u; String temp = listStr(wlist, end); float twidth = t.getPaint().measureText(temp); if (twidth < fwidth){ if (end < wlist.size()) end++; else { return u + temp; } } else { temp = listStr(wlist, end-1); if (end == 1) temp = measure2(t, temp); if (wlist.isEmpty()) return u + temp; else u = u + temp + "\n"; wlist = wlist.subList(end - 1, wlist.size()); end = 1; } } } public String listStr (List<String> arr, int end) { String s = ""; for (String e : arr.subList(0, end) ){ s = s + e + " "; } return s.trim(); } 

我用上面的代码生成一个原始strings,一个stringu将被打印。 但是,我认为这种方法效率很低。 有另一种方法或更好的algorithm? 注意:我修正了measure3中的一些错误,但却懒得修改

Solutions Collecting From Web of "如何find每行android字符数的字符?"

尝试这个:

 private boolean isTooLarge (TextView text, String newText) { float textWidth = text.getPaint().measureText(newText); return (textWidth >= text.getMeasuredWidth ()); } 

由于字符的可变宽度,检测字符的适合度将是不可能的。 上面的函数将testing一个特定的string是否适合在TextView中。 newText的内容应该是特定行中的所有字符。 如果为true,则开始新行(并使用新string作为parameter passing)。


回答评论:

  1. 因为该应用程序可以运行在许多系统正是为什么你需要测量它。
  2. 这是解决你的“整体问题”的一种方法。 使用str.size()> numCol vs isTooLarge有什么区别? 你将需要实现你的animation(提示#1:插入一个换行符)
  3. 正如我之前所说,当你开始一个新的行,你开始一个新的string(提示#2:如果你扩展TextView,你可以在覆盖setText实现所有这一切)。 (提示#3:跟踪用static int lines;行创build的static int lines;并使用newString.split("\\r?\\n")[lines-1]来检查长度)。

你可以得到Textview的总行,并通过下面的代码得到每个字符的string。然后你可以设置样式到每一行,无论你想要的。

我设置第一行粗体。

 private void setLayoutListner( final TextView textView ) { textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { textView.getViewTreeObserver().removeGlobalOnLayoutListener(this); final Layout layout = textView.getLayout(); // Loop over all the lines and do whatever you need with // the width of the line for (int i = 0; i < layout.getLineCount(); i++) { int end = layout.getLineEnd(0); SpannableString content = new SpannableString( textView.getText().toString() ); content.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, end, 0); content.setSpan(new StyleSpan(android.graphics.Typeface.NORMAL), end, content.length(), 0); textView.setText( content ); } } }); 

}

试试这种方法。你可以用这种方式应用多种风格。