Android TextView自動換行文字排字參差不齊的原因及處理

來源:互聯網
上載者:User

標籤: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自動換行文字排字參差不齊的原因及處理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.