android text 中英文混排 換行的問題

心鑫發表於2013-09-29
package com.example.mytextview;

import java.util.ArrayList;
import java.util.Arrays;

import android.R.integer;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.TextView;

public class MyTextView3 extends TextView {
	private Paint paint1 = new Paint();
	private float textSize;

	public MyTextView3(Context context, AttributeSet attrs) {
		super(context, attrs);
		textSize = super.getTextSize();
		paint1.setTextSize(textSize);
		int textColor = super.getTextColors().getColorForState(
				getDrawableState(), 0);
		paint1.setColor(textColor);
		paint1.setAntiAlias(true);
	}
	/**
	 *  返回每行能顯示字串的集合
	 * @param content 所有字元
	 * @param p  用於測量每個字元的寬度
	 * @param width   文字框有效的寬度 去掉左右邊距
	 * @return
	 */
	
	private ArrayList<String> autoSplit(String content, Paint p, float width) {
		ArrayList<String> as = new ArrayList<String>();
		//字元口中 的個數
		int length = content.length();
		float textWidth = p.measureText(content);
		if (textWidth < width) {
			as.add(content);
			return as;
		}

		int start = 0, end = 1;
		while (start < length) {
			// 一定個數的文字寬度小於控制元件寬度
			// 且 個數加1個(防止越界)文字寬度大於控制元件寬度時
			if (p.measureText(content, start, (end + 1) > length ? length
					: (end + 1)) >= width
					&& p.measureText(content, start, end) <= width) {

				as.add((String) content.subSequence(start, end));
				start = end;
			}
			// 不足一行的文字 最後一行處理
			if (end == length) {
				as.add((String) content.subSequence(start, end));
				break;
			}
			// 對換行符的識別
			if (content.charAt(end) == '\n') {
				as.add((String) content.subSequence(start, end));
				// end +1 去掉'\n'
				start = end + 1;
			}
			end += 1;
		}
		return as;
	}

	protected void onDraw(Canvas canvas) {

		String txt = super.getText().toString();
		FontMetrics fm = paint1.getFontMetrics();
		float baseline = fm.descent - fm.ascent;
		float x = getPaddingLeft();
		float y = baseline; // 由於系統基於字型的底部來繪製文字,所有需要加上字型的高度。
		// 一行的內容長度
		float lineLenth = getWidth() - getPaddingLeft() - getPaddingRight();
		ArrayList<String> texts = autoSplit(txt, paint1, lineLenth);

		for (String string : texts) {
			System.out.println("string-->" + string);
		}

		for (int i=0;i<texts.size();i++) {
			String text=texts.get(i);
			if (text == null) {
				continue;
			}
			// 左對齊
			if (getGravity() == getFormatGravity(Gravity.CENTER)) {
				float textLength = paint1.measureText(text, 0, text.length());
				canvas.drawText(text, x+(lineLenth - textLength)/2, y, paint1);
				
			}
			// 右對齊
			else if (getGravity() == getFormatGravity(Gravity.RIGHT)) {
				float textLength = paint1.measureText(text, 0, text.length());
				canvas.drawText(text, x+lineLenth - textLength, y, paint1);
			}
			//居中對齊
			else{
				canvas.drawText(text, x, y, paint1); // 座標以控制元件左上角為原點
			}
			//最後一行不新增間距
			if(i!=texts.size()-1){
			y += baseline + fm.leading;}  // 新增字型行間距
		}
	}
	private int getFormatGravity(int gravity){
//		if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
//            gravity |= Gravity.START;
//        }
        if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
            gravity |= Gravity.TOP;
        }
        return gravity;
	}
}
 <com.example.mytextview.MyTextView3
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="46dp"
            android:layout_marginRight="20dp"
            android:background="@android:color/darker_gray"
            android:paddingLeft="20dp"
            android:paddingRight="40dp"
            android:gravity="left"
            android:id="@+id/tv1"
            android:textColor="#FF0000"
            android:text="@string/text"
            android:textSize="12sp" />


TextView mtv = (TextView) findViewById(R.id.view);
mtv.setText(text);

MyTextView3繼承textView 所以可直接用TextView ,直接替換就行

目前與自帶TextView相比 ,實現的功能還不全





相關文章