ViewGroup可实现上下、各地跑马灯效果滚动
先上效果图:
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可实现上下、各地跑马灯效果滚动的更多相关文章
- ListView 中的TextView实现跑马灯效果
案例:怎么样在一个ListView中含有TextView的item中实现字母滚动呢.这个在一些特定的场合经常用得到.如下图,当焦点位于某个item的时候其内容就自动滚动显示 要实现这样的效果,废话不多 ...
- Android-TextView跑马灯效果
要实现跑马灯还是比较简单的. 同时有几个需要注意的点,先上代码: public class MTView extends TextView { public MTView(Context contex ...
- TextView跑马灯效果
转载:http://www.2cto.com/kf/201409/330658.html 一.只想让TextView显示一行,但是文字超过TextView的长度怎么办?在开头显示省略号 android ...
- Android_TextView之跑马灯效果
对于android控件中的TextView,相信大家一定不陌生,在显示文本内容时十分方便.不过我在使用时遇到一个小问题,就是当文字交多时,如何为用户进行展示.今天就为大家介绍一种解决方案--跑马灯效果 ...
- android中实现跑马灯效果以及AutoCompleteTestView与MultiAutoCompleteTextView的学习
跑马灯效果 1.用过属性的方式实现跑马灯效果 属性: android:singleLine="true" 这个属性是设置TextView文本中文字 ...
- Android 实现多行文本跑马灯效果
Android TextView 实现跑马灯的效果很简单,只要加三个属性就可以了. android:ellipsize="marquee" android:focusable=&q ...
- android:ellipsize实现跑马灯效果总结(转)
最近无意间看到了涉及到跑马灯效果的代码,于是在网上查阅了很多资料,在这里对自己看的一些文章进行一下总结,顺便加上自己的一些体会. 让我们一步步逐渐向下. 首先我们要实现走马灯这样一个效果,通常来说 ...
- flex 简单跑马灯效果(竖着显示)
<mx:Move id="move_area" target="{VBox_AreaWarning}"/> //move效果,模拟跑马灯 <s ...
- Dom操作--跑马灯效果
这里给园友们演示的是Dom操作实现跑马灯效果,相信我们很多人都用Winform实现过跑马灯效果,其中的关键就是Tirm控件,那么在Dom操作中是用setInterval方法来实现隔一段时间执行一段代码 ...
随机推荐
- hdu 5035 概率论
n服务形式,各服务窗口等候时间指数公布,求所需的等待时间. 解: 相两点:首先,等到轮到他,然后就是送达时间. 潜伏期期望每个表单1/ki(1/ki,宣布预期指数公式).总的等待时间预期1/(求和ki ...
- lca转RMQ
这个博客写得好 #include <stdio.h> #include <vector> #include <string.h> using namespace s ...
- muduo网络图书馆评测
上个月看到朋友推荐mudo网络图书馆,该代码是在国内同行中,开源工程后.甚至钦佩.根据mudo手动和035代码的版本看起来正在建设中.感觉是一个比较成熟且易于使用的网络库.我的手也有自己的网络库,虽然 ...
- 异常Exception in thread "AWT-EventQueue-XX" java.lang.StackOverflowError
今天太背了,bug不断,检查到最后都会发现自己脑残了,粗心写错,更悲剧的是写错的时候还不提示错. 刚才有遇到一个问题,抛了这个异常Exception in thread "AWT-Event ...
- Windows下一个AndroidStudio 正在使用Git(AndroidStudio工程GitHub关联)
前提条件 : 1. 设备 Git client 下载链接 2. 有着 GitHub 账号 (假设你已经有了一些git基础, 假设还一点都不会, 请去找其它加成学习) AndroidStudio项目公布 ...
- 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日. 在目前介 ...
- 3Dmax+blend+WPF综合运用
原文:3Dmax+blend+WPF综合运用 赛后总结 本人小菜,WPF刚入门,只是写一下最近的项目心得.欢迎各位前辈们前来拍砖指正,感激不敬!先申明,小弟我入门仓促,很多东西也是一知半解,所以很多问 ...
- 采用jqueryUI创建日期选择器
该公司的项目使用的插件时间选择,百度很长一段时间.没有找到合适的,而且,他们在看了jqueryUI.自己变成一个更好的集成日期选择器.为了以后遇到相同的问题是可以解决. 以下就贴出部分使用的代码,比較 ...
- 【6】和作为连续序列s
称号:输入一个整数s,并打印出所有s整数的连续序列(含有至少2的数量). 如输入9,输出2.3.4和4.5两个序列 方案一:因为序列至少要2个数,则两个数上限值为(1+s)/2,我们能够枚举该序列的起 ...
- 移动web:tab选项卡
平常做移动端会用到tab选项卡,这和PC端有些区别,移动端是触摸滑动切换,PC端是点击.移入切换. 这里滑动切换就是一个移动端事件的应用,这里主要用到的触摸事件:touchstart.touchmov ...