Android:TextView的垂直滚动效果和上下滚动效果,原生动画实现
1 效果图啥也不多说,看效果图,2 实现原理A利用平移动画TranslateAnimation完成动画向上向下平移B得到控件的LayoutParams设置控件的宽高、Margins(设置TextView的宽高为最外部容器的宽高)3 附源码代码中提供方法setCurText 设置当前的文字,无动画,upText显示上升动画,downText显示下降动画,更多的功能
·
1 效果图
啥也不多说,看效果图,
2 实现原理
A利用平移动画TranslateAnimation完成动画向上向下平移
B得到控件的LayoutParams设置控件的宽高、Margins(设置TextView的宽高为最外部容器的宽高)
3 附源码
代码中提供方法setCurText 设置当前的文字,无动画,upText显示上升动画,downText显示下降动画,更多的功能(设置字体大小、字体样式)请自行添加
package com.odds.odds.start;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;
public class UpDownTextView extends LinearLayout {
private Context mContext;
private TextView textViewTop, textViewCenter, textViewBottom;
private LinearLayout llayout;
private String curText = null;
private int mHeight = 0;
public UpDownTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initViews();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mHeight = h;
textViewTop = addText();
textViewCenter = addText();
textViewBottom = addText();
resizeLL();
}
private void initViews() {
llayout = new LinearLayout(mContext);
llayout.setOrientation(LinearLayout.VERTICAL);
this.addView(llayout);
}
private void resizeLL() {
LayoutParams lp2 = (LayoutParams) llayout.getLayoutParams();
lp2.height = mHeight * (llayout.getChildCount());
lp2.setMargins(0, -mHeight, 0, 0);// 使向上偏移一定的高度,用padding,scrollTo都分有问题
llayout.setLayoutParams(lp2);
}
private TextView addText() {
TextView tv = new TextView(mContext);
tv.setGravity(Gravity.CENTER);
tv.setTextSize(22);
llayout.addView(tv);
LayoutParams lp = (LayoutParams) tv.getLayoutParams();
lp.height = mHeight;
lp.width = getWidth();
tv.setLayoutParams(lp);
return tv;
}
/***
* 设置初始的字
*
* @param curText
*/
public void setCurText(String curText) {
this.curText = curText;
textViewCenter.setText(curText);
}
/***
* 向上弹动画
*
* @param curText
*/
public void upText(String curText) {
this.curText = curText;
textViewBottom.setText(curText);
up();// 向上的动画
}
public void downText(String curText) {
this.curText = curText;
textViewTop.setText(curText);
down();// 向上的动画
}
/***
* 向上动画
*/
private void up() {
llayout.clearAnimation();
TranslateAnimation animation = new TranslateAnimation(0, 0, 0, -mHeight);
animation.setDuration(1500);
llayout.startAnimation(animation);
animation.setAnimationListener(listener);
}
/***
* 向下动画
*/
public void down() {
llayout.clearAnimation();
TranslateAnimation animation = new TranslateAnimation(0, 0, 0, mHeight);
animation.setDuration(1500);
llayout.startAnimation(animation);
animation.setAnimationListener(listener);
}
/***
* 动画监听,动画完成后,动画恢复,设置文本
*/
private AnimationListener listener = new AnimationListener() {
@Override
public void onAnimationStart(Animation arg0) {
}
@Override
public void onAnimationRepeat(Animation arg0) {
}
@Override
public void onAnimationEnd(Animation arg0) {
setCurText(curText);
}
};
}
2016年1月19日
4 改进版
package com.odds.odds.view;
import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;
public class UpDownTextView extends LinearLayout {
private Context mContext;
private TextView textViews[] = new TextView[3];
private LinearLayout llayout;
private String curText = null;
private int mHeight = 0;
private int mDuring=500;
public UpDownTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initViews();
}
private void initViews() {
llayout = new LinearLayout(mContext);
llayout.setOrientation(LinearLayout.VERTICAL);
this.addView(llayout);
textViews[0] = addText();
textViews[1] = addText();
textViews[2] = addText();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mHeight = h;
setViewsHeight();//
}
private void setViewsHeight() {
for (TextView tv : textViews) {
LayoutParams lp = (LayoutParams) tv.getLayoutParams();
lp.height = mHeight;
lp.width = getWidth();
tv.setLayoutParams(lp);
}
LayoutParams lp2 = (LayoutParams) llayout.getLayoutParams();
lp2.height = mHeight * (llayout.getChildCount());
lp2.setMargins(0, -mHeight, 0, 0);// 使向上偏移一定的高度,用padding,scrollTo都分有问题
llayout.setLayoutParams(lp2);
}
public void setGravity(int graty) {
for (TextView tv : textViews) {
tv.setGravity(graty);
}
}
public void setTextSize(int dpSize) {
for (TextView tv : textViews) {
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dpSize);
}
}
public void setTextColor(int color) {
for (TextView tv : textViews) {
tv.setTextColor(color);
}
}
private TextView addText() {
TextView tv = new TextView(mContext);
tv.setGravity(Gravity.CENTER_VERTICAL);
llayout.addView(tv);
return tv;
}
/***
* 设置初始的字
*
* @param curText
*/
public void setText(String curText) {
this.curText = curText;
textViews[1].setText(curText);
}
/***
* 向上弹动画
*
* @param curText
*/
public void setTextUpAnim(String text) {
this.curText = text;
textViews[2].setText(text);
up();// 向上的动画
}
public void setTextDownAnim(String text) {
this.curText = text;
textViews[0].setText(text);
down();// 向上的动画
}
public void setDuring(int during){
this.mDuring=during;
}
/***
* 向上动画
*/
private void up() {
llayout.clearAnimation();
TranslateAnimation animation = new TranslateAnimation(0, 0, 0, -mHeight);
animation.setDuration(mDuring);
llayout.startAnimation(animation);
animation.setAnimationListener(listener);
}
/***
* 向下动画
*/
public void down() {
llayout.clearAnimation();
TranslateAnimation animation = new TranslateAnimation(0, 0, 0, mHeight);
animation.setDuration(mDuring);
llayout.startAnimation(animation);
animation.setAnimationListener(listener);
}
/***
* 动画监听,动画完成后,动画恢复,设置文本
*/
private AnimationListener listener = new AnimationListener() {
@Override
public void onAnimationStart(Animation arg0) {
}
@Override
public void onAnimationRepeat(Animation arg0) {
}
@Override
public void onAnimationEnd(Animation arg0) {
setText(curText);
}
};
}
2016年1月20日
5 改进第二版
package com.example.testt;
import java.util.List;
import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;
public class UpDownTextView extends LinearLayout {
private Context mContext;
private TextView textViews[] = new TextView[3];
private LinearLayout llayout;
private String curText = null;
/***
* 动画时间
*/
private int mAnimTime = 500;
/**
* 停留时间
*/
private int mStillTime = 500;
/***
* 轮播的string
*/
private List<String> mTextList;
/***
* 当前轮播的索引
*/
private int currentIndex = 0;
/***
* 动画模式
*/
private int animMode = 0;// 默认向上 0--向上,1--向下
public final static int ANIM_MODE_UP = 0;
public final static int ANIM_MODE_DOWN = 1;
private TranslateAnimation animationDown, animationUp;
public UpDownTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initViews();
}
private void initViews() {
llayout = new LinearLayout(mContext);
llayout.setOrientation(LinearLayout.VERTICAL);
this.addView(llayout);
textViews[0] = addText();
textViews[1] = addText();
textViews[2] = addText();
}
/***
* 当界面销毁时
*/
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
stopAutoScroll();// 防止内存泄漏的操作
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setViewsHeight();
}
/***
* 重新设置VIEW的高度
*/
private void setViewsHeight() {
for (TextView tv : textViews) {
LayoutParams lp = (LayoutParams) tv.getLayoutParams();
lp.height = getHeight();
lp.width = getWidth();
tv.setLayoutParams(lp);
}
LayoutParams lp2 = (LayoutParams) llayout.getLayoutParams();
lp2.height = getHeight() * (llayout.getChildCount());
lp2.setMargins(0, -getHeight(), 0, 0);// 使向上偏移一定的高度,用padding,scrollTo都分有问题
llayout.setLayoutParams(lp2);
}
// /以下是一些基本的方法textView要用到///
public void setGravity(int graty) {
for (TextView tv : textViews) {
tv.setGravity(graty);
}
}
public void setTextSize(int dpSize) {
for (TextView tv : textViews) {
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dpSize);
}
}
public void setTextColor(int color) {
for (TextView tv : textViews) {
tv.setTextColor(color);
}
}
private TextView addText() {
TextView tv = new TextView(mContext);
tv.setGravity(Gravity.CENTER_VERTICAL);
llayout.addView(tv);
return tv;
}
/***
* 设置初始的字
*
* @param curText
*/
public void setText(String curText) {
this.curText = curText;
textViews[1].setText(curText);
}
/***
* 开始自动滚动
*/
public void startAutoScroll() {
if (mTextList == null || mTextList.size() == 0) {
return;
}
// 先停止
stopAutoScroll();
this.postDelayed(runnable, mStillTime);// 可用runnable来代替hander或者 timer
}
/***
* 停止自动滚动
*/
public void stopAutoScroll() {
this.removeCallbacks(runnable);
}
private Runnable runnable = new Runnable() {
@Override
public void run() {
currentIndex = (currentIndex) % mTextList.size();
switch (animMode) {
case ANIM_MODE_UP:
setTextUpAnim(mTextList.get(currentIndex));
break;
case ANIM_MODE_DOWN:
setTextDownAnim(mTextList.get(currentIndex));
break;
}
currentIndex++;
UpDownTextView.this.postDelayed(runnable, mStillTime + mAnimTime);
}
};
/***
* 向上弹动画
*
* @param curText
*/
public void setTextUpAnim(String text) {
this.curText = text;
textViews[2].setText(text);
up();// 向上的动画
}
public void setTextDownAnim(String text) {
this.curText = text;
textViews[0].setText(text);
down();// 向上的动画
}
public void setDuring(int during) {
this.mAnimTime = during;
}
/***
* 向上动画
*/
private void up() {
llayout.clearAnimation();
if (animationUp == null)
animationUp = new TranslateAnimation(0, 0, 0, -getHeight());
animationUp.setDuration(mAnimTime);
llayout.startAnimation(animationUp);
animationUp.setAnimationListener(listener);
}
/***
* 向下动画
*/
public void down() {
llayout.clearAnimation();
if (animationDown == null)
animationDown = new TranslateAnimation(0, 0, 0, getHeight());
animationDown.setDuration(mAnimTime);
llayout.startAnimation(animationDown);
animationDown.setAnimationListener(listener);
}
/***
* 动画监听,动画完成后,动画恢复,设置文本
*/
private AnimationListener listener = new AnimationListener() {
@Override
public void onAnimationStart(Animation arg0) {
}
@Override
public void onAnimationRepeat(Animation arg0) {
}
@Override
public void onAnimationEnd(Animation arg0) {
setText(curText);
}
};
public int getAnimTime() {
return mAnimTime;
}
public void setAnimTime(int mAnimTime) {
this.mAnimTime = mAnimTime;
}
public int getStillTime() {
return mStillTime;
}
public void setStillTime(int mStillTime) {
this.mStillTime = mStillTime;
}
public List<String> getTextList() {
return mTextList;
}
public void setTextList(List<String> mTextList) {
this.mTextList = mTextList;
}
public int getCurrentIndex() {
return currentIndex;
}
public void setCurrentIndex(int currentIndex) {
this.currentIndex = currentIndex;
}
public int getAnimMode() {
return animMode;
}
public void setAnimMode(int animMode) {
this.animMode = animMode;
}
}
6 修正bug版
经测试在7.0系统下无法正常显示,所以作了一点点修正
当onsizeChanged 时,需要延时处理才能设置高度,加上post后面做要做的事即可
package com.caiyu.qqsd.lib.widget;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.caiyu.qqsd.common.interfaceImpl.AnimationListenerImpl;
import java.util.List;
/**
* 上下滚动的TEXTVIEW
* Created by liugd on 2017/3/20.
*/
public class UpDownTextView extends LinearLayout {
private Context mContext;
private TextView textViews[] = new TextView[3];
private LinearLayout llayout;
private String curText = null;
/***
* 动画时间
*/
private int mAnimTime = 500;
/**
* 停留时间
*/
private int mStillTime = 3500;
/***
* 轮播的string
*/
private List<String> mTextList;
/***
* 当前轮播的索引
*/
private int currentIndex = 0;
/***
* 动画模式
*/
private int animMode = 0;// 默认向上 0--向上,1--向下
/***
* 是否正在自动滚动
*/
private boolean isRunning = false;
public final static int ANIM_MODE_UP = 0;
public final static int ANIM_MODE_DOWN = 1;
private TranslateAnimation animationDown, animationUp;
public UpDownTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
if (!isInEditMode())
initViews();
}
private void initViews() {
llayout = new LinearLayout(mContext);
llayout.setOrientation(LinearLayout.VERTICAL);
this.addView(llayout);
textViews[0] = addText();
textViews[1] = addText();
textViews[2] = addText();
}
/***
* 当界面销毁时
*/
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
stopAutoScroll();// 防止内存泄漏的操作
// LogUitls.print("滚动文本","界面销毁移动handler");
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (!isInEditMode()) {
post(new Runnable() {//7.0以后,需要界面可见时,设置宽高才有效果
@Override
public void run() {
setViewsHeight();
}
});
}
}
/***
* 重新设置VIEW的高度
*/
private void setViewsHeight() {
for (TextView tv : textViews) {
LayoutParams lp = (LayoutParams) tv.getLayoutParams();
lp.height = getHeight();
lp.width = getWidth();
tv.setLayoutParams(lp);
}
LayoutParams lp2 = (LayoutParams) llayout.getLayoutParams();
lp2.height = getHeight() * (llayout.getChildCount());
lp2.setMargins(0, -getHeight(), 0, 0);// 使向上偏移一定的高度,用padding,scrollTo都分有问题
llayout.setLayoutParams(lp2);
}
// /以下是一些基本的方法textView要用到///
public void setGravity(int graty) {
for (TextView tv : textViews) {
tv.setGravity(graty);
}
}
public void setTextSize(int dpSize) {
for (TextView tv : textViews) {
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dpSize);
}
}
public void setTextColor(int color) {
for (TextView tv : textViews) {
tv.setTextColor(color);
}
}
private TextView addText() {
TextView tv = new TextView(mContext);
tv.setGravity(Gravity.CENTER_VERTICAL);
llayout.addView(tv);
return tv;
}
/***
* 设置初始的字
*
* @param curText
*/
public void setText(String curText) {
this.curText = curText;
textViews[1].setText(curText);
}
/***
* 开始自动滚动
*/
public void startAutoScroll() {
if (!isRunning) {
isRunning = true;
if (mTextList == null || mTextList.size() == 0) {
stopAutoScroll();
return;
}
this.postDelayed(runnable, mStillTime + mAnimTime);// 可用runnable来代替hander或者 timer
}
}
/***
* 停止自动滚动
*/
public void stopAutoScroll() {
if (isRunning) {
isRunning = false;
this.removeCallbacks(runnable);
}
}
private Runnable runnable = new Runnable() {
@Override
public void run() {
currentIndex++;
currentIndex = (currentIndex) % mTextList.size();
switch (animMode) {
case ANIM_MODE_UP:
setTextUpAnim(mTextList.get(currentIndex));
break;
case ANIM_MODE_DOWN:
setTextDownAnim(mTextList.get(currentIndex));
break;
}
UpDownTextView.this.postDelayed(runnable, mStillTime + mAnimTime);
if (onTextScrollListener != null) {
onTextScrollListener.onTextScroll();
}
// LogUitls.print("滚动文本", "界面滚动");
}
};
/***
* 向上弹动画
*
* @param curText
*/
public void setTextUpAnim(String curText) {
this.curText = curText;
textViews[2].setText(curText);
up();// 向上的动画
}
public void setTextDownAnim(String text) {
this.curText = text;
textViews[0].setText(text);
down();// 向上的动画
}
public void setDuring(int during) {
this.mAnimTime = during;
}
/***
* 向上动画
*/
private void up() {
llayout.clearAnimation();
if (animationUp == null)
animationUp = new TranslateAnimation(0, 0, 0, -getHeight());
animationUp.setDuration(mAnimTime);
llayout.startAnimation(animationUp);
animationUp.setAnimationListener(listener);
}
/***
* 向下动画
*/
public void down() {
llayout.clearAnimation();
if (animationDown == null)
animationDown = new TranslateAnimation(0, 0, 0, getHeight());
animationDown.setDuration(mAnimTime);
llayout.startAnimation(animationDown);
animationDown.setAnimationListener(listener);
}
/***
* 动画监听,动画完成后,动画恢复,设置文本
*/
private AnimationListener listener = new AnimationListenerImpl() {
@Override
public void onAnimationEnd(Animation arg0) {
setText(curText);
}
};
public int getAnimTime() {
return mAnimTime;
}
public void setAnimTime(int mAnimTime) {
this.mAnimTime = mAnimTime;
}
public int getStillTime() {
return mStillTime;
}
public void setStillTime(int mStillTime) {
this.mStillTime = mStillTime;
}
public List<String> getTextList() {
return mTextList;
}
public void setTextList(List<String> mTextList) {
this.mTextList = mTextList;
}
public int getCurrentIndex() {
return currentIndex;
}
public void setCurrentIndex(int currentIndex) {
this.currentIndex = currentIndex;
}
public int getAnimMode() {
return animMode;
}
public void setAnimMode(int animMode) {
this.animMode = animMode;
}
public void setSingleLine() {
for (TextView tv : textViews) {
tv.setSingleLine();
tv.setEllipsize(TextUtils.TruncateAt.END);//尾部打省略号
}
}
OnTextScrollListener onTextScrollListener;
public void setOnTextScrollListener(OnTextScrollListener onTextScrollListener) {
this.onTextScrollListener = onTextScrollListener;
}
public interface OnTextScrollListener {
void onTextScroll();
}
}
调用方法
public void fun(){
final UpDownTextView textView = (UpDownTextView) findViewById(R.id.textView1);
final ArrayList<String> titleList = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
titleList.add(i + "");
}
textView.setTextList(titleList);
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
textView.startAutoScroll();
}
});
}
布局十分简单,我就不贴出来了
http://download.csdn.net/detail/u012990509/9786599 (左边下载地址),下载地址中的代码不是最新的,因CSDN限制不能更新,所以请以最后更新的为准
2017年8月31日
更多推荐
已为社区贡献1条内容
所有评论(0)