先上效果图:

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. hdu 5035 概率论

    n服务形式,各服务窗口等候时间指数公布,求所需的等待时间. 解: 相两点:首先,等到轮到他,然后就是送达时间. 潜伏期期望每个表单1/ki(1/ki,宣布预期指数公式).总的等待时间预期1/(求和ki ...

  2. lca转RMQ

    这个博客写得好 #include <stdio.h> #include <vector> #include <string.h> using namespace s ...

  3. muduo网络图书馆评测

    上个月看到朋友推荐mudo网络图书馆,该代码是在国内同行中,开源工程后.甚至钦佩.根据mudo手动和035代码的版本看起来正在建设中.感觉是一个比较成熟且易于使用的网络库.我的手也有自己的网络库,虽然 ...

  4. 异常Exception in thread "AWT-EventQueue-XX" java.lang.StackOverflowError

    今天太背了,bug不断,检查到最后都会发现自己脑残了,粗心写错,更悲剧的是写错的时候还不提示错. 刚才有遇到一个问题,抛了这个异常Exception in thread "AWT-Event ...

  5. Windows下一个AndroidStudio 正在使用Git(AndroidStudio工程GitHub关联)

    前提条件 : 1. 设备 Git client 下载链接 2. 有着 GitHub 账号 (假设你已经有了一些git基础, 假设还一点都不会, 请去找其它加成学习) AndroidStudio项目公布 ...

  6. ASP.NET Core 1.0 部署 HTTPS

    ASP.NET Core 1.0 部署 HTTPS ASP.NET Core 1.0 部署 HTTPS (.NET Framework 4.5.1) 提示 更新时间:2016年01月23日. 在目前介 ...

  7. 3Dmax+blend+WPF综合运用

    原文:3Dmax+blend+WPF综合运用 赛后总结 本人小菜,WPF刚入门,只是写一下最近的项目心得.欢迎各位前辈们前来拍砖指正,感激不敬!先申明,小弟我入门仓促,很多东西也是一知半解,所以很多问 ...

  8. 采用jqueryUI创建日期选择器

    该公司的项目使用的插件时间选择,百度很长一段时间.没有找到合适的,而且,他们在看了jqueryUI.自己变成一个更好的集成日期选择器.为了以后遇到相同的问题是可以解决. 以下就贴出部分使用的代码,比較 ...

  9. 【6】和作为连续序列s

    称号:输入一个整数s,并打印出所有s整数的连续序列(含有至少2的数量). 如输入9,输出2.3.4和4.5两个序列 方案一:因为序列至少要2个数,则两个数上限值为(1+s)/2,我们能够枚举该序列的起 ...

  10. 移动web:tab选项卡

    平常做移动端会用到tab选项卡,这和PC端有些区别,移动端是触摸滑动切换,PC端是点击.移入切换. 这里滑动切换就是一个移动端事件的应用,这里主要用到的触摸事件:touchstart.touchmov ...