实现中国古文的那种行文格式排版,从上至下从右至左的顺序。
|
(1)自定义竖排文字控件TextViewVertical.java:
package org.guyue; /************************** * 作者:古月摇光 * E-mail:45361251@qq.com * 更新日期:2012/02/28 * 说明:本类实现了文字的竖直排版显示(中国古时的行文形式), * 虽然仍有许多特效及功能仍未实现,但基本的使用已经能满足。 * 版权:尽管放心用吧,可以自行随意改进转载和使用,转载时请保留这段文字即可 * 另特别感谢 老僧xp 提出的修改意见 **************************/ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Typeface; import android.graphics.Paint.Align; import android.graphics.Paint.FontMetrics; import android.graphics.drawable.BitmapDrawable; import android.os.Handler; import android.util.AttributeSet; import android.util.Log; import android.view.View; /** * 自定义竖排文字控件 */ 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.BLACK);//默认文字颜色 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); } } } //调用接口方法 //activity.getHandler().sendEmptyMessage(TestFontActivity.UPDATE); } //计算文字行数和总宽 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) * 0.9);// 获得字体高度 //计算文字行数 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); //int measuredWidth = measureWidth(widthMeasureSpec); 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; } /* private int measureWidth(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; } return result; } */ }
(2)使用界面:
package org.guyue; import android.app.Activity; //import android.graphics.Typeface; import android.os.Bundle; import android.os.Handler; import android.widget.HorizontalScrollView; public class TestFontActivity extends Activity{ private HorizontalScrollView sv; private TextViewVertical tv; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tv=(TextViewVertical)findViewById(R.id.tv); sv=(HorizontalScrollView)findViewById(R.id.sv); //设置接口事件接收 Handler handler=new Handler(){ public void handleMessage(android.os.Message msg) { switch(msg.what){ case TextViewVertical.LAYOUT_CHANGED: sv.scrollBy(tv.getTextWidth(), 0);//滚动到最右边 break; } } }; tv.setHandler(handler);//将Handler绑定到TextViewVertical //创建并设置字体(这里只是为了效果好看一些,但为了让网友们更容易下载,字体库并没有一同打包 //如果需要体验下效果的朋友可以自行在网络上搜索stxingkai.ttf并放入assets/fonts/中) //Typeface face=Typeface.createFromAsset(getAssets(),"fonts/stxingkai.ttf"); //tv.setTypeface(face); //设置文字内容 tv.setText("测试\n这是一段测试文字,主要是为了测试竖直排版TextView的显示效果。" + "为了能更好的体验感受,我特意增加了比较接近书法的字体和颜色,如果有什么改进的建议请发邮件到我的邮箱吧。" + "\n竖直排版的TextView需要配合HorizontalScrollView使用才能有更佳的效果。当然,如果你有时间的话,也可以给这个类" + "加上滚动的功能。"); } }
简单易用,工程见附件
相关推荐
一个文字竖直滚动的view控件
本类实现了文字的竖直排版显示(中国古时的行文形式), 虽然仍有许多特效及功能仍未实现,但基本的使用已经能满足。
用到了在网上下载的一个资源,在其基础上改变了其界面风格。 原网络资源 直接看效果,
通过在style文件中进行配置,实现了带文字竖直进度条 类似电量显示的功能。
Android竖直(竖直)漂亮seekbar的源码实现,有竖直的和水平的两个进度条,欢迎下载学习。
Android 竖直刻度尺效果
很简单的文本信息竖直滚动展示效果,没有积分的可以搜索“Android TextView竖直滚动文字广告效果”的博客。
Android竖直时光轴效果,可扩展,支持图文排版.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
Android垂直滚动代码,Scrolview改写。
Android项目竖直滑动条.rar
本文给大家分享了三种方式实现Android文字垂直滚动、纵向走马灯效果,文中给大家介绍了相关属性及注意事项,需要的朋友参考下吧
在MFC中通过Button控件实现2水平和竖直2个方向的滚动。
Android为我们提供了竖直方向的滚动控件GridView,这篇文章主要介绍了Android使GridView横向水平滚动的实现方式,有兴趣的可以了解一下
android 垂直滚动的TextViewandroid 垂直滚动的TextView
Android项目竖直SeekBar源码.rar
Android案例页面底部弹框PopupWindow+竖直滑动选择器WheelView的实现
[Android]竖直滑动选择器WheelView的实现,效果类似android4.0以上原生的DatePicker这种,可以实现自定义的字符串数组竖直滑动显示