跑马灯效果

来源:互联网 发布:网络大学有哪些 编辑:程序博客网 时间:2024/05/22 06:29

一句话概括,平移再画一次。





Textview 默认就支持跑马灯效果,但需要设置一些东西,满足一些条件。

但我想知道它的原理。

看这效果,就是平滑移动 Textview 的内容,这不就是 mScrollX 干的吗,结合 ValueAnimator 很容易就实现了。

难点在于,把文字的头部重新从右边开始画出来。


width 代表 Textview 的实际宽度。

lineWidth 代表文字宽度,比如 “ABCD” 的宽度。

gap 代表文字头部和尾部的间隙,默认为 width/3。

mGhostStart ,幽灵的起始位置?


当 Textview 平移了 mGhostStart 后,正好展示完 gap 的最后一像素。

在下一帧,就需要重新绘制文字头部了。

canvas.translate(mMaxScroll, 0.0f);getLayout().draw(canvas, null, null, 0);


mMaxScroll = lineWidth + gap 

canvas 平移这段距离,就像是重新又从 A 开始绘画了。

知道原理后,用什么类实现都可以,改变 gap,改变速度,改变方向,垂直跑马灯等等。

canvas 真的是爹。


代码:

public class MyTextView extends TextView {    public MyTextView(Context context) {        super(context);    }    public MyTextView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    //    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.save();        if (isRunning() && shouldDrawGhost()) {            // 平移重画            canvas.translate(mMaxScroll, 0.0f);            getLayout().draw(canvas, null, null, 0);        }        canvas.restore();    }    // 跑马中    boolean running = false;    public boolean isRunning() {        return running;    }    // 该画幽灵部分了    boolean shouldDrawGhost() {        return isRunning() && getScrollX() > mGhostStart;    }    private float mMaxScroll;    private float mGhostStart;    public void start() {        running = true;        final int textWidth = getWidth();        final float lineWidth = getLayout().getLineWidth(0);        final float gap = textWidth / 3.0f;        mGhostStart = lineWidth - textWidth + gap;        mMaxScroll = lineWidth + gap;        ValueAnimator animator = ValueAnimator.ofFloat(0, mMaxScroll);        animator.setDuration(5000);        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                float f = (Float) animation.getAnimatedValue();                setScrollX((int) f);                if (1 == animation.getAnimatedFraction()) {                    running = false;                }            }        });        animator.start();    }}






0 0
原创粉丝点击