当前位置:   article > 正文

textView 中英文混排导致的自动换行出现的混乱的解决方案_android textview 显示英文不友好

android textview 显示英文不友好
android textView 中英文混排导致的自动换行出现的混乱的解决方案。
  1. package com.zhaoshebei.ui.custom;
  2. import android.annotation.SuppressLint;
  3. import android.content.Context;
  4. import android.graphics.Canvas;
  5. import android.os.Build;
  6. import android.text.TextPaint;
  7. import android.text.TextUtils;
  8. import android.util.AttributeSet;
  9. import android.view.ViewTreeObserver;
  10. import android.widget.TextView;
  11. import java.util.ArrayList;
  12. public class AutoTextView extends TextView {
  13. /**
  14. * 文本是否变化
  15. */
  16. boolean mIsDirty = false;
  17. AdaptableText mAdaptableText;
  18. public JustifyTextView(Context context) {
  19. super(context);
  20. requestLayoutFor();
  21. }
  22. public JustifyTextView(Context context, AttributeSet attrs) {
  23. super(context, attrs);
  24. requestLayoutFor();
  25. }
  26. public JustifyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
  27. super(context, attrs, defStyleAttr);
  28. requestLayoutFor();
  29. }
  30. private void requestLayoutFor(){
  31. getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
  32. @Override
  33. public void onGlobalLayout() {
  34. if (getWidth() > 0) {
  35. if (Build.VERSION.SDK_INT >= 16) {
  36. getViewTreeObserver().removeOnGlobalLayoutListener(this);
  37. } else {
  38. getViewTreeObserver().removeGlobalOnLayoutListener(this);
  39. }
  40. requestLayout();
  41. }
  42. }
  43. });
  44. }
  45. @Override
  46. protected void onTextChanged(CharSequence text, int start, int before, int after) {
  47. super.onTextChanged(text, start, before, after);
  48. mIsDirty = true;
  49. }
  50. @Override
  51. public int getLineCount() {
  52. AdaptableText helper = getAdaptableText();
  53. return null==helper?0:helper.getLineCount();
  54. }
  55. @Override
  56. public void setMaxLines(int maxLines) {
  57. super.setMaxLines(maxLines);
  58. mIsDirty = true;
  59. }
  60. @Override
  61. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  62. //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  63. int w = measureWidth(widthMeasureSpec);
  64. int h = measureHeight(heightMeasureSpec);
  65. setMeasuredDimension(w, h);
  66. }
  67. private int measureWidth(int measureSpec) {
  68. int result = 0;
  69. int specMode = MeasureSpec.getMode(measureSpec);
  70. int specSize = MeasureSpec.getSize(measureSpec);
  71. if (specMode == MeasureSpec.EXACTLY) {
  72. result = specSize;
  73. } else {
  74. String text = getText().toString();
  75. result = (int) getPaint().measureText(text) + getPaddingLeft()
  76. + getPaddingRight();
  77. if (specMode == MeasureSpec.AT_MOST) {
  78. result = Math.min(result, specSize);
  79. }
  80. }
  81. return result;
  82. }
  83. @SuppressLint("NewApi")
  84. private int measureHeight(int measureSpec) {
  85. int result = 0;
  86. int specMode = MeasureSpec.getMode(measureSpec);
  87. int specSize = MeasureSpec.getSize(measureSpec);
  88. if (specMode == MeasureSpec.EXACTLY) {
  89. result = specSize;
  90. } else {
  91. result = 0;
  92. String text = getText().toString();
  93. if (!TextUtils.isEmpty(text)) {
  94. int lineCount = getLineCount();
  95. int maxLines = getMaxLines();
  96. lineCount = Math.min(maxLines, lineCount);
  97. int lineHeight = getLineHeight();
  98. result = lineCount * lineHeight;
  99. }
  100. }
  101. return result;
  102. }
  103. @Override
  104. @SuppressLint("NewApi")
  105. protected void onDraw(Canvas canvas) {
  106. getAdaptableText();
  107. if (mIsDirty) {
  108. mIsDirty = false;
  109. String text = getText().toString();
  110. int maxLines = getMaxLines();
  111. if (!mAdaptableText.getText().equals(text))
  112. mAdaptableText.setText(text);
  113. if (mAdaptableText.getMaxLines() != maxLines)
  114. mAdaptableText.setMaxLines(maxLines);
  115. }
  116. mAdaptableText.draw(canvas);
  117. }
  118. @SuppressLint("NewApi")
  119. private AdaptableText getAdaptableText() {
  120. if (mAdaptableText == null) {
  121. int measuredWidth = getMeasuredWidth();
  122. if (measuredWidth <= 0){
  123. return null;
  124. }
  125. TextPaint paint = getPaint();
  126. paint.setColor(getCurrentTextColor());
  127. paint.drawableState = getDrawableState();
  128. int paddingLeft = getPaddingLeft();
  129. int paddingRight = getPaddingRight();
  130. int lineHeight = getLineHeight();
  131. String text = getText().toString();
  132. mAdaptableText = new AdaptableText(text, paint, measuredWidth - paddingLeft - paddingRight, lineHeight);
  133. mAdaptableText.setMaxLines(getMaxLines());
  134. }
  135. return mAdaptableText;
  136. }
  137. private class AdaptableText {
  138. /**
  139. * 文本宽高
  140. */
  141. int mLineWidth, mLineHeight;
  142. /**
  143. * 最大行数
  144. */
  145. int mMaxLines;
  146. private TextPaint mPaint;
  147. private String mText;
  148. /**
  149. * 存储分割后的每行
  150. */
  151. ArrayList<String> strs = new ArrayList<String>();
  152. public AdaptableText(String text, TextPaint paint, int lineWidth, int lineHeight) {
  153. mLineHeight = lineHeight;
  154. mLineWidth = lineWidth;
  155. mPaint = paint;
  156. mText = text;
  157. parseText();
  158. }
  159. /**
  160. * 根据控件宽度,计算得出每行的字符串
  161. */
  162. private void parseText() {
  163. if (mLineWidth > 0 && mLineHeight > 0) {
  164. strs.clear();
  165. int start = 0;//行起始Index
  166. int curLineWidth = 0;//当前行宽
  167. for (int i = 0; i < mText.length(); i++) {
  168. char ch = mText.charAt(i);//获取当前字符
  169. float[] widths = new float[1];
  170. String srt = String.valueOf(ch);
  171. mPaint.getTextWidths(srt, widths);//获取这个字符的宽度
  172. if (ch == '\n') {//如果是换行符,则当独一行
  173. strs.add(mText.substring(start, i));
  174. start = i + 1;
  175. curLineWidth = 0;
  176. } else {
  177. curLineWidth += (int) (Math.ceil(widths[0]));//计算当前宽度
  178. if (curLineWidth > mLineWidth) {//直到当前行宽度大于控件宽度,截取为一行
  179. strs.add(mText.substring(start, i));
  180. start = i;
  181. i--;
  182. curLineWidth = 0;
  183. } else {
  184. if (i == (mText.length() - 1)) {//剩余的单独一行
  185. String s = mText.substring(start, mText.length());
  186. if (!TextUtils.isEmpty(s)) {
  187. strs.add(s);
  188. }
  189. }
  190. }
  191. }
  192. }
  193. }
  194. }
  195. public void draw(Canvas canvas) {
  196. int lines = mMaxLines > 0 && mMaxLines <= strs.size() ? mMaxLines : strs.size();
  197. for (int i = 0; i < lines; i++) {
  198. String text = strs.get(i);
  199. //如果是最大行的最后一行但不是真实的最后一行则自动添加省略号
  200. if (i == lines - 1 && i < strs.size() - 1)
  201. text = text.substring(0, text.length() - 3) + "...";
  202. canvas.drawText(text, getPaddingLeft(), getPaddingTop() + mPaint.getTextSize() + mLineHeight * i, mPaint);
  203. }
  204. }
  205. public void setText(String text) {
  206. mText = text;
  207. parseText();
  208. }
  209. public String getText() {
  210. return mText;
  211. }
  212. public void setMaxLines(int maxLines) {
  213. mMaxLines = maxLines;
  214. }
  215. public int getMaxLines() {
  216. return mMaxLines;
  217. }
  218. public int getLineCount() {
  219. return strs.size();
  220. }
  221. public int getLineEnd(int line) {
  222. int size = 0;
  223. for (int i = 0; i <= line; i++) {
  224. size += strs.get(i).length();
  225. }
  226. return size;
  227. }
  228. }
  229. }

 

                
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/242957
推荐阅读
相关标签
  

闽ICP备14008679号