先上效果图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGFuZ25lbmd3dQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" height="369" width="199" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGFuZ25lbmd3dQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" height="369" width="202" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGFuZ25lbmd3dQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" height="441" width="265" alt="">

代码:

package com.example.scrolltextview;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.SpinnerAdapter;
import android.widget.TextView; public class ScrollTextView extends ViewGroup { private static final int SCROLL = 0;
private static final int JUSTIFY = 1;
private static final int ANIMATION_DURATION = 3000; private int mOrientation;
private int mSize;
private int mIndex;
private int mPosition;
private Scroller mScroller;
private Map<View, Integer> mViews;
private SpinnerAdapter mAdapter;
private int mPackedViews;
private int mAnimationDuration; private float measuredWidth = 0;
private float textSize = 0;
private float measuredHeight = 0;
private String text= null;
private String[] data;
private boolean flag = true;
public ScrollTextView(Context context, AttributeSet attrs) {
super(context, attrs); int[] linerarLayoutAttrs = {
android.R.attr.orientation,
};
TypedArray a = context.obtainStyledAttributes(attrs, linerarLayoutAttrs);
mOrientation = a.getInteger(0, LinearLayout.HORIZONTAL);
a.recycle(); mAnimationDuration = ANIMATION_DURATION; mScroller = new Scroller(context);
mIndex = -1;
mPosition = -1;
mPackedViews = -1;
mViews = new HashMap<View, Integer>(); setFocusable(true);
setFocusableInTouchMode(true); } public float getCharacterWidth(String text, float size){
if(null == text || "".equals(text))
return 0;
float width = 0;
Paint paint = new Paint();
paint.setTextSize(size);
float text_width = paint.measureText(text);//得到整体长度
width = text_width/text.length();//字符的长度
return width;
} public void setText(String text)
{
this.text = text;
data = new String[]{this.text};
LayoutInflater inflater= (LayoutInflater) getContext().getSystemService(getContext().LAYOUT_INFLATER_SERVICE);
TextView view = (TextView) inflater.inflate(R.layout.scroll_text_view, null);
textSize = view.getTextSize();
measuredHeight = textSize;
textSize = getCharacterWidth(text,textSize);
} public void beginScroll()
{
thread.start();
}
Thread thread = new Thread(new Runnable() {
boolean enabled = true;
@Override
public void run() {
// TODO Auto-generated method stub
while(enabled)
{
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setNextView();
enabled = mIndex + 1 < mAdapter.getCount();
}
}
}); @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measuredWidth = getMeasuredWidth();
mSize = mOrientation == LinearLayout.HORIZONTAL? getMeasuredWidth() : getMeasuredHeight();
if(flag && text!=null)
{
int length = text.length();
Log.i("AAA", "length*textSize:"+length*textSize+" measuredWidth:"+measuredWidth);
if(length*textSize >= measuredWidth)
{
int textCountInOneLine = (int) (measuredWidth/textSize -1);
int lineCount =(int) ((length%textCountInOneLine==0)? (length/textCountInOneLine):(length/textCountInOneLine+1));
Log.i("AAA", "length:"+length+" textCountInOneLine:"+textCountInOneLine+" lineCount:"+lineCount);
data = new String[lineCount];
for(int i=0;i<lineCount;i++)
{
if((i+1)*textCountInOneLine<length)
data[i] = text.substring(i*textCountInOneLine, (i+1)*textCountInOneLine);
else
data[i] = text.substring(i*textCountInOneLine, length);
Log.i("AAA", "data:"+data[i]);
}
}
else
{
data = new String[]{text};
} ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), R.layout.scroll_text_view, data);
setAdapter(adapter);
flag = false;
}
View view = getChildAt(0);
if(view!=null)
{
measureChild(view, widthMeasureSpec, widthMeasureSpec);
measuredHeight = view.getMeasuredHeight();
} setMeasuredDimension((int)measuredWidth, (int)measuredHeight);
} private int getPackedViews(int offset) {
int size = mSize;
int start = offset / size;
int numViews = offset % size != 0? 1 : 0;
return start << 1 | numViews;
} Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
mScroller.computeScrollOffset();
int currX = mScroller.getCurrX();
int delta = mPosition - currX;
mPosition = currX;
int packed = getPackedViews(mPosition);
manageViews(packed);
scroll(delta);
if (!mScroller.isFinished()) {
handler.sendEmptyMessage(msg.what);
} else {
if (msg.what == SCROLL) {
justify();
} else {
mIndex = mPosition / mSize; }
}
}
}; private void justify() {
int offset = mPosition % mSize;
if (offset != 0) {
int endPosition = mPosition - offset;
if (offset > mSize / 2) {
endPosition += mSize;
}
mScroller.startScroll(mPosition, 0, endPosition - mPosition, 0, mAnimationDuration);
handler.sendEmptyMessage(JUSTIFY);
} else {
mIndex = mPosition / mSize; }
} private void scroll(int offset) {
if (mOrientation == LinearLayout.HORIZONTAL) {
for (View view : mViews.keySet()) {
view.offsetLeftAndRight(offset);
}
} else {
for (View view : mViews.keySet()) {
view.offsetTopAndBottom(offset);
}
}
invalidate();
} public void setSelection(int index, boolean animate) {
if (index == mIndex) {
return;
}
int endPosition = index * mSize;
int diff = Math.abs(index - mIndex);
int sign = index > mIndex? 1 : -1;
mIndex = index;
if (diff > 1) {
mPosition = endPosition - sign * mSize;
}
if (animate) {
mScroller.startScroll(mPosition, 0, endPosition - mPosition, 0, mAnimationDuration);
handler.removeMessages(JUSTIFY);
handler.removeMessages(SCROLL);
handler.sendEmptyMessage(JUSTIFY);
} else {
mPosition = endPosition;
manageViews(index << 1); invalidate();
}
} private void manageViews(int packedViews) {
if (packedViews == mPackedViews) {
return;
} mPackedViews = packedViews;
int startIdx = packedViews >> 1;
int endIdx = startIdx + (packedViews & 1);
int viewIdx = startIdx;
while (viewIdx <= endIdx) {
if (!mViews.containsValue(viewIdx)) {
if (viewIdx >= 0 && viewIdx < mAdapter.getCount()) {
View view = mAdapter.getView(viewIdx, null, this);
mViews.put(view, viewIdx);
addView(view);
}
}
viewIdx++;
} // remove not visible views
Iterator<View> iterator = mViews.keySet().iterator();
while (iterator.hasNext()) {
View view = iterator.next();
int idx = mViews.get(view);
if (idx < startIdx || idx > endIdx) {
iterator.remove();
removeView(view);
}
}
} public int getSelection() {
return mIndex;
} public void setPreviousView() {
if (mAdapter != null && mIndex > 0) {
setSelection(mIndex-1, true); }
} public void setNextView() {
if (mAdapter != null && mIndex + 1 < mAdapter.getCount()) {
setSelection(mIndex+1, true);
}
} public void setAdapter(SpinnerAdapter adapter) {
mAdapter = adapter;
if (mAdapter != null) {
setSelection(0, false);
}
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (View view : mViews.keySet()) {
if (view.getWidth() == 0) {
// new View: not layout()ed
int idx = mViews.get(view);
if (mOrientation == LinearLayout.HORIZONTAL) {
int left = mSize * idx - mPosition;
view.layout(left, 0, left+r-l, b-t);
} else {
int top = mSize * idx - mPosition;
view.layout(0, top, r-l, top+b-t);
}
}
}
} }

使用:

String temp = getResources().getString(R.string.info);
ScrollTextView switcher1 = (ScrollTextView) findViewById(R.id.switcher1);
switcher1.setText(temp);
switcher1.beginScroll();

唉,我认为我真是懒....

还是直接给project吧!

源代码

版权声明:本文博主原创文章。博客,未经同意不得转载。

ViewGroup可实现上下、各地跑马灯效果滚动的更多相关文章

  1. ListView 中的TextView实现跑马灯效果

    案例:怎么样在一个ListView中含有TextView的item中实现字母滚动呢.这个在一些特定的场合经常用得到.如下图,当焦点位于某个item的时候其内容就自动滚动显示 要实现这样的效果,废话不多 ...

  2. Android-TextView跑马灯效果

    要实现跑马灯还是比较简单的. 同时有几个需要注意的点,先上代码: public class MTView extends TextView { public MTView(Context contex ...

  3. TextView跑马灯效果

    转载:http://www.2cto.com/kf/201409/330658.html 一.只想让TextView显示一行,但是文字超过TextView的长度怎么办?在开头显示省略号 android ...

  4. Android_TextView之跑马灯效果

    对于android控件中的TextView,相信大家一定不陌生,在显示文本内容时十分方便.不过我在使用时遇到一个小问题,就是当文字交多时,如何为用户进行展示.今天就为大家介绍一种解决方案--跑马灯效果 ...

  5. android中实现跑马灯效果以及AutoCompleteTestView与MultiAutoCompleteTextView的学习

    跑马灯效果 1.用过属性的方式实现跑马灯效果 属性:                  android:singleLine="true" 这个属性是设置TextView文本中文字 ...

  6. Android 实现多行文本跑马灯效果

    Android TextView 实现跑马灯的效果很简单,只要加三个属性就可以了. android:ellipsize="marquee" android:focusable=&q ...

  7. android:ellipsize实现跑马灯效果总结(转)

      最近无意间看到了涉及到跑马灯效果的代码,于是在网上查阅了很多资料,在这里对自己看的一些文章进行一下总结,顺便加上自己的一些体会. 让我们一步步逐渐向下. 首先我们要实现走马灯这样一个效果,通常来说 ...

  8. flex 简单跑马灯效果(竖着显示)

    <mx:Move id="move_area" target="{VBox_AreaWarning}"/> //move效果,模拟跑马灯 <s ...

  9. Dom操作--跑马灯效果

    这里给园友们演示的是Dom操作实现跑马灯效果,相信我们很多人都用Winform实现过跑马灯效果,其中的关键就是Tirm控件,那么在Dom操作中是用setInterval方法来实现隔一段时间执行一段代码 ...

随机推荐

  1. 【第四篇章-android平台MediaCodec】推断是否支持硬件解码码

    public boolean isSupportMediaCodecHardDecoder(){ boolean isHardcode = false; //读取系统配置文件/system/etc/m ...

  2. Windows Phone开发(38):动画之PointAnimation

    原文:Windows Phone开发(38):动画之PointAnimation PointAnimation也是很简单的,与前面说到的两个Animation是差不多的,属性也是一样的,如By.Fro ...

  3. hdu - 4975 - A simple Gaussian elimination problem.(最大流量)

    意甲冠军:要在N好M行和列以及列的数字矩阵和,每个元件的尺寸不超过9,询问是否有这样的矩阵,是独一无二的N(1 ≤ N ≤ 500) , M(1 ≤ M ≤ 500). 主题链接:http://acm ...

  4. 状态压缩dp入门

    poj1321 http://poj.org/problem?id=1321 我们可以把棋盘的每一行看做是一个状态,如果某一列放置了棋子,那么就标记为1,否则就标记为0.然后把它看成是一个二进制数,然 ...

  5. cocos2d-x笔记(十一)Lua发展飞机战争-5- 让飞机动

    然后在飞机上已被添加到游戏,下一步是让它动起来.主要是为了应对触摸事件. 在C++通过重写ccTouchBegan().ccTouchMoved().ccTouchEnded()三个函数来响应触摸事件 ...

  6. Effective C++规定45 额外的代码

    这部分是额外的代码博客,关键45术语思想已经实现. #include<iostream> using namespace std; template<typename T> c ...

  7. 凝视条件推断浏览器&lt;!--[if !IE]&gt;&lt;!--[if IE]&gt;&lt;!--[if lt IE 6]&gt;&lt;!--[if gte IE 6]&gt;

    <!--[if !IE]><!--> 除IE外可识别 <!--<![endif]--> <!--[if IE]> 所有的IE可识别 <![e ...

  8. 使用Ratpack和Spring Boot打造高性能的JVM微服务应用

    使用Ratpack和Spring Boot打造高性能的JVM微服务应用 这是我为InfoQ翻译的文章,原文地址:Build High Performance JVM Microservices wit ...

  9. DP:树DP

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  10. SCM文章10课时:定时器中断

    JP3遇见P0口. #include<reg51.h> #define uchar unsigned char uchar flag,num; uchar code smg[10] = { ...