首先看看效果图(录制的gif有点卡,真实的效果还是很流畅的)
实现思路
通过上面的gif图可以得出结论,其实它就是同时绘制两条文本信息,然后通过动画不断的改变两条文本信息距离顶部的高度,以此来实现滚动的效果。
具体实现
首先定义一些要用到的属性
<declare-styleable name="MarqueeViewStyle"> <attr name="textSize" format="dimension" /> <attr name="textColor" format="color" /> <attr name="paddingLeft" format="dimension" /> <attr name="paddingTop" format="dimension" /> <attr name="paddingBottom" format="dimension" /> <attr name="paddingTopBottom" format="dimension"/> <attr name="startDelayTime" format="integer"/> 动画开始延迟时间 <attr name="reRepeatDelayTime" format="integer"/> 动画重复延迟时间 <attr name="itemAnimationTime" format="integer"/> 单个动画的执行时间 </declare-styleable>
接下来解析属性值
private void init(Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MarqueeViewStyle); mTextColor = typedArray.getColor(R.styleable.MarqueeViewStyle_textColor, Color.BLACK); mTextSize = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_textSize, 45); mPaddingLeft = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingLeft, 15); mPaddingTop = mPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingTopBottom, 25); mPaddingTop = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingTop, mPaddingTop); mPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingBottom, mPaddingBottom); itemAnimationTime = typedArray.getInteger(R.styleable.MarqueeViewStyle_itemAnimathtml" target="_blank">ionTime, 1000); reRepeatDelayTime = typedArray.getInteger(R.styleable.MarqueeViewStyle_reRepeatDelayTime, 1000); startDelayTime = typedArray.getInteger(R.styleable.MarqueeViewStyle_startDelayTime, 500); typedArray.recycle(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setTextSize(mTextSize); mPaint.setColor(mTextColor); mPaint.setTextAlign(Paint.Align.LEFT);}
重写onMeasure方法
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if(mTextArray == null || mTextArray.length == 0) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } else { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); ViewGroup.LayoutParams lp = getLayoutParams(); setMeasuredDimension(getViewWidth(lp, width), getViewHeight(lp, height)); } }
数据为空时调用父类的方法,设置数据以后根据不同的布局计算宽高。
设置数据
public void setTextArray(String[] textArray) { if(textArray == null || textArray.length <= 1) return; mTextArray = textArray; initTextRect(); setTextCurrentOrNextStatus(0, 1, true); startAnimation();}
initTextRect()方法是计算出单个文本的高度和数组中最大文本的宽度,文本的高度用来计算绘制文本时的位置,文本的最大宽度在onMeasure()方法的时候会用到。
setTextCurrentOrNextStatus()方法设置当前的position,文本以及下一个position,文本。还有文本距离顶部的初始化高度。
startAnimation() 方法 开始执行动画。
动画实现
private void startAnimation() { va = ValueAnimator.ofFloat(0, 1); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mProgress = (float) animation.getAnimatedValue(); . int moveOffset = (int) (mTextMoveOffset * mProgress); mCurrentTextMoveMarginTop = mCurrentTextInitMarginTop - moveOffset; mNextTextMoveMarginTop = mNextTextInitMarginTop - moveOffset; postInvalidate(); } }); va.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationRepeat(Animator animation) { va.pause(); setTextCurrentOrNextStatus(mNextTextPosition, mNextTextPosition + 1, false); handler.postDelayed(new Runnable() { @Override public void run() { va.resume(); } }, reRepeatDelayTime); } }); va.setRepeatCount(-1); va.setDuration(itemAnimationTime); va.setStartDelay(startDelayTime); va.start(); }
va.setRepeatCount(-1); 设置动画无限重复
onAnimationUpdate() 方法得到动画执行的进度,计算出text距离顶部的距离,调用postInvalidate()方法刷新界面。
onAnimationRepeat() 方法,通过handler延迟reRepeatDelayTime时间,再重新执行动画。
绘制
protected void onDraw(Canvas canvas) { if(mTextArray == null || mTextArray.length == 0) { super.onDraw(canvas); } else { canvas.drawText(mCurrentText, mPaddingLeft, mCurrentTextMoveMarginTop, mPaint); canvas.drawText(mNextText, mPaddingLeft, mNextTextMoveMarginTop, mPaint); } }
总结
到这里所有的代码已经分析完毕,其实实现这个效果还有很多种方法,通过继承ViewGroup等等都可以实现,大家有兴趣可以自己尝试。希望本文的内容对大家的学习或者工作能有所帮助,如果有疑问大家可以留言交流。
本文向大家介绍Android自定义View实现竖直跑马灯效果案例解析,包括了Android自定义View实现竖直跑马灯效果案例解析的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android实现竖直跑马灯效果的具体代码,供大家参考,具体内容如下 首先给出跑马灯效果图 中间的色块是因为视频转成GIF造成的失真,自动忽略哈。 大家知道,横向的跑马灯android自带的TextView就
本文向大家介绍Android自定义图文跑马灯效果,包括了Android自定义图文跑马灯效果的使用技巧和注意事项,需要的朋友参考一下 之前的需求是用FlipperView来实现上下翻动效果,但是发现数据有点长会造成一屏幕放不下三条数据,后来改为跑马灯,但是只有文字的跑马灯TextView自己就有,但是要求文字后面带一个小图标怎们办呢? (1).MainActivity.java: (2).fragm
本文向大家介绍Android自定义跑马灯文字效果,包括了Android自定义跑马灯文字效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android自定义跑马灯文字的具体代码,供大家参考,具体内容如下 Android 跑马灯效果文字: 效果图(真实动画很流畅,这个转gif有问题,感觉有点卡): 代码: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
本文向大家介绍Android实现垂直跑马灯效果,包括了Android实现垂直跑马灯效果的使用技巧和注意事项,需要的朋友参考一下 在我们开发过程中,跑马灯这个功能非常实用的,在实现这个功能的时候,这个时候我们通常需要找demo来实现这个方法,我从github上面找到这个demo感觉很好用,所以就要实现了这个功能喽MarqueeView,看这个工具类,因为我找这个类的时候是没有点击事件的,所以我给它加
本文向大家介绍android使用TextView实现跑马灯效果,包括了android使用TextView实现跑马灯效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了android使用TextView实现跑马灯效果的具体代码,供大家参考,具体内容如下 先上效果图:此为静态图,实际动态中文字匀速向左滑动。 实现步骤: 第一步:创建好布局页面 第二步:在activity中编写java代
本文向大家介绍Android TextView跑马灯效果实现方法,包括了Android TextView跑马灯效果实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android TextView跑马灯效果实现方法。分享给大家供大家参考,具体如下: 在xml文件中: 更多关于Android控件相关内容感兴趣的读者可查看本站专题:《Android控件用法总结》 希望本文所述对大家And