天天看點

Android TextView 解決文字換行排版

如題 問題就不描述了直接幹貨(還可以優化 如果有哪位優化了 請記得貼一份,thks)

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.yaxp.common.utils.StringUtil;

public class AutoNewLinesTextView extends TextView {
	private int mMaxLines;
	private boolean mChecked = false;
	
	@Override
	protected void onTextChanged(CharSequence text, int start,int lengthBefore, int lengthAfter) {
		super.onTextChanged(text, start, lengthBefore, lengthAfter);
		if(text != null && lengthBefore != lengthAfter && text.toString().indexOf("\n") == -1)
			mChecked = true;
		else
			mChecked = false;
	}
	
	public AutoNewLinesTextView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public AutoNewLinesTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public AutoNewLinesTextView(Context context) {
		super(context);
	}

	
	protected void onDraw(Canvas canvas) {
		String txt = getText().toString().trim();
		if(StringUtil.isNotNull(txt)){
			Paint mPaint = getPaint();
			if(mPaint == null){
				mPaint = new Paint();
				mPaint.setTextSize(getTextScaleX());
			}
			if(mChecked){
				mChecked = false;
			    //文本自動換行
			    String texts = autoSplit(txt, mPaint, getWidth());
			    if(texts.indexOf("\n") > 0){
			    	setText(texts);
			    }
		    }
			super.onDraw(canvas);
		}
		
	}

	@Override
	public void setLines(int lines) {
		super.setLines(lines);
		this.mMaxLines = lines;
	}
	
	@Override
	public void setMaxLines(int maxlines) {
		super.setMaxLines(maxlines);
		this.mMaxLines = maxlines;
	}
	
	/**
	 * 自動分割文本
	 * @param content 需要分割的文本
	 * @param p  畫筆,用來根據字型測量文本的寬度
	 * @param width 最大的可顯示像素(一般為控件的寬度)
	 * @return 一個字元串數組,儲存每行的文本 最大行數2
	 */
	private String autoSplit(String content, Paint p, float width) {
		int length = content.length();
	    float textWidth = p.measureText(content);
	    if(textWidth <= width) {
	        return content;
	    }
	    int start = 0, end = 1, i = 0;
	    String[] lineTexts = new String[mMaxLines];
	    for (int j = 0; j < length; j++) {
	    	float lw = 0;
	    	if(end < length){
	    		lw = p.measureText(content.substring(end, end+1));
	    	}
	    	float iw = p.measureText(content, start, end);
//	    	if(end < length)
//	    		System.out.println(j + " lw=" + lw + " iw=" + iw +" (iw >= width - lw)" + (iw >= width - lw) +" e = "+ end +" " + content.substring(end, end+1));
	    	if(iw >= (width - lw)) { //文本寬度超出控件寬度時
	    		if(i == (mMaxLines -1)){
	        		end -=1;
	        		lineTexts[i++] = (String) content.subSequence(start, end) +"…";
	        		break;
	    		}else{
	    			lineTexts[i++] = (String) content.subSequence(start, end);
	    		}
	    		start = end;
		    }else if(j == (length -1) && i == (mMaxLines -1)){
		    	lineTexts[i++] = (String) content.subSequence(start, end);
		    }
		    end += 1;
		}
	    String text = "";
	    for (int j = 0; j < lineTexts.length; j++) {
	    	if(isNotNull(lineTexts[j])){
		    	if(j != 0)
		    		text += "\n";
		    	text += lineTexts[j];
	    	}
		}
	    return text;
	}
	
	/**
	 * 判斷是否為空 并且内容不能為null字元
	 * @param str
	 * @return
	 */
	public static boolean isNotNull(String str) {
		return str != null && !"".equals(str.trim()) && !"null".equals(str.trim());
	}
           

XML布局(注意 設定AutoNewLinesTextView   android:layout_width="match_parent" ) 

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/goods_list_item_h"
        android:layout_centerVertical="true"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/goods_cover_iv"
            android:layout_width="@dimen/goods_list_cover"
            android:layout_height="@dimen/goods_list_cover"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="@dimen/common_ten_dp"
            android:layout_marginRight="@dimen/common_ten_dp"
            android:contentDescription="@string/app_name"
            android:scaleType="fitXY"
            android:src="@drawable/default_cover" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
           	android:layout_marginTop="@dimen/common_ten_dp"
            android:orientation="vertical" >

            <com.yaxp.customer.widget.AutoNewLinesTextView
                android:id="@+id/goods_title_tv"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="@dimen/common_ten_dp"
                android:ellipsize="end"
                android:maxLines="2"
                android:textColor="@color/black"
                android:textSize="@dimen/def_text_size" />

            <TextView
                android:id="@+id/goods_price_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:textColor="@color/light_text"
                android:textSize="@dimen/low_text_size" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <TextView
                    android:id="@+id/goods_specification_tv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:singleLine="true"
                    android:textColor="@color/normal_text_gray"
                    android:textSize="@dimen/low_text_size" />

                <TextView
                    android:id="@+id/goods_orgin_tv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="@dimen/common_twenty_dp"
                    android:singleLine="true"
                    android:textColor="@color/normal_text_gray"
                    android:textSize="@dimen/low_text_size" />
            </LinearLayout>

            <TextView
                android:id="@+id/goods_sales_volume_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:textColor="@color/normal_light_text"
                android:textSize="@dimen/def_text_size" />
        </LinearLayout>
    </LinearLayout>