[Android]TextView實現分散對齊(兩端對齊)

TextView是個特別基礎的Android控件,隻要有文本基本就少不瞭它。但是最近在項目開發的過程中我發現TextView存在很多局限性,其中最令我頭疼的就是TextView文本排版方面的問題。我們都知道在word中文字對齊方式有靠左、靠右、居中、分散對齊等,但是TextView中就偏偏沒有分散對齊這個屬性設置。這就導致瞭TextView中一段文字會出現右邊參差不齊的問題,中文由於每個字等寬看起來還不是特別糟糕,英文看起來就比較過分瞭。

為瞭解決這個問題,一個常用的解決方法是在TextView內使用html來實現文本樣式的設定,或者幹脆放棄TextView而使用WebView來實現。但是,凡事都應該敢於解決問題,而不是回避問題,我相信即使僅用TextView一樣是可以實現,後來我發現stackoverflow上有個回答提供瞭一種思路,我按照這種思路果然實現瞭TextView文本的分散對齊。 以下是我的實現過程:

MainActivity中:

Display display = getWindowManager().getDefaultDisplay();           
DisplayMetrics dm = new DisplayMetrics();           
display.getMetrics(dm);           
width = dm.widthPixels;                       
//根據屏幕調整文字大小
mArticleTextView.setLineSpacing(0f, 1.5f);
mArticleTextView.setTextSize(8*(float)width/320f);                       
//設置TextView
mArticleTextView.setText("TextView需要顯示的文本內容");   
           
TextJustification.justify(mArticleTextView,mArticleTextView.getWidth());首先設置TextView的顯示字體大小和文本內容,這裡設置字體大小根據屏幕尺寸調整。然後調用自定義的類Textustification中的justify方法來實現TextView的分散對齊,兩個參數分別是TextView控件以及控件的寬度。

自定義的類TextJustification內容如下:

import java.util.ArrayList;

import android.graphics.Paint;
import android.text.TextUtils;
import android.widget.TextView;
import android.widget.TextView.BufferType;

public class TextJustification {

    public static void justify(TextView textView, float contentWidth) {
        String text=textView.getText().toString();
        String tempText;
        String resultText = "";
        Paint paint=textView.getPaint();

        ArrayList<String> paraList = new ArrayList<String>();       
        paraList = paraBreak(text);       
        for(int i = 0; i<paraList.size(); i++) {           
            ArrayList<String> lineList=lineBreak(paraList.get(i).trim(),paint,contentWidth);           
            tempText = TextUtils.join(" ", lineList).replaceFirst("\\s*", "");           
            resultText += tempText.replaceFirst("\\s*", "") + "\n";       
        }               
       
        textView.setText(resultText);
    }
    //分開每個段落
    public static ArrayList<String> paraBreak(String text, TextView textview) {
        ArrayList<String> paraList = new ArrayList<String>();
        String[] paraArray = text.split("\\n+");
           for(String para:paraArray) {
               paraList.add(para);
        }
        return paraList;
    }

    //分開每一行,使每一行填入最多的單詞數
    private static ArrayList<String> lineBreak(String text, Paint paint, float contentWidth){
        String [] wordArray=text.split("\\s");
        ArrayList<String> lineList = new ArrayList<String>();
        String myText="";

        for(String word:wordArray){
            if(paint.measureText(myText+" "+word)<=contentWidth)
                myText=myText+" "+word;
            else{
                int totalSpacesToInsert=(int)((contentWidth-paint.measureText(myText))/paint.measureText(" "));
                lineList.add(justifyLine(myText,totalSpacesToInsert));
                myText=word;
            }
        }
        lineList.add(myText);
        return lineList;
    }
    //已填入最多單詞數的一行,插入對應的空格數直到該行滿
    private static String justifyLine(String text,int totalSpacesToInsert){
        String[] wordArray=text.split("\\s");
        String toAppend=" ";

        while((totalSpacesToInsert)>=(wordArray.length-1)){
            toAppend=toAppend+" ";
            totalSpacesToInsert=totalSpacesToInsert-(wordArray.length-1);
        }
        int i=0;
        String justifiedText="";
        for(String word:wordArray){
            if(i<totalSpacesToInsert)
                justifiedText=justifiedText+word+" "+toAppend;

            else               
                justifiedText=justifiedText+word+toAppend;

            i++;
        }

        return justifiedText;
    }
   

}這個類完成瞭TextView內部文字的排版工作,主要分3個步驟:
1、將一篇文章按段落分成若幹段(如果隻有一段可以略去該步驟);

2、將每一段的文字拆分成各個單詞,然後根據控件長度確定每一行最多可以填入的單詞數,並且算出排滿該行還需要填入幾個空格。

3、填入空格。

註意代碼中用到瞭一些正則表達式進行文章內容操作,若不清楚可以自行搜索含義。

 

這樣就完成瞭TextView內部文字分散對齊的排版過程。總結一下,這樣操作還是有點蛋疼的,雖然不算復雜,但還是對文本內容進行瞭完全的重新處理;並且僅是使用瞭已有的文本和空格數來實現對齊,並不是嚴格的分散對齊。但不管怎麼說,終究是用TextView自身的操作來實現瞭,並且效果還算不錯。

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *