我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android中怎么用TextView实现跑马灯效果

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android中怎么用TextView实现跑马灯效果

这篇“Android中怎么用TextView实现跑马灯效果”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Android中怎么用TextView实现跑马灯效果”文章吧。

    【前言】

         在Textview设置的宽度有限,而需要显示的文字又比较多的情况下,往往需要给Textview设置跑马灯效果才能让用户完整地看到所有设置的文字,所以给TextView设置跑马灯效果的需求是很常见的

    一、新手设置跑马灯效果

    先在xml中给Textview设置好对应的属性

     <TextView        android:id="@+id/tv"        android:layout_width="200dp"        android:layout_height="wrap_content"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toBottomOf="@id/show_float"        android:singleLine="true"        android:ellipsize="marquee"        android:focusable="true"        android:focusableInTouchMode="true"        android:marqueeRepeatLimit="-1"        android:layout_marginTop="20dp"        android:padding="10dp"        android:text="欢迎来到跑马灯新手村,这是新手示例~"        android:textColor="@color/white"        android:background="@drawable/com_live_rounded_rectangle"/>

    然后在代码中设置请求获取焦点即可

            TextView tv = findViewById(R.id.tv);        tv.requestFocus();

    这样设置之后,跑马灯的效果就出来了

    Android中怎么用TextView实现跑马灯效果

    【关键点讲解】

    android:layout_width 是限制为固定宽度,同时文本的长度大于所设置的宽度,要是设置android:layout_widthwrap_content, 那么Textview的宽度会随着文本长度变长而拉宽,这样就不能出现跑马灯效果
    2、android:singleLine="true"设置Textview只能一行显示,要是不设置为true,默认会自动换行,显示为多行,这样的话,也不能出现跑马灯效果
    3、android:ellipsize="marquee"设置要是文本长度超出Textview的宽度时候,文本应该以跑马灯效果显示,这个是设置跑马灯效果最关键的设置,android:ellipsize还可以取值startendmiddlenone,分别是开头显示省略号结尾显示省略号中间显示省略号直接截断
    4、android:focusable="true"设置Textview可以获取焦点,跑马灯效果需要获取到焦点时候才生效,Textview默认是不获取焦点的
    5、android:focusableInTouchMode="true"设置在触摸模式下可以获取焦点,目前智能机基本都是自动进入触摸模式,其实目前只要设置android:focusableInTouchMode="true",默认android:focusable也会变为true了
    6、android:marqueeRepeatLimit="-1"设置跑马灯循环的次数,-1表示无限循环,不设置的话,默认是循环3次
    7、 tv.requestFocus();设置获取焦点, 只有当该view的focusable属性为true时候才生效

    【总结】

    一定要设置android:focusableInTouchMode="true",若是只设置了android:focusable="true"android:focusableInTouchMode没设置,那么跑马灯效果是不生效的,因为进入触摸模式之后,isFocusable()返回false,下面看看Texivew startMarquee()源码就知道需要满足什么条件才会开始跑马灯特效:

         private void startMarquee() {        // Do not ellipsize EditText        if (getKeyListener() != null) return;        if (compressText(getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight())) {            return;        }// 1、跑马灯控制类没有创建或者跑马灯效果已经停止        if ((mMarquee == null || mMarquee.isStopped()) &&         // 2、当前Textview是获取到焦点或者被选中状态        (isFocused() || isSelected())        // 3、文本的行数只有一行         && getLineCount() == 1         // 4、文本长度大于Textview的宽度          && canMarquee()) {            if (mMarqueeFadeMode == MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) {                mMarqueeFadeMode = MARQUEE_FADE_SWITCH_SHOW_FADE;                final Layout tmp = mLayout;                mLayout = mSavedMarqueeModeLayout;                mSavedMarqueeModeLayout = tmp;                setHorizontalFadingEdgeEnabled(true);                requestLayout();                invalidate();            }            if (mMarquee == null) mMarquee = new Marquee(this);            mMarquee.start(mMarqueeRepeatLimit);        }    }         private boolean canMarquee() {        int width = mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight();        return width > 0 && (mLayout.getLineWidth(0) > width                || (mMarqueeFadeMode != MARQUEE_FADE_NORMAL && mSavedMarqueeModeLayout != null                        && mSavedMarqueeModeLayout.getLineWidth(0) > width));    }

    二、高端玩家设置跑马灯效果

         从上面总结的TextView跑马灯源码可以看到,只要isFocusable()或者isSelected()方法返回true,那么就没必要管是否触摸模式,是否可以获取焦点之类的问题了,所以我们可以自定义一个类继承于TextView,然后重写isFocusable()直接返回true即可:

    public class MarqueeTextView extends TextView {    public MarqueeTextView(Context context) {        super(context);        initView(context);    }    public MarqueeTextView(Context context, AttributeSet attrs) {        super(context, attrs);        initView(context);    }    public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView(context);    }    private void initView(Context context) {        this.setEllipsize(TextUtils.TruncateAt.MARQUEE);        this.setSingleLine(true);        this.setMarqueeRepeatLimit(-1);    }    //最关键的部分    public boolean isFocused() {        return true;    }}

    直接在Xml中使用自定义的MarqueeTextView,那么跑马灯效果就出来了,无需任何额外配置

     <com.example.MarqueeTextView        android:id="@+id/tv"        android:layout_width="200dp"        android:layout_height="wrap_content"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toBottomOf="@id/show_float"        android:layout_marginTop="20dp"        android:padding="10dp"        android:text="欢迎来到跑马灯高端玩家局,这是高端玩法示例~"        android:textColor="@color/white"        android:background="@drawable/com_live_rounded_rectangle"/>

    来看看效果:

    Android中怎么用TextView实现跑马灯效果

    三、延伸阅读

         假如有这样一个需求:因为显示文本的空间有限,所以只能用跑马灯的效果来给用户展示文本,但是在用户完整地看完一遍文本之后,需要隐藏掉Textview,那么问题来了,我们怎么知道跑马灯效果什么时候跑完一遍呢?先来看看Textview跑马灯部分Marquee类的部分源码:

           void start(int repeatLimit) {       //重复次数设置0,那就直接停止跑马灯            if (repeatLimit == 0) {                stop();                return;            }           //...省略掉大部分不相关的代码                mChoreographer.postFrameCallback(mStartCallback);            }        }             private Choreographer.FrameCallback mStartCallback = new Choreographer.FrameCallback() {            @Override            public void doFrame(long frameTimeNanos) {                mStatus = MARQUEE_RUNNING;                mLastAnimationMs = mChoreographer.getFrameTime();                tick();            }        };        void tick() {            if (mStatus != MARQUEE_RUNNING) {                return;            }            if (textView != null && (textView.isFocused() || textView.isSelected())) {                long currentMs = mChoreographer.getFrameTime();                long deltaMs = currentMs - mLastAnimationMs;                mLastAnimationMs = currentMs;                float deltaPx = deltaMs * mPixelsPerMs;                mScroll += deltaPx;                //要是跑马灯滚动的距离大于最大距离,那么回到给mRestartCallback                if (mScroll > mMaxScroll) {                    mScroll = mMaxScroll;                    mChoreographer.postFrameCallbackDelayed(mRestartCallback, MARQUEE_DELAY);                } else {                    mChoreographer.postFrameCallback(mTickCallback);                }                textView.invalidate();            }        }                 private Choreographer.FrameCallback mRestartCallback = new Choreographer.FrameCallback() {            @Override            public void doFrame(long frameTimeNanos) {                if (mStatus == MARQUEE_RUNNING) {                    if (mRepeatLimit >= 0) {                        mRepeatLimit--;                    }                    start(mRepeatLimit);                }            }        }

    从上面对Marquee源码分析可知,跑马灯跑完一轮之后会调用到MarqueemRestartCallback对象的doFrame方法,那么我们来一招“偷龙转凤”,通过反射把mRestartCallback对象替换成我们自己实例化的对象,那么在跑马灯跑完一轮之后就会回调到我们替换的对象中,这样就实现了对跑马灯效果跑完一轮的监听,实现源码如下:

    public class MarqueeTextView extends androidx.appcompat.widget.AppCompatTextView {    private Choreographer.FrameCallback mRealRestartCallbackObj;    private Choreographer.FrameCallback mFakeRestartCallback;    private OnShowTextListener mOnShowTextListener;    public MarqueeTextView(Context context, OnShowTextListener onShowTextListener) {        super(context);        initView(context);        this.mOnShowTextListener = onShowTextListener;    }    public MarqueeTextView(Context context, AttributeSet attrs) {        super(context, attrs);        initView(context);    }    public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView(context);    }    private void initView(Context context) {        //绕过隐藏api的限制        Reflection.unseal(context.getApplicationContext());        //设置跑马灯生效条件        this.setEllipsize(TextUtils.TruncateAt.MARQUEE);        this.setSingleLine(true);        this.setFocusable(true);        //反射设置跑马灯监听        try {            //从TextView类中找到定义的字段mMarquee            Field marqueeField = ReflectUtil.getDeclaredField(TextView.class, "mMarquee");            //获取Marquee类的构造方法Marquee(TextView v)            Constructor declaredConstructor = ReflectUtil.getDeclaredConstructor(Class.forName("android.widget.TextView$Marquee"), TextView.class);            //实例化一个Marquee对象,传入参数是Textview对象            Object marqueeObj = declaredConstructor.newInstance(this);            //从Marquee类中找到定义的字段mRestartCallback,重新开始一轮跑马灯时候会回调到这个对象doFrame()方法            Field restartCallbackField = ReflectUtil.getDeclaredField(Class.forName("android.widget.TextView$Marquee"), "mRestartCallback");            //从Marquee实例对象中获取到真实的mRestartCallback对象            mRealRestartCallbackObj = (Choreographer.FrameCallback) restartCallbackField.get(marqueeObj);            //构造一个假的mRestartCallback对象,用来监听什么时候跑完一轮跑马灯效果            mFakeRestartCallback = new Choreographer.FrameCallback() {                @Override                public void doFrame(long frameTimeNanos) {                    //这里还是执行真实的mRestartCallback对象的代码逻辑                    mRealRestartCallbackObj.doFrame(frameTimeNanos);                    Log.i("min77","跑马灯文本显示完毕");                    //回调通知跑完一轮                    if(MarqueeTextView.this.mOnShowTextListener != null){                        MarqueeTextView.this.mOnShowTextListener.onComplete(0);                    }                }            };            //把假的mRestartCallback对象设置给Marquee对象,其实就是代理模式            restartCallbackField.set(marqueeObj, mFakeRestartCallback);            //把自己实例化的Marquee对象设置给Textview            marqueeField.set(this, marqueeObj);        } catch (Exception e) {            e.printStackTrace();            Log.e("min77",e.getMessage());        }    }    //最关键的部分    public boolean isFocused() {        return true;    }        public interface OnShowTextListener{        void onComplete(int delayMillisecond);    }}

    效果如下:

    Android中怎么用TextView实现跑马灯效果

    以上就是关于“Android中怎么用TextView实现跑马灯效果”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Android中怎么用TextView实现跑马灯效果

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Android中怎么用TextView实现跑马灯效果

    这篇“Android中怎么用TextView实现跑马灯效果”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Android中怎么
    2023-06-29

    android中怎么利用TextView实现跑马灯效果

    这篇文章给大家介绍android中怎么利用TextView实现跑马灯效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、要点设置四个属性android:singleLine="true"android:ellipsi
    2023-05-31

    怎么在Android中利用TextView实现跑马灯效果

    怎么在Android中利用TextView实现跑马灯效果?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。MainActivitypackage com.example.jun
    2023-06-15

    Android TextView跑马灯效果实现方法

    本文实例讲述了Android TextView跑马灯效果实现方法。分享给大家供大家参考,具体如下:public class MyTextView extends TextView{public MyTextView(Context cont
    2022-06-06

    Android基于TextView实现跑马灯效果

    本文实例为大家分享了Android TextView实现跑马灯效果的具体代码,供大家参考,具体内容如下当Layout中只有一个TextView需要实现跑马灯效果时,操作如下。 在Layout的TextView配置文件中增加
    2022-06-06

    Android使用TextView跑马灯效果

    老规矩,先上图看效果。说明TextView的跑马灯效果也就是指当你只想让TextView单行显示,可是文本内容却又超过一行时,自动从左往右慢慢滑动显示的效果就叫跑马灯效果。 其实,TextView实现跑马灯效果很简单,因为官方已经实现了,你
    2022-06-06

    Android中使用TextView实现文字跑马灯效果

    通常情况下我们想实现文字的走马灯效果需要在xml文件中这样设置
    2022-06-06

    Android 中TextView中跑马灯效果的实现方法

    条件: 1、android:ellipsize=”marquee” 2、TextView必须单行显示,即内容必须超出TextView大小 3、TextView要获得焦点才能滚动 mTVText.setText(“超过文本长度的数据");
    2022-06-06

    在Android中使用TextView实现一个跑马灯效果

    本篇文章为大家展示了在Android中使用TextView实现一个跑马灯效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 条件:1、android:ellipsize=”marquee”2、Tex
    2023-05-31

    怎么在Android中利用TextView实现一个跑马灯效果

    这期内容当中小编将会给大家带来有关怎么在Android中利用TextView实现一个跑马灯效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。TextView的跑马灯效果也就是指当你只想让TextView单
    2023-05-31

    Android基于TextView实现的跑马灯效果实例

    本文实例讲述了Android基于TextView实现的跑马灯效果。分享给大家供大家参考,具体如下:package sweet.venst.act; import java.io.BufferedReader; import java.io.
    2022-06-06

    Android用过TextView实现跑马灯效果的示例

    以前就遇到过这个问题,今天重新拾起来。跑马灯效果其实就是当文字超过TextView控件宽度的时候,使用滚动的方式显示出来:方法1:(直接xml搞定)Android系统中TextView实现跑马灯效果,必须具备以下几个条件: 1、androi
    2023-05-30

    如何在Android中利用TextView实现一个跑马灯效果

    本篇文章为大家展示了如何在Android中利用TextView实现一个跑马灯效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Android自带的跑马灯效果不太好控制,还必须要满足条件才能有效果,而
    2023-05-31

    TextView实现跑马灯效果 就这么简单!

    一、方法这里我们用两种方法来实现跑马灯效果,虽然实质上是一种实质就是:1、TextView调出跑马灯效果2、TextView获取焦点 第一种:1、TextView调出跑马灯效果android:ellipsize="marquee"2、Tex
    2023-05-30

    Android基于TextView不获取焦点实现跑马灯效果

    本文实例讲述了Android基于TextView不获取焦点实现跑马灯效果。分享给大家供大家参考,具体如下: 1. 写一个类继承TextViewpackage com.example.tt; import android.content.Co
    2022-06-06

    Android基于TextView属性android:ellipsize实现跑马灯效果的方法

    本文实例讲述了Android基于TextView属性android:ellipsize实现跑马灯效果的方法。分享给大家供大家参考,具体如下: Android系统中TextView实现跑马灯效果,必须具备以下几个条件: 1、android:e
    2022-06-06

    Android自定义textview如何实现竖直滚动跑马灯效果

    这篇文章主要为大家展示了Android自定义textview如何实现竖直滚动跑马灯效果,内容简而易懂,希望大家可以学习一下,学习完之后肯定会有收获的,下面让小编带大家一起来看看吧。xml布局
    2023-05-31

    Android实现跑马灯效果的方法

    本文实例讲述了Android实现跑马灯效果的方法。分享给大家供大家参考。具体如下: 运行效果截图如下:直接在布局里写代码就好了:
    2022-06-06

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录