赞
踩
android textView 中英文混排导致的自动换行出现的混乱的解决方案。
- package com.zhaoshebei.ui.custom;
-
- import android.annotation.SuppressLint;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.os.Build;
- import android.text.TextPaint;
- import android.text.TextUtils;
- import android.util.AttributeSet;
- import android.view.ViewTreeObserver;
- import android.widget.TextView;
-
- import java.util.ArrayList;
-
- public class AutoTextView extends TextView {
- /**
- * 文本是否变化
- */
- boolean mIsDirty = false;
- AdaptableText mAdaptableText;
-
- public JustifyTextView(Context context) {
- super(context);
-
- requestLayoutFor();
- }
-
- public JustifyTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- requestLayoutFor();
- }
-
- public JustifyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
-
- requestLayoutFor();
- }
-
- private void requestLayoutFor(){
- getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- if (getWidth() > 0) {
- if (Build.VERSION.SDK_INT >= 16) {
- getViewTreeObserver().removeOnGlobalLayoutListener(this);
- } else {
- getViewTreeObserver().removeGlobalOnLayoutListener(this);
- }
-
- requestLayout();
- }
- }
- });
- }
-
- @Override
- protected void onTextChanged(CharSequence text, int start, int before, int after) {
- super.onTextChanged(text, start, before, after);
- mIsDirty = true;
- }
-
- @Override
- public int getLineCount() {
- AdaptableText helper = getAdaptableText();
- return null==helper?0:helper.getLineCount();
- }
-
- @Override
- public void setMaxLines(int maxLines) {
- super.setMaxLines(maxLines);
- mIsDirty = true;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int w = measureWidth(widthMeasureSpec);
- int h = measureHeight(heightMeasureSpec);
- setMeasuredDimension(w, h);
- }
-
- private int measureWidth(int measureSpec) {
- int result = 0;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
-
- if (specMode == MeasureSpec.EXACTLY) {
- result = specSize;
- } else {
- String text = getText().toString();
- result = (int) getPaint().measureText(text) + getPaddingLeft()
- + getPaddingRight();
- if (specMode == MeasureSpec.AT_MOST) {
- result = Math.min(result, specSize);
- }
- }
-
- return result;
- }
-
- @SuppressLint("NewApi")
- private int measureHeight(int measureSpec) {
- int result = 0;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
-
- if (specMode == MeasureSpec.EXACTLY) {
- result = specSize;
- } else {
- result = 0;
- String text = getText().toString();
- if (!TextUtils.isEmpty(text)) {
- int lineCount = getLineCount();
- int maxLines = getMaxLines();
- lineCount = Math.min(maxLines, lineCount);
- int lineHeight = getLineHeight();
- result = lineCount * lineHeight;
- }
- }
-
- return result;
- }
-
- @Override
- @SuppressLint("NewApi")
- protected void onDraw(Canvas canvas) {
- getAdaptableText();
- if (mIsDirty) {
- mIsDirty = false;
- String text = getText().toString();
- int maxLines = getMaxLines();
- if (!mAdaptableText.getText().equals(text))
- mAdaptableText.setText(text);
- if (mAdaptableText.getMaxLines() != maxLines)
- mAdaptableText.setMaxLines(maxLines);
- }
- mAdaptableText.draw(canvas);
- }
-
- @SuppressLint("NewApi")
- private AdaptableText getAdaptableText() {
- if (mAdaptableText == null) {
- int measuredWidth = getMeasuredWidth();
- if (measuredWidth <= 0){
- return null;
- }
-
- TextPaint paint = getPaint();
- paint.setColor(getCurrentTextColor());
- paint.drawableState = getDrawableState();
-
- int paddingLeft = getPaddingLeft();
- int paddingRight = getPaddingRight();
- int lineHeight = getLineHeight();
-
- String text = getText().toString();
- mAdaptableText = new AdaptableText(text, paint, measuredWidth - paddingLeft - paddingRight, lineHeight);
- mAdaptableText.setMaxLines(getMaxLines());
- }
- return mAdaptableText;
- }
-
- private class AdaptableText {
- /**
- * 文本宽高
- */
- int mLineWidth, mLineHeight;
- /**
- * 最大行数
- */
- int mMaxLines;
- private TextPaint mPaint;
- private String mText;
- /**
- * 存储分割后的每行
- */
- ArrayList<String> strs = new ArrayList<String>();
-
- public AdaptableText(String text, TextPaint paint, int lineWidth, int lineHeight) {
- mLineHeight = lineHeight;
- mLineWidth = lineWidth;
- mPaint = paint;
- mText = text;
- parseText();
- }
-
- /**
- * 根据控件宽度,计算得出每行的字符串
- */
- private void parseText() {
- if (mLineWidth > 0 && mLineHeight > 0) {
- strs.clear();
- int start = 0;//行起始Index
- int curLineWidth = 0;//当前行宽
- for (int i = 0; i < mText.length(); i++) {
- char ch = mText.charAt(i);//获取当前字符
- float[] widths = new float[1];
- String srt = String.valueOf(ch);
- mPaint.getTextWidths(srt, widths);//获取这个字符的宽度
- if (ch == '\n') {//如果是换行符,则当独一行
- strs.add(mText.substring(start, i));
- start = i + 1;
- curLineWidth = 0;
- } else {
- curLineWidth += (int) (Math.ceil(widths[0]));//计算当前宽度
- if (curLineWidth > mLineWidth) {//直到当前行宽度大于控件宽度,截取为一行
- strs.add(mText.substring(start, i));
- start = i;
- i--;
- curLineWidth = 0;
- } else {
- if (i == (mText.length() - 1)) {//剩余的单独一行
- String s = mText.substring(start, mText.length());
- if (!TextUtils.isEmpty(s)) {
- strs.add(s);
- }
- }
- }
- }
- }
- }
- }
-
- public void draw(Canvas canvas) {
- int lines = mMaxLines > 0 && mMaxLines <= strs.size() ? mMaxLines : strs.size();
- for (int i = 0; i < lines; i++) {
- String text = strs.get(i);
- //如果是最大行的最后一行但不是真实的最后一行则自动添加省略号
- if (i == lines - 1 && i < strs.size() - 1)
- text = text.substring(0, text.length() - 3) + "...";
- canvas.drawText(text, getPaddingLeft(), getPaddingTop() + mPaint.getTextSize() + mLineHeight * i, mPaint);
- }
- }
-
- public void setText(String text) {
- mText = text;
- parseText();
- }
-
- public String getText() {
- return mText;
- }
-
- public void setMaxLines(int maxLines) {
- mMaxLines = maxLines;
- }
-
- public int getMaxLines() {
- return mMaxLines;
- }
-
- public int getLineCount() {
- return strs.size();
- }
-
- public int getLineEnd(int line) {
- int size = 0;
- for (int i = 0; i <= line; i++) {
- size += strs.get(i).length();
- }
- return size;
- }
- }
- }


Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。