Android 可以自定义速度的跑马灯效果

android:singleLine="true"  
android:ellipsize="marquee"
android:focusable="true" 

这三个属性就可以实现跑马灯的效果,但是这种做法只适用于一个TextView,如果想让两个以上的TextView跑起来就需要自定义TextView。

让两个以上的TextView以默认的滚动方式、滚动速度跑起来很简单,只需要在自定义TextView中重写isFocused方法,然后将返回值改为true,代码如下:

public class CarouselTextView extends TextView{

    public CarouselTextView(Context context) {
    super(context);
   }    

    public CarouselTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
   }

    public CarouselTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    }
  /**
 * 获取焦点,不重写不能滚动
 */
    @Override
    public boolean isFocused() {
        return true;
    }

布局如下:

 
      

其中android:marqueeRepeatLimit="marquee_forever" 这个属性是设置无限重复,如果不设置的话,默认会在3次之后停止不动了。
android.widget.TextView类里设置的属性如下:

private int mMarqueeRepeatLimit = 3;
/**
 * Sets how many times to repeat the marquee animation. Only applied if the
 * TextView has marquee enabled. Set to -1 to repeat indefinitely.
 *
 * @see #getMarqueeRepeatLimit()
 *
 * @attr ref android.R.styleable#TextView_marqueeRepeatLimit
 */
public void setMarqueeRepeatLimit(int marqueeLimit) {
    mMarqueeRepeatLimit = marqueeLimit;
}

下面再来说说自定义速度的跑马灯效果:

其实,跑马灯效果就是不断的滚动位置,而自定义速度的跑马灯就是以自定义的时间间隔去滚动位置,明白了这个思想之后,做起来就比较的简单了。

首先以自定义的时间间隔去滚动位置,就需要不断地执行滚动的操作,所以我们可以用一个线程来执行这个滚动的操作,这里用的方法是实现Runnable接口,重写run方法来实现的。

/**
 * 执行滚动
 */
@Override
public void run() {
    Log.d(TAG, "run");
    currentScrollX += speed;  // 滚动速度每次加几个点
    scrollTo(currentScrollX, 0); // 滚动到指定位置
    if(isStop){   
        return;
    }
    if(currentScrollX >= endX){   // 如果滚动的位置大于最大限度则滚动到初始位置
        scrollTo(firstScrollX, 0);
        currentScrollX = firstScrollX; // 初始化滚动速度
        postDelayed(this, SCROLL_DELAYED);  // SCROLL_DELAYED毫秒之后重新滚动
    }else {
        postDelayed(this, delayed);  // delayed毫秒之后再滚动到指定位置
    }
    
}

其次,在显示TextView控件的过程中,会有一些回调方法,而滚动的属性和参数都需要进行初始化,所以,我们可以通过这些回调方法中进行初始化操作。代码如下:

@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
    super.onTextChanged(text, start, lengthBefore, lengthAfter);
    Log.d(TAG , "onTextChanged");
    isStop = true; // 停止滚动
    this.removeCallbacks(this);   // 清空队列
    currentScrollX = firstScrollX;  // 滚动到初始位置
    this.scrollTo(currentScrollX, 0);
    super.onTextChanged(text, start, lengthBefore, lengthAfter);
    // 需要重新设置参数
    isFirstDraw = true;  
    isStop = false;
    postDelayed(this, SCROLL_DELAYED);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (isFirstDraw) {
        Log.d(TAG , "isFirstDraw=="+isFirstDraw);
        getTextWidth();
        firstScrollX = getScrollX(); // 获取第一次滑动的X轴距离
        System.out.println("firstScrollX======"+firstScrollX);
        currentScrollX = firstScrollX;
        mWidth = this.getWidth();  // 获取文本宽度,如果文本宽度大于屏幕宽度,则为屏幕宽度,否则为文本宽度
        Log.d(TAG , "mWidth======"+mWidth);
        endX = firstScrollX + textWidth - mWidth/2;  // 滚动的最大距离,可根据需要来定
        Log.d(TAG , "endX========"+endX);
        isFirstDraw = false;
    }
}

另外将一些滚动速度的一些属性和控制滚动速度的操作贴出来:

private static final String TAG = "CarouselTextView";
private int currentScrollX = 0; // 当前滚动位置  X轴
private int firstScrollX = 0;  //  初始位置
private boolean isStop = false;  // 开始停止的标记
private int textWidth;  // 文本宽度
private int mWidth = 0; // 控件宽度
private int speed = 2;  // 默认是两个点
private int delayed = 1000; // 默认是1秒
private int endX; // 滚动到哪个位置
private boolean isFirstDraw=true; // 当首次或文本改变时重置
private static final int SCROLL_DELAYED = 4 * 1000;

/**
 * @param 滚动速度
 */
public void setSpeed(int speed) {
    this.speed = speed;
}


/**
 * @param 滚动时间间隔
 */
public void setDelayed(int delayed) {
    this.delayed = delayed;
}

        /**
     * 开始滚动
     */
    public void startScroll() {
    isStop = false;
    this.removeCallbacks(this);  // 清空队列
    postDelayed(this, SCROLL_DELAYED);  // 4秒之后滚动到指定位置
}

/**
 * 停止滑动
 */
public void stopScroll() {
    isStop = true;
}

/**
 * 从头开始滑动
 */
public void startFor(){
    currentScrollX = 0;  // 将当前位置置为0
    startScroll();
}

最后贴上布局设置:




效果图如下:

image

注意:如果设置了android:marqueeRepeatLimit="marquee_forever"属性之后,所有的速度设置都是无效的。

你可能感兴趣的:(Android 可以自定义速度的跑马灯效果)