Android实现TextView两端对齐的方法_Android

Android中的TextView控件默认是做不到两端对齐的,都是左对齐。可能的原因是安卓默认数字、字母不能为第一行以后每行的开头字符,因为数字、字母为半角字符,还有就是文字中的英文字符占用1个字节,而一个汉字占用两个字节。下面我就介绍下实现两端对齐的原理:

  • 1、测量一个中文汉字所占用的宽度
  • 2、根据TextView的宽度和一个汉字所占用的宽度以及字符之间的间隔计算出总行数。
  • 3、根据padding和margin以及行高计算出TextView的总高度。
  • 4、绘制每一行的每一个字符

效果如下:

具体代码如下:

package com.wedroid.framework.module.ui;

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.MarginLayoutParams;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.widget.TextView;

public class WeDroidAlignTextView extends TextView {

  private boolean first = true;

  public WeDroidAlignTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
      @Override
      public boolean onPreDraw() {
        initTextInfo();
        return true;
      }
    });
  }

  public WeDroidAlignTextView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public WeDroidAlignTextView(Context context) {
    this(context, null, 0);
  }

  private float textSize;
  private float textLineHeight;
  private int top;
  private int y;
  private int lines;
  private int bottom;
  private int right;
  private int left;
  private int lineDrawWords;
  private char[] textCharArray;
  private float singleWordWidth;

  private float lineSpacingExtra;

  public void initTextInfo() {
    textSize = getTextSize();
    textLineHeight = getLineHeight();
    left = 0;
    right = getRight();
    y = getTop();
    // 要画的宽度
    int drawTotalWidth = right - left;
    String text = getText().toString();
    if (!TextUtils.isEmpty(text) && first) {
      textCharArray = text.toCharArray();
      TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
      mTextPaint.density = getResources().getDisplayMetrics().density;
      mTextPaint.setTextSize(textSize);
      // 一个单词的的宽度
      singleWordWidth = mTextPaint.measureText("一") + lineSpacingExtra;
      // 一行可以放多少个字符
      lineDrawWords = (int) (drawTotalWidth / singleWordWidth);
      int length = textCharArray.length;
      lines = length / lineDrawWords;
      if ((length % lineDrawWords) > 0) {
        lines = lines + 1;
      }
      first = false;
      MarginLayoutParams layoutParams = (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行开始的字符index
        int startIndex = (i * 1) * lineDrawWords;
        // 第i+1行结束的字符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) {
    // 导致TextView异常换行的原因:安卓默认数字、字母不能为第一行以后每行的开头字符,因为数字、字母为半角字符
    // 所以我们只需要将半角字符转换为全角字符即可
    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);
  }

}

希望本文所述对大家学习Android程序设计有所帮助。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
textview
textview两端对齐、textview文字两端对齐、安卓textview两端对齐、textalign两端对齐、text两端对齐,以便于您获取更多的相关知识。

时间: 2024-09-19 05:55:54

Android实现TextView两端对齐的方法_Android的相关文章

Android实现TextView两端对齐的方法

Android中的TextView控件默认是做不到两端对齐的,都是左对齐.可能的原因是安卓默认数字.字母不能为第一行以后每行的开头字符,因为数字.字母为半角字符,还有就是文字中的英文字符占用1个字节,而一个汉字占用两个字节.下面我就介绍下实现两端对齐的原理: 1.测量一个中文汉字所占用的宽度 2.根据TextView的宽度和一个汉字所占用的宽度以及字符之间的间隔计算出总行数. 3.根据padding和margin以及行高计算出TextView的总高度. 4.绘制每一行的每一个字符 效果如下: 具

Android TextView两端对齐解决办法

Android TextView两端对齐解决办法 今天遇到一个关于TextView文字两端对齐其实方案,大家都知道原生控件是不能满足我们的需求的,因此需要自定义View 下面看下效果图 package com.example.VerticalMarqueeTextView.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import andro

Word的两端对齐设置方法

两端对齐:设置文本内容两端,调整文字的水平间距,使其均匀分布在左右页边距之间.两端对齐使两侧文字具有整齐的边缘. 电脑教程 Word中设置两端对齐 对齐方式的应用范围为段落,以Microsoft Word 2010软件为例介绍设置两端对齐的方法: 方式1 打开Word2010文档窗口,选中需要设置对齐方式的段落.然后在"开始"功能区的"段落"分组中单击"两端对齐"按钮设置对齐方式. 方式2 打开Word2010文档窗口,选中需要设置对齐方式的段落

android动态布局之动态加入TextView和ListView的方法_Android

本文实例讲述了android动态布局之动态加入TextView和ListView的方法.分享给大家供大家参考.具体实现方法如下: package org.guoshi; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.guoshi.adapter.ImageAndTextAdapter; import android.app.

基于Android的英文词典的实现方法_Android

英文词典是手机中经常使用的应用.因此,在本文将结合Android来讨论如何实现一个Android版的英文词典.实现英文词典的方法很多.在本文使用了SQLite数据库来保存英文单词信息.系统通过SQLite数据库中保存的单词信息来查找到与指定英文对应的中文信息.当然,实现这样一个英文词典需要解决一系列技术问题.例如,如何将保存英文单词信息的数据库文件随程序(apk文件)一起发布:发布后如何打开数据库:如何在输入前几个字母后,在AutoCompleteTextView组件提示列表中显示以所输入字符串

android编程之menu按键功能实现方法_Android

本文实例讲述了android编程之menu按键功能实现方法.分享给大家供大家参考.具体分析如下: android应用程序可以通过menu按键弹出菜单,现在通过menu按键弹出一个拥有两个选项的菜单.点击第一个按键,文本框会显示"第1个按键",点击第二个按键,文本框会显示"第2个按键" package com.test_menu; import android.app.Activity; import android.os.Bundle; import android

Android编程实现TCP客户端的方法_Android

本文实例讲述了Android编程实现TCP客户端的方法.分享给大家供大家参考,具体如下: 因为项目上需要实现一个TCP Client 端:在网上找好多例子基本上都是阻塞方式完成: 我的实现例子:由Activity 及sever 来实现,在sever 创建一个线程来监听接受数据.收到数据,通过广播发送给Activity; 服务端我没有去实现,你可以下载TCP Socket 调试工具v2.2:创建个9005端口:客户端:访问的IP为10.0.2.2 AnetTest.java: /** * Copy

Android 添加TextView删除线(代码简单)_Android

在做商城的项目中,有这么个需求,就是一个产品下有两个价格,一个是市场价,一个是销售价,这时要把市场价添加个删除线: 刚开始遇到这个时,在网上找了半天的资料,看到最多的就是用SpannableString这个类中的方法,而且代码多,感觉有点繁琐,后来发现用Paint里的一些方法实现更好,只须一句代码 public class TestActivity extends Activity { private TextView tv; @Override public void onCreate(Bun

Android实现下载文件功能的方法_Android

本文所述为Android实现下载文件功能的完整示例代码,对于学习和研究android编程相信会有一定的帮助,尤其是对Android初学者有一定的借鉴价值. 完整功能代码如下: package com.test; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import and