跑马灯状态获取(停止后自动隐藏,用于广告推送等)

原创 2016年08月28日 18:57:17

继之前一篇的推送广告需求,需要广告播放3次后自动消失。

因此需要监控TextView的Marquee的状态,在Marquee  stop之后隐藏TextView。

查看了文档,TextView并没有提供一个获取跑马灯状态的接口。只能自己想办法了。


这里先放出代码,各位看官如果需要,可以直接下代码,因为本人文笔实在...

https://github.com/HangminTian/MarqueueDemo

争取慢慢改进,提升文章可读性


Marquee是TextView的内部类,点到TextView源码中找到它。

下面列出和需求相关的重要成员

跑马灯状态标识,3个byte类型。

private static final byte MARQUEE_STOPPED = 0x0;
private static final byte MARQUEE_STARTING = 0x1;
private static final byte MARQUEE_RUNNING = 0x2;


默认重播次数为3,刚刚好是需求次数。省的我自己设置了。

mStatus是我们想要的东西,它记录了marquee当前的状态。

private int mMarqueeRepeatLimit = 3;
private byte mStatus = MARQUEE_STOPPED;

接下来两个跟需求没什么关系,但是我们可以拿来做做文章,订制我们自己需要的效果。

比如改变一下速度、等待时间。

private static final int MARQUEE_DELAY = 1200;
private static final int MARQUEE_RESTART_DELAY = 1200;



目的很明确,就是要获取TextView的私有内部类Marquee的mStatus值,可以用反射啊


然后反射代码是这样的(马克,2016/9/22,兼容AppCompatTextView,已经同步更新到github):

private void getFiled(){
        Class<?> mTextViewClass = mTextView.getClass();

        if(mTextViewClass != TextView.class){
            mTextViewClass = mTextViewClass.getSuperclass();
        }

        Field filedMarquee = null;
        try {
            filedMarquee = mTextViewClass.getDeclaredField("mMarquee");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        if(filedMarquee == null){
            return;
        }
        filedMarquee.setAccessible(true);

        try {
            mMarquee = filedMarquee.get(mTextView);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if(mMarquee == null){
            return;
        }

        Class<?> mMarqueeClass = mMarquee.getClass();
        try {
            fieldStatus = mMarqueeClass.getDeclaredField("mStatus");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        if(fieldStatus == null){
            return;
        }
        fieldStatus.setAccessible(true);
    }

    public void checkStop(){
        if(fieldStatus == null){
            getFiled();
        }
        if(fieldStatus == null){
            Log.d(TAG, "fieldStatus == null");
            return;
        }
        Byte mStatus = -1;
        try {
            mStatus = (Byte) fieldStatus.get(mMarquee);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


这样,我们就获得了mStatus的值,但是我们要知道它何时被置成了stop(0x0),

这里我采用的轮询,每1秒去检查一次,虽然这个办法不是很靠谱,但暂时也是个办法吧。

有好方法的大神希望提供一下思路。


用一个Handler负责去检查marquee是否已经停止。

 final Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            if (msg.what == CHECK_MARQUE_STOPED) {
                checkStop();
            }
            super.handleMessage(msg);
        }
    };



在Activity初始化的时候,用一个Timer定时去启动这个handler,以保证TextView的内部全部已经加载完成。

mTimer = new Timer();
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                mHandler.sendEmptyMessage(CHECK_MARQUE_STOPED);
            }
        }, 2000);



在checkStop中,每当检查到还没stop的时候,继续进行检查,如果已经stop,则隐藏TextView,并终止检查。

    private void getFiled(){
        Class<?> mTextViewClass = mTextView.getClass();

        if(mTextViewClass != TextView.class){
            mTextViewClass = mTextViewClass.getSuperclass();
        }

        Field filedMarquee = null;
        try {
            filedMarquee = mTextViewClass.getDeclaredField("mMarquee");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        if(filedMarquee == null){
            return;
        }
        filedMarquee.setAccessible(true);

        try {
            mMarquee = filedMarquee.get(mTextView);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if(mMarquee == null){
            return;
        }

        Class<?> mMarqueeClass = mMarquee.getClass();
        try {
            fieldStatus = mMarqueeClass.getDeclaredField("mStatus");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        if(fieldStatus == null){
            return;
        }
        fieldStatus.setAccessible(true);
    }

    public void checkStop(){
        if(fieldStatus == null){
            getFiled();
        }
        if(fieldStatus == null){
            Log.d(TAG, "fieldStatus == null");
            return;
        }
        
        Byte mStatus = -1;
        try {
            mStatus = (Byte) fieldStatus.get(mMarquee);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        Log.d(TAG, "mStatus = "+mStatus);
        if(mStatus == MARQUEE_STOPPED){
            mTextView.setVisibility(View.GONE);
            return;
        }


        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                mHandler.sendEmptyMessage(CHECK_MARQUE_STOPED);
            }
        }, 1000);
    }


版权声明:本文为博主原创文章,未经博主允许不得转载。

marquee 循环显示数据库中的记录,一次显示一条

需要显示的list: List sysNoticeList = sysNoticeService.getAllNoticeList(); 每一条都展示为一个a标签:              ...

android中给TextView设置属性ellipsize, 过长自动隐藏 或 跑马灯效果

http://www.cnblogs.com/fengzhblog/archive/2013/05/15/3080392.html

推送跑马灯效果

  • 2016年02月22日 11:49
  • 4.95MB
  • 下载

大作业之小无聊------TextView跑马灯推送消息

无聊之中学习,好好玩      目的 :在屏幕上方推送消息,一直无限循环推送 一 实验效果图: 1.单行: 2.多行: 二:实验步骤: 1.修改helloword   效...

javascript:广告、文字跑马灯、图片浮动案例

javascript浏览器对象  window.open  实现一个广告弹出效果 1、确定我们要弹出的内容 2、控制弹出大小、窗口的特征 3、弹出的起始坐标(0,0)   functi...

跑马灯广告语的实现过程,并且自定义marquee,解决焦点抢占问题.

1.默认布局如下,为了只显示一行加上singleLine属性,加上后又显示不全 2  为了解决上述文字显示不全的问题,我们加上ellipsize 这个属性,这个属性包含以下几个参数. ...

教你自定义竖直跑马灯效果(广告专用)

最近因为项目需要,写了一个跑马灯效果的控件,过程中也学到一些东西,在这里和大家分享一下。 首先让我们来看一下效果:...

Android TextView文字横向自动滚动(跑马灯)

TextView实现文字滚动需要以下几个要点: 1.文字长度长于可显示范围:android:singleLine="true" 2.设置可滚到,或显示样式:android:ellipsize="m...

51.使用HorizontalScrollView+LinearLayout实现文字+图片的自动跑马灯效果

使用HorizontalScrollView+LinearLayout实现文字+图片的自动跑马灯效果
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:跑马灯状态获取(停止后自动隐藏,用于广告推送等)
举报原因:
原因补充:

(最多只允许输入30个字)