最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android AutoWrapTextView中英文排版問題的解決方法

 更新時間:2017年05月23日 08:28:24   作者:偽文藝大叔  
這篇文章主要給大家介紹了關于Android AutoWrapTextView中英文排版問題的解決方法,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。

前言

最近項目有新需求,UED給了個卡券密碼的UI樣式,如圖:


我一看很簡單啊,一個TextView解決問題,然后做好以后在模擬器里一看.....


納尼,這個時候才想起來,TextView 中英文在一起會有排版問題,那怎么解決呢......

思路

剛開始的想法是一個字符一個字符的去繪制,繪制到最右邊的臨界點就換行繪制,結果實踐以后發(fā)現(xiàn)不同的字符之間的間距不一樣,顯示會非常凌亂,又沒有什么好的方案解決這個間距問題,所以這個方案pass;單個字符繪制不行那就一行一行繪制,根據(jù)View的長度把文本拆分成N行,然后一行一行的繪制。

實現(xiàn)

首先創(chuàng)建一個繼承自View的AutoWrapTextView

public class AutoWrapTextView extends View {

}

來看看它的構造方法

public AutoWrapTextView(Context context, AttributeSet attrs) {
  super(context, attrs);

  init(context, attrs);
}

private void init(Context context, AttributeSet attrs) {
  initStyle(context, attrs);
  initPaint();
}

init方法里分別調(diào)用了initStyle方法和initPaint方法;

initStyle方法主要解析自定義的屬性

 private void initStyle(Context context, AttributeSet attrs) {
  TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AutoWrapTextViewStyle);
  mPaddingLeft = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_paddingLeft, 0);
  mPaddingRight = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_paddingRight, 0);
  mPaddingTop = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_paddingTop, 0);
  mPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_paddingBottom, 0);

  mTextColor = typedArray.getColor(R.styleable.AutoWrapTextViewStyle_textColor, Color.BLACK);
  mTextSize = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_textSize, 50);
  mLineSpacingExtra = typedArray.getInteger(R.styleable.AutoWrapTextViewStyle_lineSpacingExtra, 7);

  typedArray.recycle();
 }

屬性名含義都很明顯不用過多解釋,initPaint方法就是初始化一個文本畫筆

 private void initPaint() {
  mTextPaint = new TextPaint();
  mTextPaint.setAntiAlias(true);
  mTextPaint.setTextSize(mTextSize);
  mTextPaint.setColor(mTextColor);
  mTextPaint.setTextAlign(Paint.Align.LEFT);
 }

接下來我們看看設置文本的方法setText方法

 public void setText(String text) {
  if (TextUtils.isEmpty(text)) return;

  //把文本轉(zhuǎn)換成Char數(shù)組
  mTextCharArray = text.toCharArray();
  requestLayout();
 }

首先把文本轉(zhuǎn)換成Char數(shù)組,然后循環(huán)數(shù)組把整個文本拆分成N行文本,下面來看看核心方法splitText方法

 private void splitText(int heightMode) {
  if (mTextCharArray == null) return;

  mSplitTextList = new ArrayList<>();
  mSingleTextWidth = getMeasuredWidth() - mPaddingLeft - mPaddingRight;
  int currentSingleTextWidth = 0;
  StringBuffer lineStringBuffer = new StringBuffer();
  for (int i = 0, length = mTextCharArray.length; i < length; i++) {
   char textChar = mTextCharArray[i];
   currentSingleTextWidth += getSingleCharWidth(textChar);
   if (currentSingleTextWidth > mSingleTextWidth) {
    mSplitTextList.add(lineStringBuffer.toString());
    lineStringBuffer = new StringBuffer();
    currentSingleTextWidth = 0;
    i--;
   } else {
    lineStringBuffer.append(textChar);
    if (i == length - 1) mSplitTextList.add(lineStringBuffer.toString());
   }
  }

  int textHeight = 0;
  mSplitTextRectArray = new Rect[mSplitTextList.size()];
  for (int m = 0, length = mSplitTextList.size(); m < length; m++) {
   String lineText = mSplitTextList.get(m);
   Rect lineTextRect = new Rect();
   mTextPaint.getTextBounds(lineText, 0, lineText.length(), lineTextRect);
   if (heightMode == MeasureSpec.AT_MOST) {
    textHeight += (lineTextRect.height() + mLineSpacingExtra);
    if (m == length - 1) {
     textHeight = textHeight + mPaddingBottom + mPaddingTop;
    }
   } else {
    if (textHeight == 0)
     textHeight = getMeasuredHeight();
   }
   mSplitTextRectArray[m] = lineTextRect;
  }

  setMeasuredDimension(getMeasuredWidth(), textHeight);
 }

首先創(chuàng)建一個屬性名為mSplitTextList的List集合用來存放拆分的文本;

mSingleTextWidth 為單行文本顯示的寬度;

currentSingleTextWidth 為當前一行累計計算的寬度;

然后開始循環(huán)Char數(shù)組,getSingleCharWidth方法就是計算單個Char的寬度;

如果currentSingleTextWidth 小于 mSingleTextWidth 就把Char添加到lineStringBuffer 當中,如果是最后一個Char就直接把lineStringBuffer添加到mSplitTextList集合當中

如果currentSingleTextWidth 大于 mSingleTextWidth,就把lineStringBuffer添加到mSplitTextList集合當中,重新給lineStringBuffer賦值,currentSingleTextWidth 歸0;

循環(huán)結束以后拆分好的文本就都添加到mSplitTextList集合當中了。

拆分完成以后循環(huán)mSplitTextList集合,得到每一行文本的Rect值,繪制文本的時候會用到,然后設置View的寬高。

接下來就是繪制方法drawText

 public void drawText(Canvas canvas) {
  if (mSplitTextList == null || mSplitTextList.size() == 0) return;

  int marginTop = getTopTextMarginTop();
  for (int m = 0, length = mSplitTextList.size(); m < length; m++) {
   String lineText = mSplitTextList.get(m);
   canvas.drawText(lineText, mPaddingLeft, marginTop, mTextPaint);
   marginTop += (mSplitTextRectArray[m].height() + mLineSpacingExtra);
  }
 }

首先得到第一行文本距離頂部的高度marginTop,然后循環(huán)文本繪制每一行文本內(nèi)容。

效果圖

我們來看下最后的效果


結束語

至此整個類的邏輯分析就結束了,想看完整源碼的可以移步:https://github.com/chenpengfei88/AutoWrapTextView或者通過本地進行下載:http://xiazai.jb51.net/201705/yuanma/AutoWrapTextView(jb51.net).rar

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • Android編程之下拉菜單Spinner控件用法示例

    Android編程之下拉菜單Spinner控件用法示例

    這篇文章主要介紹了Android編程之下拉菜單Spinner控件用法,結合簡單實例形式分析了Android下拉菜單Spinner的布局與功能相關實現(xiàn)技巧,需要的朋友可以參考下
    2017-07-07
  • Android應用程序中讀寫txt文本文件的基本方法講解

    Android應用程序中讀寫txt文本文件的基本方法講解

    這篇文章主要介紹了Android應用程序中讀寫txt文本文件的基本方法講解,基本上依靠context.openFileInput()和context.openFileOutput()兩個方法為主,需要的朋友可以參考下
    2016-04-04
  • 5步教你快速寫一個android Router路由框架

    5步教你快速寫一個android Router路由框架

    本篇文章主要介紹了5步教你快速寫一個Router路由框架(詳細步驟),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Android自定義View實現(xiàn)仿駕考寶典顯示分數(shù)效果(收藏)

    Android自定義View實現(xiàn)仿駕考寶典顯示分數(shù)效果(收藏)

    本文通過自定義view和屬性動畫結合在一起實現(xiàn)實現(xiàn)仿駕考寶典顯示分數(shù)效果,非常不錯,具有參考借鑒價值,需要的的朋友參考下
    2017-03-03
  • Android自定義View實現(xiàn)內(nèi)存清理加速球效果

    Android自定義View實現(xiàn)內(nèi)存清理加速球效果

    這篇文章主要為大家詳細介紹了Android自定義View實現(xiàn)內(nèi)存清理加速球的效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Android電話撥號器實例詳解

    Android電話撥號器實例詳解

    這篇文章主要為大家詳細介紹了Android電話撥號器實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android 通過代碼安裝 APK的方法詳解

    Android 通過代碼安裝 APK的方法詳解

    這篇文章主要介紹了Android 通過代碼安裝 APK的方法詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習火鍋工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Android IPC機制ACtivity綁定Service通信代碼實例

    Android IPC機制ACtivity綁定Service通信代碼實例

    這篇文章主要介紹了Android IPC機制ACtivity綁定Service通信代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Android LayoutParams使用案例詳解

    Android LayoutParams使用案例詳解

    這篇文章主要介紹了Android LayoutParams使用案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Android 實現(xiàn)左滑出現(xiàn)刪除選項

    Android 實現(xiàn)左滑出現(xiàn)刪除選項

    滑動刪除的部分主要包含兩個部分, 一個是內(nèi)容區(qū)域(用于放置正常顯示的view),另一個是操作區(qū)域(用于放置刪除按鈕)。下面通過本文給大家介紹Android 實現(xiàn)左滑出現(xiàn)刪除選項,需要的朋友可以參考下
    2017-06-06

最新評論

盖州市| 理塘县| 柘荣县| 长顺县| 泸溪县| 巴青县| 新民市| 柳林县| 凤台县| 姜堰市| 泰顺县| 泰兴市| 德钦县| 兴业县| 仁怀市| 朝阳区| 河西区| 缙云县| 沂南县| 扶风县| 汉沽区| 凤翔县| 镇巴县| 万全县| 桃园县| 张家口市| 南漳县| 惠来县| 阜城县| 南平市| 淳化县| 库伦旗| 平昌县| 中西区| 连云港市| 临潭县| 固安县| 通道| 互助| 梓潼县| 称多县|