纵向滚动的TextView

本文介绍了一个名为VerticalScrollTextView的自定义View,用于实现文本的纵向滚动效果。该类继承自View,包含滚动速度、时间间隔、滚动时间和停顿时间等属性,并提供了设置列表、获取当前选中下标、绘制文字、滚动逻辑等相关方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 纵向滚动的TextView
 *
 * Created by Liu Jianping
 *
 * @date : 16/6/8.
 */
public class VerticalScrollTextView extends View{

    private List<String> list;

    /**
     * 每次向上移动的偏移量
     */
    private int speed = 5;

    /**
     * 每滑动一个偏移量的时间间隔
     */
    private int interval;

    /**
     * 滚动时间
     */
    private int scrollTime = 1000;

    /**
     * 停顿的时间
     */
    private int delayTime = 3000;

    /**
     * 滑动停止后的字符的Y坐标
     */
    private int fromY;

    /**
     * 记录text1, text2 的Y坐标
     */
    private int currY1, currY2;

    /**
     * 用来记录正在滑的两个字符
     */
    private String text1, text2;

    /**
     * 字符颜色
     */
    private int textColor = Color.BLACK;

    private float textSize = 30;

    private Paint paint = new Paint();

    /**
     * 当前选中是哪一个字符,text1
     */
    private int currIndex = -1;

    /**
     * 控件的高度
     */
    private int height;

    /**
     *  是否停止滑动,用来防止退出界面的时候线程还在继续执行
     */
    private boolean stop;

    public VerticalScrollTextView(Context context, List<String> list) {
        super(context);
        this.list = list;

        paint.setColor(textColor);
        paint.setTextSize(textSize);

        start();
    }

    public VerticalScrollTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
    }

    public void setList(List<String> list) {
        this.list = list;
        start();
    }

    /**
     * 获取当前选中的下标
     * @return
     */
    public int getCurrIndex()
    {
        if (currIndex == 0)
        {
            return 0;
        }
        return (currIndex + 1) % list.size();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (text1 == null || text2 == null)
        {
            return;
        }
        //画第一字符
        canvas.drawText(text1, 0, currY1, paint);

        canvas.drawText(text2, 0, currY2, paint);
    }

    /**
     * 获取文字的高度
     *
     * @return
     */
    private int getTextHeight(String text) {
        Rect rect = new Rect();
        //获取文字的边界值
        paint.getTextBounds(text, 0, text.length(), rect);
        //文字的高度等于(底-高)
        return rect.bottom - rect.top;
    }

    /**
     * 开始
     */
    private void start()
    {
        //在构造方法里直接调用getHeight是0,所以必须要等测量结束后再获取
        post(new Runnable() {
            @Override
            public void run() {
                //获取控件的高度
                height = getHeight();

                //要偏移多少次?
                int count = height / speed;

                //我要在一秒钟之内完成,计算每一次偏次的时间间隔
                interval = scrollTime / count;

                prepareScroll();
            }
        });
    }

    /**
     * 准备滚动
     */
    private void prepareScroll()
    {
        currIndex++;

        int index1 = currIndex % list.size();
        int index2 = (index1 + 1) % list.size();

        text1 = list.get(index1);
        text2 = list.get(index2);

        fromY = height - (height - getTextHeight(text1)) / 2;

        //重置Y坐标
        currY1 = fromY;
        currY2 = currY1 + height;

        scroll();
    }

    /**
     *  滚动
     */
    private void scroll()
    {
        if (stop)
        {
            return;
        }
        //开始变更Y坐标
        currY1 -= speed;
        currY2 = currY1 + height;

        //重绘一次
        invalidate();
        //是暂停还是继续滚?
        if (needPause())
        {
            pause();
        }
        else
        {
            goOnScroll();
        }
    }

    /**
     * 是否需要停止 ?
     *
     * @return
     */
    private boolean needPause() {

        return currY2 <= fromY;
    }

    /**
     * 继续滚动
     */
    private void goOnScroll()
    {
        //隔一个时间片再进行下一次滑动
        postDelayed(new Runnable() {
            @Override
            public void run() {
                scroll();
            }
        }, interval);
    }

    /**
     * 暂停滚动
     */
    private void pause()
    {
        //停留三秒准备下一次滚动
        postDelayed(new Runnable() {
            @Override
            public void run() {
                prepareScroll();
            }
        }, delayTime);
    }

    /**
     * 在控件脱离窗口的时候会调用这个方法
     */
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        stop = true;
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值