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

原创 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);
    }


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

跑马灯无效果问题(TextView隐藏和显示后无效果)

这两天在做项目的时候,有一个需求是在同一个页面显示两种结果,一种是带有跑马灯效果的,这时候就使用到了View的隐藏和显示(GONE和VISIBLE),但是在做的过程中,如果这个TextView使用go...
  • b10060224
  • b10060224
  • 2016年05月18日 16:35
  • 1326

html5使用<marquee>标签实现走马灯效果

很是简单。。。只要使用html5的标签 浙江温州皮革厂倒闭了。。。
  • HUSHILIN001
  • HUSHILIN001
  • 2017年09月13日 10:52
  • 1034

无间断滚动marquee的详细用法解析(转)

无间断滚动marquee的详细用法解析记得前阵子有个朋友问我 无间断滚动我也忘记了我当时在做什么了随便上网拷了一段代码给他实现是可以实现 但是太麻烦了一大堆的代码 不静下心来是看不懂的  趁着 今天有...
  • xuezhongsong
  • xuezhongsong
  • 2009年02月19日 09:40
  • 8168

图片左右循环连续滚动代码,解决marquee的留白问题

想必大家都注意到的不循环滚动,所以出现了很多替代脚本,或iframe或JS输出,不管怎么做,都略显麻烦。下面说一下这个相对简单的实现思路:一个设定宽度并且隐藏超出它宽度的内容的容器demo,里面放de...
  • huangjianxiang1875
  • huangjianxiang1875
  • 2012年07月25日 18:11
  • 8507

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

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

【Android 控件】垂直滚动广告栏控件实现(跑马灯效果)

跑马灯TextView是每个学过android开发的人在入门阶段都会去自己实现一遍的。然而,在实际应用当中,要在跑马灯中展示的不仅仅是一行文字,常常是一幅幅图片,甚至是图文混排的广告。这种场景下,集成...
  • colinandroid
  • colinandroid
  • 2017年12月12日 21:20
  • 106

HTML中让图片滚动的<marquee>标签的使用方法

实例:  
  • wendylover
  • wendylover
  • 2012年11月24日 23:36
  • 16490

TextView实现滚动显示的效果

TextView中有个ellipsize属性,作用是当文字过长时,该控件该如何显示,解释如下: 1.android:ellipsize=”start”—–省略号显示在开头 2.android:el...
  • l0605020112
  • l0605020112
  • 2014年07月08日 19:31
  • 18585

广告精准推送项目介绍

广告中介商:每个用户的目标客户不同,找的广告位也就不一样。广告提供商(网站、APP):想拉业务,也去找中介。将广告栏位提供给中介商。广告用户(各行业厂商):想去打广告,需要去找一些广告提供商。但是很难...
  • mrbcy
  • mrbcy
  • 2017年04月01日 12:16
  • 772

Android中添加万普广告墙、推送广告等

一、配置环境 1.添加从万普SDK中下载下来的AppOffer_1.6.4.jar包 2.修改AndroidManifest.xml文件: (1)加入以下权限(是项目情况不同,可...
  • shakespeare001
  • shakespeare001
  • 2012年04月19日 22:02
  • 8729
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:跑马灯状态获取(停止后自动隐藏,用于广告推送等)
举报原因:
原因补充:

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