Android:TextView的垂直滚动效果和上下滚动效果,原生动画实现
2017-01-19 16:04
1031 查看
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(); } /*** d89f * 重新设置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日
相关文章推荐
- Gifski:一个跨平台的高质量 GIF 编码器
- 模仿动画的放大缩小容器
- jQuery实现边框动态效果的实例代码
- jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween
- Android实现定制返回按钮动画效果的方法
- Dialog底部弹出自定义view并且伴随动画弹出和消失
- Android的TextView与Html相结合的具体方法
- Android中ViewFlipper的使用及设置动画效果实例详解
- Android中实现为TextView添加多个可点击的文本
- monkeyrunner之安卓开发环境搭建教程(1)
- jQuery实现美观的多级动画效果菜单代码
- php结合安卓客户端实现查询交互实例
- php判断GIF图片是否为动画的方法
- Android设置TextView首行缩进示例代码
- JQuery中解决重复动画的方法
- jQuery实现动画效果circle实例
- HTML5游戏引擎LTweenLite实现的超帅动画效果(附demo源码下载)
- Vuejs第七篇之Vuejs过渡动画案例全面解析
- 浅析JavaScript动画
- js排序动画模拟-插入排序