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方法来实现隔一段时间执行一段代码 ...
随机推荐
- Python学习入门基础教程(learning Python)--3.2 if-else分支语句
if-else分支语句结构的特点是当conditon条件满足时,执行if下的语句块,当condition条件不满足时执行else下的语句块,也就是说根据条件来控制让某些语句执行,某些语句不被执行. i ...
- c#为了实现自己的线程池功能(一)
线程池的技术背景 在面向对象编程中,创建和销毁对象是非常费时间的,由于创建一个对象要获取内存资源或者其他很多其他资源,所以提高服务程序效率的一个手段就是尽可能降低创建和销毁对象的次数.特别是一些非常耗 ...
- 上市ASCII 表省内发现!
表格来自,这里 扩展码表:
- WPF用SkewTransform画3D柱状图
WPF用SkewTransform画3D柱状图 SkewTransform主要是对控件实现一种2-D扭曲,具体内容可以查看以下链接: http://msdn.microsoft.com/zh-cn/l ...
- Cocos2d-x 3.2 大富翁游戏项目开发-第七部分 获取角色路径_1
以下是一些设计略显繁琐,有必要清除思维. 下一个主要的成就,当我们点击Gobutton后,得到一个随机数骰子,是走了几步,它是基于以下步骤行走路径的数目,然后移动位置的基于角色的路径. 流程如图普遍认 ...
- tb连续aaaaa123aaa自适应
在连续的字符串数字中,td不会自适应大小,需要加上样式 style="word-break : break-all; overflow:hidden; " <table> ...
- Jquery中使用setInterval和setTimeout 容易犯的低级错误
直接在ready中调用其他方法,会提示缺少对象的错误,解决方法如下: 方法1. 应用jQuery的扩展可以解决这个问题. $(document).ready(function(){ $.extend( ...
- sql语句中单引号嵌套问题
在sql语句中,我们难免会用到单引号嵌套的时候,但是直接嵌套肯定是不行的,java中用反斜杠做转义符也是不行的,在sql中是用单引号来做转义符的. 比如下面例子是存储过程里查询时的语句示例 exec ...
- iOS 删除黑色边框线导航栏&删除搜索框的阴影边界线和中黑色文本输入框 - 解
删除黑色边框线导航栏 in viewDidload: [self.navigationController.navigationBar setBackgroundImage:[[UIImage all ...
- android集成apk对一些问题经常遇到系统
1.集成APK必须确认是否release版本号,否则会导致CTS测试失败. 途径:反编译apk,视图manifest.xml文件,看<application>在那里debug属性:andr ...