justified實現Textview和Edittext文字左右對齊
https://github.com/programingjd/justified
http://blog.sina.com.cn/s/blog_73615d370100zpt5.html
今天忽然發現android項目中的文字排版參差不齊的情況非常嚴重,不得不想辦法解決一下。經過研究之后,終于找到了textview自動換行導致混亂的原因了----半角字符與全角字符混亂所致!一般情況下,我們輸入的數字、字母以及英文標點都是半角,所以占位無法確定。它們與漢字的占位大大的不同,由于這個原因,導致很多文字的排版都是參差不齊的。對此我找到了兩種辦法可以解決這個問題:
1. 將textview中的字符全角化。即將所有的數字、字母及標點全部轉為全角字符,使它們與漢字同占兩個字節,這樣就可以避免由于占位導致的排版混亂問題了。 半角轉為全角的代碼如下,只需調用即可。
2. 去除特殊字符或將所有中文標號替換為英文標號。利用正則表達式將所有特殊字符過濾,或利用replaceAll()將中文標號替換為英文標號。則轉化之后,則可解決排版混亂問題。
解決之前層次不齊的排版截圖:
解決之后的整齊排版,如下圖:
Android自定義view-文本自動換行
文本自動換行原理:文本超出控件寬度后,自動換到下一行繪制。
實現代碼:
https://github.com/programingjd/justified
http://blog.sina.com.cn/s/blog_73615d370100zpt5.html
今天忽然發現android項目中的文字排版參差不齊的情況非常嚴重,不得不想辦法解決一下。經過研究之后,終于找到了textview自動換行導致混亂的原因了----半角字符與全角字符混亂所致!一般情況下,我們輸入的數字、字母以及英文標點都是半角,所以占位無法確定。它們與漢字的占位大大的不同,由于這個原因,導致很多文字的排版都是參差不齊的。對此我找到了兩種辦法可以解決這個問題:
1. 將textview中的字符全角化。即將所有的數字、字母及標點全部轉為全角字符,使它們與漢字同占兩個字節,這樣就可以避免由于占位導致的排版混亂問題了。 半角轉為全角的代碼如下,只需調用即可。
/** * 半角轉換為全角 * * @param input * @return */ 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); }
2. 去除特殊字符或將所有中文標號替換為英文標號。利用正則表達式將所有特殊字符過濾,或利用replaceAll()將中文標號替換為英文標號。則轉化之后,則可解決排版混亂問題。
/** * 去除特殊字符或將所有中文標號替換為英文標號 * * @param str * @return */ public static String stringFilter(String str) { str = str.replaceAll("【", "[").replaceAll("】", "]") .replaceAll("!", "!").replaceAll(":", ":");// 替換中文標號 String regEx = "[『』]"; // 清除掉特殊字符 Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(str); return m.replaceAll("").trim(); }
解決之前層次不齊的排版截圖:

解決之后的整齊排版,如下圖:

Android自定義view-文本自動換行
文本自動換行原理:文本超出控件寬度后,自動換到下一行繪制。
實現代碼:
protected void onDraw(Canvas canvas) { FontMetrics fm = mPaint.getFontMetrics(); float baseline = fm.descent - fm.ascent; float x = 0; float y = baseline; //由于系統基于字體的底部來繪制文本,所有需要加上字體的高度。 String txt = getResources().getString(com.orgcent.demo.R.string.hello); //文本自動換行 String[] texts = autoSplit(txt, mPaint, getWidth() - 5); System.out.printf("line indexs: %s\n", Arrays.toString(texts)); for(String text : texts) { canvas.drawText(text, x, y, mPaint); //坐標以控件左上角為原點 y += baseline + fm.leading; //添加字體行間距 } }
/** * 自動分割文本 * @param content 需要分割的文本 * @param p 畫筆,用來根據字體測量文本的寬度 * @param width 最大的可顯示像素(一般為控件的寬度) * @return 一個字符串數組,保存每行的文本 */ private String[] autoSplit(String content, Paint p, float width) { int length = content.length(); float textWidth = p.measureText(content); if(textWidth < = width) { return new String[]{content}; } int start = 0, end = 1, i = 0; int lines = (int) Math.ceil(textWidth / width); //計算行數 String[] lineTexts = new String[lines]; while(start < length) { if(p.measureText(content, start, end) > width) { //文本寬度超出控件寬度時 lineTexts[i++] = (String) content.subSequence(start, end); start = end; } if(end == length) { //不足一行的文本 lineTexts[i] = (String) content.subSequence(start, end); break; } end += 1; } return lineTexts; }

更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
