文字长度超过限制时水平滚动显示

本文介绍了如何在Android中创建一个水平滚动的TextView。通过继承TextView,添加Scroller,并覆盖computeScroll方法来实现文字超长时的水平滚动效果。同时,提供了布局文件中的用法示例和初始化及滚动操作步骤。

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

本文章由azibug编写,转载请注明出处,请勿用于商业用途
文章链接:
http://blog.youkuaiyun.com/owillll/article/details/8879896

作者:azibug    邮箱: azibug#163.com


原理:

1. 继承TextView并添加Scroller到TextView里面滚动条

2. 覆盖computeScroll方法并在Scroller滚动结束时重新开始滚动

3. TextView 的样式应该设置为单行和不需要ellipsize并且设置滚动为水平滚动


实例:

在layout中:

            <com.chaokuaidi.android.util.ScrollTextView
                android:ellipsize="marquee"
                android:gravity="center"
                android:id="@+id/textTitle"
                android:layout_height="wrap_content"
                android:scrollHorizontally="true"
                android:singleLine="true"
                android:marqueeRepeatLimit="marquee_forever"
                android:layout_width="250px"/>


水平滚动android实现ScrollTextView:

package com.chaokuaidi.android.util;

import android.content.Context;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.animation.LinearInterpolator;
import android.widget.Scroller;
import android.widget.TextView;

public class ScrollTextView extends TextView {

    // scrolling feature
    private Scroller mSlr;

    // milliseconds for a round of scrolling
    private int mRndDuration = 250;

    // the X offset when paused
    private int mXPaused = 0;

    // whether it's being paused
    private boolean mPaused = true;

    /*
     * constructor
     */
    public ScrollTextView(Context context) {
        this(context, null);
    }

    /*
     * constructor
     */
    public ScrollTextView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

    /*
     * constructor
     */
    public ScrollTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // customize the TextView
        setSingleLine();
        setEllipsize(null);
//        setVisibility(INVISIBLE);

        // use LinearInterpolator for steady scrolling
        mSlr = new Scroller(this.getContext(), new LinearInterpolator());
        // Do not know why it would not scroll sometimes
        // if setHorizontallyScrolling is called in constructor.
        setHorizontallyScrolling(true);
        setScroller(mSlr);
    }


    /**
     * calculate the scrolling length of the text in pixel
     *
     * @return the scrolling length in pixels
     */
    private int calculateScrollingLen() {
        TextPaint tp = getPaint();
        Rect rect = new Rect();
        String strTxt = getText().toString();
        tp.getTextBounds(strTxt, 0, strTxt.length(), rect);

        int scrollingLen = -1;
        if (rect.width() > -10 + getWidth())
            scrollingLen = rect.width() + getWidth();
        rect = null;
        return scrollingLen;
    }

    /**
     * begin to scroll the text from the original position
     */
    public void startScroll() {
        // begin from the very right side
        mXPaused = -1 * getWidth();
        // assume it's paused
        mPaused = true;
        resumeScroll();
    }

    /**
     * resume the scroll from the pausing point
     */
    public void resumeScroll() {

        if (!mPaused)
            return;

        int scrollingLen = calculateScrollingLen();
        if (scrollingLen > 0) {
            setGravity(3);
            int distance = scrollingLen - (getWidth() + mXPaused);
            int duration = (new Double(mRndDuration * distance * 1.00000
                    / scrollingLen)).intValue();
            // setVisibility(VISIBLE);
            mSlr.startScroll(mXPaused, 0, distance, 0, duration);
            mPaused = false;
        } else {
            reset();
        }
    }

    /**
     * pause scrolling the text
     */
    public void pauseScroll() {
        if (null == mSlr)
            return;

        if (!mPaused) {
            mPaused = true;

            // abortAnimation sets the current X to be the final X,
            // and sets isFinished to be true
            // so current position shall be saved
            mXPaused = mSlr.getCurrX();

            mSlr.abortAnimation();
        }
    }

    public void reset() {
        setGravity(17);
        this.mXPaused = 0;
        pauseScroll();
        this.mPaused = true;
    }

    @Override
        /*
         * override the computeScroll to restart scrolling when finished so as that
         * the text is scrolled forever
         */
    public void computeScroll() {
        super.computeScroll();

        if (null == mSlr) return;

        if (mSlr.isFinished() && (!mPaused)) {
            this.startScroll();
        }
    }

    public int getRndDuration() {
        return mRndDuration;
    }

    public void setRndDuration(int duration) {
        this.mRndDuration = duration;
    }

    public boolean isPaused() {
        return mPaused;
    }
}

可以根据某个宽度在不滚动是否显示文本而合理地取消setVisibility(INVISIBLE);的注释。


使用的时候很简单的两步:根据id初始化ScrollTextView控件并设置完整滚动完的时间,然后在适当的时候设置文本内容和开始滚动:

1.初始化

songName = (ScrollTextView)findViewById(R.id.textTitle);
        songName.setRndDuration(15000);  // 15秒


2. 设置内容和开始滚动:

songName.setText(title);
                    songName.startScroll();




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值