当前位置: 首页 > article >正文

Android TextView实现跑马灯效果性能优化

在生活中经常见到文字滚动显示场景,比如电子屏幕信息提示、KTV电视上显示播放歌曲信息等,俗称跑马灯。那么在Android中如何简单实现呢?

最简单的就是通过文本控件TextView自带的属性实现,如下:

<TextView
        android:id="@+id/srcoll_text"
        android:layout_gravity="top"
        android:layout_marginTop="@dimen/size_dp_10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:marqueeRepeatLimit="marquee_forever"
        android:textColor="#fff"
        android:textSize="30sp"
       />

最重要的就是以下三个属性:

 android:singleLine="true"  //单行显示
 android:ellipsize="marquee" //显示长度不够时滚动显示
 android:marqueeRepeatLimit="marquee_forever" //无限循环滚动

但是以上滚动效果只有在TextView获取焦点时才会触发,所以需要通过代码设置TextView焦点。

srcollText.setEllipsize(TextUtils.TruncateAt.MARQUEE);
srcollText.setSingleLine(true);
srcollText.setMarqueeRepeatLimit(-1);
srcollText.setSelected(true); //设置选中
//或者设置获取焦点
/*
  srcollText.setFocusable(true);
  srcollText.setFocusableInTouchMode(true);
  srcollText.requestFocus();
*/
srcollText.setText("滚动文本内容要足够长,超过TextView设置的宽度");

这样就可以实现横向滚动的跑马灯效果,实践中发现这种方式比较消耗CPU性能,单一功能多消耗CPU 5%左右,网上也要好多优化建议:

1.开启硬件加速

<application
    android:hardwareAccelerated="true"
    ... >
    ...
</application>

2.自定义TextView,延时降低重绘次数

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

public class CustomMarqueeTextView extends TextView {

    private static final int MARQUEE_DELAY = 100; // 调整此值以降低帧率

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

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

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        postInvalidateDelayed(MARQUEE_DELAY); // 延迟重绘
    }
}

3.进一步自定义TextView动画

import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;

public class CustomMarqueeTextView extends TextView {

    private ValueAnimator animator;
    private int scrollOffset;

    public CustomMarqueeTextView(Context context) {
        super(context);
        init();
    }

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

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

    private void init() {
        animator = ValueAnimator.ofInt(0, getWidth());
        animator.setDuration(5000); // 动画时长
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                scrollOffset = (int) animation.getAnimatedValue();
                scrollTo(scrollOffset, 0);
            }
        });
        animator.start();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (animator != null) {
            animator.cancel();
        }
    }
}

实践发现效果不明显,性能消耗还是偏高。而改成通过平移动画上下翻滚效果,性能消耗低很多。

在 res/anim 目录下创建 slide_up.xml 

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromYDelta="0%"
        android:toYDelta="-150%"
        android:duration="3000"
       />
</set>
 <TextView
        android:id="@+id/scrolling_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是一段会上下翻滚的文字~"
        android:textSize="20sp"
        android:padding="16dp" />

实现多段文字轮流上下滚动显示 

     if (runnable == null) {
                final Animation slideUp = AnimationUtils.loadAnimation(mContext, R.anim.slide_up);
                runnable = new Runnable() {
                    @Override
                    public void run() {
                        myViewBinding.srcollText.startAnimation(slideUp);
                        // 切换索引
                        currentScrollIndex = (currentScrollIndex + 1) % parts.length;
                        myViewBinding.srcollText.setText(parts[currentScrollIndex]);
                        if (MainApplication.onFullScreen)
                            handler.postDelayed(this, slideUp.getDuration()/* + slideDown.getDuration()*/);
                    }
                };

                // 启动循环任务
                handler.postDelayed(runnable, 1000);
            }

这种方式实现整体性能消耗降低3%左右。性能优化就是要积少成多,每个小功能细节上节省一点,应用整体上就会流畅很多。


http://www.kler.cn/a/611598.html

相关文章:

  • 用shell脚本,批量备份MySQL中所有数据库,并批量还原!
  • asp.net进销存软件WEB进销存ERP软件库存玻璃行业
  • SQLite优化实践
  • 【设计模式】策略模式(Strategy Pattern)详解
  • 5分钟快速上手Docker容器化部署:从零到实践
  • 带你刷题—公因子的数目(leetcode2427)
  • docker-操作实战
  • Visual Studio 使用 IntelliCode AI 辅助代码开发
  • 【CUDA】mnist_cuda
  • 模块学习篇#2:解析常用于YOLO等深度学习模型的注意力机制CBAM
  • Oracle常用分析诊断工具(9)——ADDM
  • Java单例设计模式详解
  • 深度学习篇---卷积网络结构
  • 【CodeReview】Jupiter(Eclipse插件)代码审查工具简介
  • Oracle补丁自动化安装步骤
  • 阶段一:Java基础语法
  • 运行前端项目报错解决方法
  • 游戏引擎学习第184天
  • MTK Android15 去掉设置中的顶部空白
  • 苹果与安卓,鸿蒙下跨设备,应用分享