標籤:des android color os java io strong for 檔案
Android TextView自動換行文字排版參差不齊的原因及處理
轉自:
TextView會自動換行,而且排版文字參差不齊。查了下資料,總結原因如下:
1、半形字元與全形字元混亂所致:這種情況一般就是漢字與數字、英文字母混用
解決方案一:
將textview中的字元全形化。即將所有的數字、字母及標點全部轉為全形字元,使它們與漢字同佔兩個位元組,這樣就可以避免由於佔位導致的排版混亂問題了。 半形轉為全形的代碼如下,只需調用即可。
public static String ToDBC(String input) {
char[] c = input.toCharArray();
for (int i = 0; i< c.length; i++) {
if (c[i] == 12288) {
c[i] = (char) 32;
continue;
}if (c[i]> 65280&& c[i]< 65375)
c[i] = (char) (c[i] - 65248);
}
return new String(c);
}
解決方案二:
去除特殊字元或將所有中文標號替換為英文標號。利用Regex將所有特殊字元過濾,或利用replaceAll()將中文標號替換為英文標號。則轉化之後,則可解決排版混亂問題。
// 替換、過濾特殊字元
public static String StringFilter(String str) throws PatternSyntaxException{
str=str.replaceAll("","]").replaceAll("!","!");//替換中文標號
String regEx="[『』]"; // 清除掉特殊字元
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.replaceAll("").trim();
}
2、TextView在顯示中文的時候標點符號不能顯示在一行的行首和行尾,如果一個標點符號剛好在一行的行尾,該標點符號就會連同前一個字元跳到下一行顯示。
解決方案:在標點符號後加一個空格。
3、一個英文單詞不能被顯示在兩行中( TextView在顯示英文時,標點符號是可以放在行尾的,但英文單詞也不能分開 )。
4、如果要兩行對其的顯示效果:有兩種方法
方法一:
修改Android原始碼;將frameworks/base/core/java/android/text下的StaticLayout.java檔案中的如下代碼:
if (c == ‘ ‘ || c == ‘/t‘ ||
((c == ‘.‘ || c == ‘,‘ || c == ‘:‘ || c == ‘;‘) &&
(j - 1 < here || !Character.isDigit(chs[j - 1 - start])) &&
(j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
((c == ‘/‘ || c == ‘-‘) &&
(j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
(c >= FIRST_CJK && isIdeographic(c, true) &&
j + 1 < next && isIdeographic(chs[j + 1 - start], false))) {
okwidth = w;
ok = j + 1;
if (fittop < oktop)
oktop = fittop;
if (fitascent < okascent)
okascent = fitascent;
if (fitdescent > okdescent)
okdescent = fitdescent;
if (fitbottom > okbottom)
okbottom = fitbottom;
}
去掉就可以了。去掉後標點符號可以顯示在行首和行尾,英文單詞也可以被分開在兩行中顯示。
方法二:
自訂View顯示文本
網上就有達人採用自訂View來解決這個問題,我做了實驗並總結了一下:
自訂View的步驟:
1)繼承View類或其子類,例子繼承了TextView類;
2)寫建構函式,通過XML擷取屬性(這一步中可以自訂屬性,見常式);
3)重寫父類的某些函數,一般都是以on開頭的函數,例子中重寫了onDraw()和onMeasure()函數;
以下是代碼
=========================MyTextView2.java=============================
public class MyTextView2 extends TextView{
private final String namespace = "";
private String text;
private float textSize;
private float paddingLeft;
private float paddingRight;
private float marginLeft;
private float marginRight;
private int textColor;
private Paint paint1 = new Paint();
private float textShowWidth;
public MyTextView2(Context context, AttributeSet attrs) {
super(context, attrs);
text = attrs.getAttributeValue("", "text");
textSize = attrs.getAttributeIntValue(namespace, "textSize", 15);
textColor = attrs.getAttributeIntValue(namespace, "textColor",Color.WHITE);
paddingLeft = attrs.getAttributeIntValue(namespace, "paddingLeft", 0);
paddingRight = attrs.getAttributeIntValue(namespace, "paddingRight", 0);
marginLeft = attrs.getAttributeIntValue(namespace, "marginLeft", 0);
marginRight = attrs.getAttributeIntValue(namespace, "marginRight", 0);
paint1.setTextSize(textSize);
paint1.setColor(textColor);
paint1.setAntiAlias(true);
textShowWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth() - paddingLeft - paddingRight - marginLeft - marginRight;
}
@Override
protected void onDraw(Canvas canvas) {
int lineCount = 0;
text = this.getText().toString();//.replaceAll("\n", "\r\n");
if(text==null)return;
char[] textCharArray = text.toCharArray();
// 已繪的寬度
float drawedWidth = 0;
float charWidth;
for (int i = 0; i < textCharArray.length; i++) {
charWidth = paint1.measureText(textCharArray, i, 1);
if(textCharArray[i]==‘\n‘){
lineCount++;
drawedWidth = 0;
continue;
}
if (textShowWidth - drawedWidth < charWidth) {
lineCount++;
drawedWidth = 0;
}
canvas.drawText(textCharArray, i, 1, paddingLeft + drawedWidth,
(lineCount + 1) * textSize, paint1);
drawedWidth += charWidth;
}
setHeight((lineCount + 1) * (int) textSize + 5);
}
}
=======================main.xml===============================
<RelativeLayout xmlns:android=""
xmlns:tools=""
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black" >
<com.wigit.MyTextView2
android:id="@+id/view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@android:color/white"
android:textSize="20dip" />
</RelativeLayout>
=======================MainActivity.java=============================
public class MainActivity extends Activity {
MyTextView2 view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = (MyTextView2) findViewById(R.id.view);
view.setText(getAssetsString(this,"1.txt"));
view.setMovementMethod(ScrollingMovementMethod.getInstance());
}
public String getAssetsString(Context context,String fileName){
StringBuffer sb = new StringBuffer();
//根據語言選擇載入
try {
AssetManager am = context.getAssets();
InputStream in = am.open(fileName);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while((line = reader.readLine())!=null){
line += ("\n");
sb.append(line);
}
reader.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
Android TextView自動換行文字排字參差不齊的原因及處理