TextView的纵向排列

通用情况下,我们都是用TextView的横向排列,但有时候需求需要用到纵向排列,此时就傻眼了,本人也因此摘了两篇文章,供参考:

1、仅文字方向纵向排列,文字并没有翻转


public class VerticalTextView extends TextView{

final boolean topDown;

public VerticalTextView(Context context, AttributeSet attrs){

super(context, attrs);

final int gravity = getGravity();

if(Gravity.isVertical(gravity) && (gravity&Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {

setGravity((gravity&Gravity.HORIZONTAL_GRAVITY_MASK) | Gravity.TOP);

topDown = false;

}else

topDown = true;

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){

super.onMeasure(heightMeasureSpec, widthMeasureSpec);

setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());

}

@Override

protected boolean setFrame(int l, int t, int r, int b){

return super.setFrame(l, t, l+(b-t), t+(r-l));

}

@Override

public void draw(Canvas canvas){

if(topDown){

canvas.translate(getHeight(), 0);

canvas.rotate(90);

}else {

canvas.translate(0, getWidth());

canvas.rotate(-90);

}

canvas.clipRect(0, 0, getWidth(), getHeight(), android.graphics.Region.Op.REPLACE);

super.draw(canvas);

}

}

2、文字正常的纵向排列(真实需求)


public class TextViewVertical extends View {

public static final int LAYOUT_CHANGED = 1;

private Paint paint;

private int mTextPosx = 0;// x坐标

private int mTextPosy = 0;// y坐标

private int mTextWidth = 0;// 绘制宽度

private int mTextHeight = 0;// 绘制高度

private int mFontHeight = 0;// 绘制字体高度

private float mFontSize = 24;// 字体大小

private int mRealLine = 0;// 字符串真实的行数

private int mLineWidth = 0;//列宽度

private int TextLength = 0 ;//字符串长度

private int oldwidth = 0 ;//存储久的width

private String text="";//待显示的文字

private Handler mHandler=null;

private Matrix matrix;

BitmapDrawable drawable = (BitmapDrawable) getBackground();

public TextViewVertical(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

public TextViewVertical(Context context,AttributeSet attrs) {

super(context, attrs);

matrix = new Matrix();

paint = new Paint();//新建画笔

paint.setTextAlign(Align.CENTER);//文字居中

paint.setAntiAlias(true);//平滑处理

paint.setColor(Color.BLUE);//默认文字颜色

try{

mFontSize = Float.parseFloat(attrs.getAttributeValue(null,"textSize"));//获取字体大小属性

}catch(Exception e){}

}

/*

//获取整数值

private final int getAttributeIntValue(AttributeSet attrs,String field) {

int intVal = 0;

//TODO

//应该可以直接用attrs.getAttributeIntValue()获取对应的数值的,

//但不知道为什么一直无法获得只好临时写个函数凑合着用,没有写完整,暂时只支持px作为单位,其它单位的转换有空再写

String tempText=attrs.getAttributeValue(androidns, field);

intVal = (int)Math.ceil(Float.parseFloat(tempText.replaceAll("px","")));

return intVal;

}*/

//设置文字

public final void setText(String text) {

this.text=text;

this.TextLength = text.length();

if(mTextHeight>0)

GetTextInfo();

}

//设置字体大小

public final void setTextSize(float size) {

if (size != paint.getTextSize()) {

mFontSize = size;

if(mTextHeight>0)

GetTextInfo();

}

}

//设置字体颜色

public final void setTextColor(int color) {

paint.setColor(color);

}

//设置字体颜色

public final void setTextARGB(int a,int r,int g,int b) {

paint.setARGB(a, r, g, b);

}

//设置字体

public void setTypeface(Typeface tf) {

if (this.paint.getTypeface() != tf) {

this.paint.setTypeface(tf);

}

}

//设置行宽

public void setLineWidth(int LineWidth) {

mLineWidth = LineWidth;

}

//获取实际宽度

public int getTextWidth() {

return mTextWidth;

}

//设置Handler,用以发送事件

public void setHandler(Handler handler) {

mHandler=handler;

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

Log.v("TextViewVertical","onDraw");

if(drawable != null){

//画背景

Bitmap b = Bitmap.createBitmap(drawable.getBitmap(),0,0,mTextWidth,mTextHeight);

canvas.drawBitmap(b, matrix, paint);

}

//画字

draw(canvas, this.text);

}

private void draw(Canvas canvas, String thetext) {

char ch;

mTextPosy = 0;//初始化y坐标

mTextPosx = mTextWidth - mLineWidth;//初始化x坐标

for (int i = 0; i < this.TextLength; i++) {

ch = thetext.charAt(i);

if (ch == ‘\n‘) {

mTextPosx -= mLineWidth;// 换列

mTextPosy = 0;

} else {

mTextPosy += mFontHeight;

if (mTextPosy > this.mTextHeight) {

mTextPosx -= mLineWidth;// 换列

i--;

mTextPosy = 0;

}else{

canvas.drawText(String.valueOf(ch), mTextPosx, mTextPosy, paint);

}

}

}

}

//计算文字行数和总宽

private void GetTextInfo() {

Log.v("TextViewVertical","GetTextInfo");

char ch;

int h = 0;

paint.setTextSize(mFontSize);

//获得字宽

if(mLineWidth == 0){

float[] widths = new float[1];

paint.getTextWidths("正", widths);//获取单个汉字的宽度

mLineWidth = (int) Math.ceil(widths[0] * 1.1 +2);

}

FontMetrics fm = paint.getFontMetrics();

mFontHeight = (int) (Math.ceil(fm.descent - fm.top) * 1.0);// 获得字体高度

//计算文字行数

mRealLine=0;

for (int i = 0; i < this.TextLength; i++) {

ch = this.text.charAt(i);

if (ch == ‘\n‘) {

mRealLine++;// 真实的行数加一

h = 0;

} else {

h += mFontHeight;

if (h > this.mTextHeight) {

mRealLine++;// 真实的行数加一

i--;

h = 0;

} else {

if (i == this.TextLength - 1) {

mRealLine++;// 真实的行数加一

}

}

}

}

mRealLine++;//额外增加一行

mTextWidth = mLineWidth*mRealLine;//计算文字总宽度

measure(mTextWidth, getHeight());//重新调整大小

layout(getLeft(), getTop(), getLeft()+mTextWidth, getBottom());//重新绘制容器

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int measuredHeight = measureHeight(heightMeasureSpec);

if(mTextWidth==0)

GetTextInfo();

setMeasuredDimension(mTextWidth, measuredHeight);

if(oldwidth!=getWidth()) {

oldwidth=getWidth();

if(mHandler!=null)mHandler.sendEmptyMessage(LAYOUT_CHANGED);

}

}

private int measureHeight(int measureSpec) {

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

int result = 500;

if (specMode == MeasureSpec.AT_MOST) {

result = specSize;

}else if (specMode == MeasureSpec.EXACTLY) {

result = specSize;

}

mTextHeight=result;//设置文本高度

return result;

}

}

有空的亲,请自己测试一下!

时间: 2024-09-29 18:51:54

TextView的纵向排列的相关文章

浅谈android中仅仅使用一个TextView实现高仿京东,淘宝各种倒计时

今天给大家带来的是仅仅使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.最近公司一直加班也没来得及时间去整理,今天难得休息想把这个分享给大家,只求共同学习,以及自己后续的复习.为什么会想到使用一个TextView来实现呢?因为最近公司在做一些优化的工作,其中就有一个倒计时样式,原来开发的这个控件的同事使用了多个TextView拼接在一起的,实现的代码冗余比较大,故此项目经理就说:小宏这个就交给你来优化了,并且还要保证有一定的扩展性,当时就懵逼了.不知道从何处开始

使用文本框TextView/EditText的开源库清单

在实际的开发中TextView和EditText是非常基本的控件.这两个控件的使用也是十分简单.而TextView/EditText的功能其实也是非常强大,例如简单的图文就可以使用TextView配合Spannable来实现,以及TextView的drawableTop属性. 而使用以下的这些库则可以帮我们很方便实现各种需求,例如标签云.支持各种字体.文本动画.富文本编辑框等等需求. AndroidTagGroup 一个漂亮的标签控件,可以动态添加和删除标签 https://github.com

android TextView实现滚动显示效果

在android中,如果设置了TextView控件为单行显示,且显示的文本太长的话,默认情况下会造成显示不全的情况,这种情况下我们需要设置该控件属性如下: <TextView android:id="@+id/tv1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" and

项目需求:自定义倒计时的TextView

现在这么一个需求: 我有一个ListView,每一个列表项 布局如上图,顶部一个大图片展示,中部一个音频播放,底部一个描述文字. 在这个界面,一次只能点击一个列表项的播放按钮,那么我直接在ListView所属的activity创建了唯一的一个MediaPlayer,然而,这不是问题,所有的音频方面的播放冲突都解决了 问题就在中部的音频播放,我需要点击左边的播放按钮,然后右边有一个剩余时间要跟随着变化,当然点击暂停的时候,剩余时间也要暂停 首先,这里运用了购物车功能的原理实现按钮的操作.Andro

android ListView条目中TextView隐藏到显示时的测量

觉得ExpendableListView挺好用,但是就是代码复杂了点,我一时半会理解不了,于是就直接自己写个效果来实现.先来看一下expendableListView中展开的动画效果: 然后我模仿此效果,建立如下的item布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent" andr

安卓给textView增加自定义的颜色

1:创建一个color.xml,然后把颜色填入 <?xml version="1.0" encoding="utf-8"?> <resources> <color name="white">#FFFFFF</color><!--白色 --> <color name="ivory">#FFFFF0</color><!--象牙色 -->

xml中定义个TextView控件及java代码中调用方法。

<TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="@string/hello_world"         android:id="@+id/myTextView" /> TextView myTextView = (Text

使用代码为textview设置drawableLeft

xml中的textView中设置android:drawableLeft: <TextView android:id="@+id/bookTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:drawableLeft="@drawable/

Android TextView里直接显示图片的三种方法

方法一:重写TextView的onDraw方法,也挺直观就是不太好控制显示完图片后再显示字体所占空间的位置关系.一般如果字体是在图片上重叠的推荐这样写.时间关系,这个不付源码了. 方法二:利用TextView支持部分Html的特性,直接用api赋图片.代码如下: //第一种方法在TextView中显示图片 String html = "<img src='" + R.drawable.circle + "'/>"; ImageGetter imgGett