Android TextView兩端對(duì)齊解決辦法
Android TextView兩端對(duì)齊解決辦法
今天遇到一個(gè)關(guān)于TextView文字兩端對(duì)齊其實(shí)方案,大家都知道原生控件是不能滿(mǎn)足我們的需求的,因此需要自定義View
下面看下效果圖

package com.example.VerticalMarqueeTextView.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.TextView;
/**
* Created by John on 2017/2/9.
*/
public class WordAlignTextView extends TextView {
private float textSize;
private float textLineHeight;
//頂部
private int top;
//y軸
private int y;
//線(xiàn)
private int lines;
//底部
private int bottom;
//右邊
private int right;
//左邊
private int left;
//線(xiàn)字
private int lineDrawWords;
private char[] textCharArray;
private float singleWordWidth;
//每個(gè)字符的空隙
private float lineSpacingExtra;
private boolean isFirst = true;
public WordAlignTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
initTextInfo();
return true;
}
});
}
public WordAlignTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WordAlignTextView(Context context) {
this(context, null, 0);
}
public void initTextInfo() {
textSize = getTextSize();
//獲取線(xiàn)的高度
textLineHeight = getLineHeight();
left = 0;
right = getRight();
y = getTop();
// 要畫(huà)的寬度
int drawTotalWidth = right - left;
String text = getText().toString();
if (!TextUtils.isEmpty(text) && isFirst) {
textCharArray = text.toCharArray();
TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.density = getResources().getDisplayMetrics().density;
mTextPaint.setTextSize(textSize);
// 獲取單個(gè)單詞的的寬度
singleWordWidth = mTextPaint.measureText("一") + lineSpacingExtra;
// 每行可以放多少個(gè)字符
lineDrawWords = (int) (drawTotalWidth / singleWordWidth);
int length = textCharArray.length;
lines = length / lineDrawWords;
if ((length % lineDrawWords) > 0) {
lines = lines + 1;
}
first = false;
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
int totalHeight = (int) (lines*textLineHeight+textLineHeight*2 + getPaddingBottom()+getPaddingTop()+layoutParams.bottomMargin+layoutParams.topMargin);
setHeight(totalHeight);
}
}
@Override
protected void onDraw(Canvas canvas) {
bottom = getBottom();
int drawTotalLine = lines;
if(maxLine!=0&&drawTotalLine>maxLine){
drawTotalLine = maxLine;
}
for (int i = 0; i < drawTotalLine; i++) {
try {
int length = textCharArray.length;
int mLeft = left;
// 第i+1行開(kāi)始的字符index
int startIndex = (i * 1) * lineDrawWords;
// 第i+1行結(jié)束的字符index
int endTextIndex = startIndex + lineDrawWords;
if (endTextIndex > length) {
endTextIndex = length;
y += textLineHeight;
} else {
y += textLineHeight;
}
for (; startIndex < endTextIndex; startIndex++) {
char c = textCharArray[startIndex];
// if (c == ' ') {
// c = '\u3000';
// } else if (c < '\177') {
// c = (char) (c + 65248);
// }
canvas.drawText(String.valueOf(c), mLeft, y, getPaint());
mLeft += singleWordWidth;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
int maxLine;
public void setMaxLines(int max){
this.maxLine = max;
}
public void setLineSpacingExtra(int lineSpacingExtra){
this.lineSpacingExtra = lineSpacingExtra;
}
/**
* 判斷是否為中文
* @return
*/
public static boolean containChinese(String string){
boolean flag = false;
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if ((c >= 0x4e00) && (c <= 0x9FA5)) {
flag = true;
}
}
return flag;
}
public static String ToDBC(String input) {
// 導(dǎo)致TextView異常換行的原因:安卓默認(rèn)數(shù)字、字母不能為第一行以后每行的開(kāi)頭字符,因?yàn)閿?shù)字、字母為半角字符
// 所以我們只需要將半角字符轉(zhuǎn)換為全角字符即可
char c[] = input.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] == ' ') {
c[i] = '\u3000';
} else if (c[i] < '\177') {
c[i] = (char) (c[i] + 65248);
}
}
return new String(c);
}
}
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Android使用Sensor感應(yīng)器獲取用戶(hù)移動(dòng)方向(指南針原理)
這篇文章主要介紹了Android使用Sensor感應(yīng)器獲取用戶(hù)移動(dòng)方向的方法,實(shí)例分析了指南針原理極其應(yīng)用,需要的朋友可以參考下2015-12-12
總結(jié)Android中多線(xiàn)程更新應(yīng)用的頁(yè)面信息的方式
這篇文章主要介紹了總結(jié)Android中多線(xiàn)程更新應(yīng)用的頁(yè)面信息的方式,文中共總結(jié)了runOnUiThread、Handler、AsyncTask異步以及View直接在UI線(xiàn)程中更新的方法,需要的朋友可以參考下2016-02-02
android實(shí)現(xiàn)簡(jiǎn)單儀表盤(pán)效果
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)簡(jiǎn)單儀表盤(pán)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
Android通過(guò)實(shí)現(xiàn)GridView的橫向滾動(dòng)實(shí)現(xiàn)仿京東秒殺效果
這篇文章主要介紹了Android通過(guò)實(shí)現(xiàn)GridView的橫向滾動(dòng)實(shí)現(xiàn)仿京東秒殺效果,實(shí)現(xiàn)代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07
Android實(shí)現(xiàn)Banner界面廣告圖片循環(huán)輪播(包括實(shí)現(xiàn)手動(dòng)滑動(dòng)循環(huán))
這篇文章主要介紹了Android實(shí)現(xiàn)Banner界面廣告圖片循環(huán)輪播(包括實(shí)現(xiàn)手動(dòng)滑動(dòng)循環(huán))的相關(guān)資料,需要的朋友可以參考下2016-02-02
Android輸入法與表情面板切換時(shí)的界面抖動(dòng)問(wèn)題解決方法
這篇文章主要介紹了Android輸入法與表情面板切換時(shí)的界面抖動(dòng)問(wèn)題解決方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
Android開(kāi)發(fā)之TabActivity用法實(shí)例詳解
這篇文章主要介紹了Android開(kāi)發(fā)之TabActivity用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android擴(kuò)展Activity實(shí)現(xiàn)標(biāo)簽頁(yè)效果的具體步驟與相關(guān)技巧,需要的朋友可以參考下2016-03-03
解決Android中自定義DialogFragment解決寬度和高度問(wèn)題
Android中自定義DialogFragment解決寬度和高度問(wèn)題但是我們很多時(shí)候想把DialogFragment的高度固定,那么我們需要設(shè)置DialogFragment的高度,在Fragment的onResume()聲明周期方法中設(shè)置window的寬高即可2017-12-12
Android實(shí)現(xiàn)ImageView圖片雙擊放大及縮小
這篇文章主要介紹了Android實(shí)現(xiàn)ImageView圖片雙擊放大及縮小的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02

