Some words about me

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas a urna sit amet leo sagittis cursus a at lectus. Donec bibendum facilisis ultricies. Maecenas nec arcu dui, ut lobortis erat. In nec condimentum quam. Vivamus euismod scelerisque ligula vitae fermentum. Nulla dignissim rutrum eleifend.

Donec mi eros, congue ut consectetur eget, pretium vitae orci. Aliquam pharetra ultricies lobortis. Morbi eget nisi lectus. Maecenas felis augue, molestie in vestibulum et, lacinia et leo. Suspendisse potenti. Maecenas eget est augue. Donec tincidunt mollis fermentum.

Contact me?

 
 
 

Donec mi eros, congue ut consectetur eget, pretium vitae orci. Aliquam pharetra ultricies lobortis. Morbi eget nisi lectus. Maecenas felis augue, molestie in vestibulum et, lacinia et leo. Suspendisse potenti. Maecenas eget est augue. Donec tincidunt mollis fermentum.

Send the message
 

自动滚动的Textview


   又到了写博博的时候了!大家还好吧!


   开始做机顶盒了,所以这里就有很多的界面需要做成一个自动化的界面。因为遥控盒手机触摸毕竟不一样咯!这里而且要方便大众的视觉体验的话,我们必须要考虑到这些因素。当然,我觉着,这次的自动滚动效果一定对大家也很有帮助的哦!


  我们只要写一个类来继承我布局文件里面写的一个TextView就ok啦。









package
com.example.myscroltextview.view; import java.util.ArrayList; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Typeface; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.widget.TextView; /** * 垂直滚动的textview * * @author Catherine.Brian.William * */ public class VertailScrollTextView extends TextView { public VertailScrollTextView(Context context) { super(context); init(); } public VertailScrollTextView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public VertailScrollTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } Handler handler; /** * 是否在滚动 */ boolean scrolling = false; /** * 当前的位移 */ float currentY; /** * 每次滚动的距离 */ float speed = 0.2f; /** * 要显示的text */ String scrollText = ""; /** * 真实宽度,在配置width="xxdp"里起作用 */ private int exactlyWidth = -1; /** * 真实高度,在配置height="xxdip"里起作用 */ private int exactlyHeight = -1; /** * 实际高度:所有字显示完全需要的高度 */ float absloutHeight = 0; /** * handler发消息的时间间隔 */ int delayTime = 50; /** * 每行的字符串 */ ArrayList<String> lineStrings; Paint mPaint; private static final int DY = 20; // 每一行的间隔 /** * 初始化 */ private void init() { // 非高亮部分 mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setTextSize(20); mPaint.setColor(Color.WHITE); mPaint.setTypeface(Typeface.SERIF); handler = new Handler() { @Override public void handleMessage(Message msg) { if (absloutHeight <= getHeight()) { currentY = 0; stop(); return; } switch (msg.what) { case 0: currentY = currentY - speed; resetCurrentY(); invalidate(); handler.sendEmptyMessageDelayed(0, delayTime); break; } super.handleMessage(msg); } /** * 重置currentY(当currentY超过absolutHeight时,让它重置为0) */ private void resetCurrentY() { if (currentY >= absloutHeight || currentY <= -absloutHeight || getHeight() <= 0) { currentY = 0; } } }; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureWidth(widthMeasureSpec); int height = MeasureHeight(width, heightMeasureSpec); setMeasuredDimension(width, height); currentY = 0; if (height < absloutHeight) { play(); } else { stop(); } } /** * 测量宽度 * * @param widthMeasureSpec * @return */ private int MeasureWidth(int widthMeasureSpec) { int mode = MeasureSpec.getMode(widthMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); // 如果时候wrap_content if (mode == MeasureSpec.AT_MOST) { double abwidth = getPaint().measureText(scrollText); width = Math.min((int) Math.rint(abwidth), width); exactlyWidth = -1; } // 精确宽度 if (mode == MeasureSpec.EXACTLY) { exactlyWidth = width; } return width; } /** * 测量高度 * * @param width * @param heightMeasureSpec * @return */ private int MeasureHeight(int width, int heightMeasureSpec) { int mode = MeasureSpec.getMode(heightMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); generateTextList(width); int lines = lineStrings.size(); absloutHeight = lines * (getLineHeight() + DY) + getPaddingBottom() + getPaddingTop(); // 如果是wrap_content if (mode == MeasureSpec.AT_MOST) { height = (int) Math.min(absloutHeight, height); exactlyHeight = -1; } else if (mode == MeasureSpec.EXACTLY) { exactlyHeight = height; } return height; } /** * 生成多行字符串列表 * * @param MaxWidth */ public void generateTextList(int MaxWidth) { lineStrings = new ArrayList<String>(); String remain = scrollText; while (!remain.equals("")) { String line = getLineText(MaxWidth, remain); lineStrings.add(line); remain = remain.substring(line.length(), remain.length()); } } /** * 获取一行的字符 * * @param MaxWidth * @param remain * @return */ private String getLineText(int MaxWidth, String str) { // 真实行 StringBuffer trueStringBuffer = new StringBuffer(); // 临时行 StringBuffer tempStringBuffer = new StringBuffer(); for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); String add = ""; if (!isChinese(c) && isENWordStart(str, i)) { int place = getNextSpecePlace(i, str); // 找到下一个空格 if (place > -1) { add = str.substring(i, place) + " "; if (getPaint().measureText(add) > MaxWidth) { add = "" + c; } else { i = place; } } else { add = "" + c; } } else { add = "" + c; } tempStringBuffer.append(add); String temp = tempStringBuffer.toString(); float width = getPaint().measureText(temp.toString()); if (width <= MaxWidth) { trueStringBuffer.append(add); } else { break; } } return trueStringBuffer.toString(); } /** * 找到下一个空格的地方 * * @param i * @param str * @return */ int getNextSpecePlace(int i, String str) { for (int j = i; j < str.length(); j++) { char c = str.charAt(j); if (c == ' ') { return j; } } return -1; } /** * 是否为英文单词的首字母 * * @param str * @param i * @return */ boolean isENWordStart(String str, int i) { if (i == 0) { return true; } else if (str.charAt(i - 1) == ' ') { return true; } return false; } /** * 设置textview的文字 * * @param scrollText */ public void setScrollText(String scrollText) { this.scrollText = scrollText; // setText(scrollText); reset(); } public String getScrollText() { return scrollText; } /** * 重置 */ private void reset() { requestLayout(); invalidate(); currentY = 0; } /** * 开始滚动 */ public void play() { if (!scrolling) { handler.sendEmptyMessage(0); scrolling = true; } } /** * 停止滚动 */ public void stop() { if (scrolling) { handler.removeMessages(0); scrolling = false; } } /** * 更改滚动状态 */ public void updateScrollStatus() { if (scrolling) { stop(); } else { play(); } } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); float x = getPaddingLeft(); float y = getPaddingTop(); float lineHeight = getLineHeight() + DY; float textSize = getPaint().getTextSize(); for (int i = 0; i < lineStrings.size(); i++) { // currentY+=50; y = lineHeight * i + textSize + currentY; float min = 0; if (exactlyHeight > -1) { min = Math.min(min, exactlyHeight - absloutHeight); } if (y < min) { y = y + absloutHeight; } else if (y >= min && y < textSize + min) { // 如果最顶端的文字已经到达需要循环从下面滚出的时候 System.out.println("x:" + x + "y:" + y); } if (y >= absloutHeight) { // 如果最底端的文字已经到达需要循环从上面滚出的时候 System.out.println("x:" + x + "y:" + y); y = y - absloutHeight; } canvas.drawText(lineStrings.get(i), x, y, mPaint); } } /** * 判断是否为中文 * * @param c * @return */ private static final boolean isChinese(char c) { Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { return true; } return false; } }

 

 

posted @ 2014-05-08 10:47  Catherine_Brain  阅读(385)  评论(0编辑  收藏  举报