跑马灯各种实现的方法,以及效果,注意事项

首先android实现跑马灯,此处有三种思路,

1,android系统自带的TextView

2,自定义的view继承TextView,通过view.post延迟更新view,ondraw

3,通过自定义scrollview中包含textview,实现,具体如下


1,实现方式,代码

必须属性,少一个就不能实现

        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:singleLine="true"
        android:marqueeRepeatLimit="marquee_forever"

解释

<!-- 跑马灯效果-->
  <!-- start 表示开始有三个点-->
  <!-- middle 表示中间有三个点-->
  <!-- end 表示结束的位置有三个点-->
      android:ellipsize="marquee"
 <!-- 单行显示文本-->
     android:singleLine="true"
<!-- 下面两个需要同时设置才可以-->
<!-- 使控件获取到焦点针对物理键-->
    android:focusable="true"
<!-- 使控件获取到焦点针对手指-->
    android:focusableInTouchMode="true"
<!-- 设置文本的滚动为一直重复-->
    android:marqueeRepeatLimit="marquee_forever"
注意事项: 

             虽然singleLine的属性已经被抛弃,但是依然不能用lines="1"来替换。

     用系统自带的前提是必须此textview有焦点,此方法是只有一个textview的可以,但是当有两个跑马灯的时候,或者焦点被editText抢的时候,或者有AlertDialg就不会出现跑马灯效果,要想有效果,解决方案如下

当有两个跑马灯,需要自定义TextView,如下

package mianshi.team.com.notifactiotest.view;

import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * Created by yuanqing on 2017/2/4.
 */

public class MarqueeTextView extends TextView {
    public MarqueeTextView(Context context) {
        this(context, null);
    }

    public MarqueeTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // android:singleLine="true"
        setSingleLine();
        // android:ellipsize="marquee"
        setEllipsize(TextUtils.TruncateAt.MARQUEE);
        // android:focusable="true"
        setFocusable(true);
        // android:focusableInTouchMode="true"
        setFocusableInTouchMode(true);
        // android:marqueeRepeatLimit="marquee_forever"
        setMarqueeRepeatLimit(-1);
    }
    /**
     * 解决当有两个跑马灯出现的时候,一个跑一个不动的现象
     * @return
     */
    @Override
    public boolean isFocused() {
        return true;
    }
}

当有一个EditText的時候焦点也会被抢走的

解决方案效果如图

package mianshi.team.com.notifactiotest.view;

import android.content.Context;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * Created by yuanqing on 2017/2/4.
 */

public class MarqueeTextView extends TextView {
    public MarqueeTextView(Context context) {
        this(context, null);
    }

    public MarqueeTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // android:singleLine="true"
        setSingleLine();
        // android:ellipsize="marquee"
        setEllipsize(TextUtils.TruncateAt.MARQUEE);
        // android:focusable="true"
        setFocusable(true);
        // android:focusableInTouchMode="true"
        setFocusableInTouchMode(true);
        // android:marqueeRepeatLimit="marquee_forever"
        setMarqueeRepeatLimit(-1);
    }

    /**
     * 解决当有两个跑马灯出现的时候,一个跑一个不动的现象
     *
     * @return
     */
    @Override
    public boolean isFocused() {
        return true;
    }

    /**
     * 解决 EditText跟跑马灯之间抢焦点的问题
     *
     * @param focused
     * @param direction
     * @param previouslyFocusedRect
     */
    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        if (focused)
            // 有焦点时走父类方法,焦点被抢走时,不去做操作
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    /**
     * 解决AlerDilago抢焦点的问题
     * @param hasWindowFocus
     */
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        if (hasWindowFocus) {
            // 窗体有焦点时走父类的方法,窗体焦点消失,不去做操作
            super.onWindowFocusChanged(hasWindowFocus);
        }
    }
}


哈哈,可以说完美解决,但是问题有出现了,跑马灯的速率怎么控制呢,采用系统的没法控制,这就需要用第二种方法了

自定义view继承TextView,

方法如下,

package mianshi.team.com.notifactiotest.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * Created by yuanqing on 2017/2/5.
 */

public class MarqueeTextView2 extends TextView implements Runnable {
    private boolean isMeasure = false;
    private int textWidth;
    private boolean isStop = false;
    private int currentScrollX;//当前滚动的位置

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

    public MarqueeTextView2(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MarqueeTextView2(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void run() {
        currentScrollX -= 1;//滚动的速率
        scrollTo(currentScrollX, 0);//内容滚动
        if (isStop) {
            return;
        }
        if (getScrollX() <= -(this.getWidth())) {
            scrollTo(textWidth, 0);
            currentScrollX = textWidth;
            return;
        }
        postDelayed(this, 10);
    }

    /**
     * 开始滚动
     */
    public void startScroll() {
        isStop = false;
        this.removeCallbacks(this);
        post(this);
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (!isMeasure) {
            getTextWidth();//获取字体的长度
        }
    }

    public void getTextWidth() {
        Paint paint = this.getPaint();
        String str = this.getText().toString();
        textWidth = (int) paint.measureText(str);
    }
}
缺点是,

字体在超过一行,就有三个点移动,不显示其他的字

第三种测试,应该可以,由于最近忙着找工作,此时就不带测试了,哈





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值