iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >Android如何实现文字动态高亮读取进度效果
  • 256
分享到

Android如何实现文字动态高亮读取进度效果

2023-06-15 04:06:16 256人浏览 安东尼
摘要

小编给大家分享一下Android如何实现文字动态高亮读取进度效果,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体内容如下1、效果图类似歌词的效果。播放下面文字的音频,同时音频播放的进度和文字高亮进度保持一致。2、代码结构

小编给大家分享一下Android如何实现文字动态高亮读取进度效果,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

具体内容如下

1、效果图

类似歌词的效果。播放下面文字的音频,同时音频播放的进度和文字高亮进度保持一致。

Android如何实现文字动态高亮读取进度效果

2、代码结构和实现

简单的类图:

Android如何实现文字动态高亮读取进度效果

ISubtitleView接口代码如下:

public interface ISubtitleView {        List<SubtitleItem> getSubtitleItemList();        void setSubtitleItemList(List<SubtitleItem> linesTextList);        void setDuration(long duration);        void updatePts(long pts);        void reset();}EMSubtitleView类的代码如下:public class EMSubtitleView extends android.support.v7.widget.AppCompatTextView  implements ISubtitleView{    private int mMeasuredWidth;    private int mMeasuredHeight;    private List<SubtitleItem> mSubtitleItemList;    private List<LineEntity> mLinesTextList;    private Paint mNORMalPaint;    private Paint mHLPaint;    private long mPts = 0;    private int mCurHLLine;    private float mReadSubtitleCount;    private Rect mLastHLRect;    private int mHLTextColor;    private long mDuration;    private boolean mIsPlain = false;    public EMSubtitleView(Context context) {        this(context , null);    }    public EMSubtitleView(Context context, AttributeSet attrs) {        this(context, attrs , 0);    }    public EMSubtitleView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mSubtitleItemList = new ArrayList<>();        mLinesTextList = null;        mLastHLRect = new Rect();        mNormalPaint = null;        initAttrs(attrs , defStyleAttr);    }    private void initAttrs(AttributeSet attrs , int defStyleAttr) {        TypedArray ta = getContext().obtainStyledAttributes(attrs , R.styleable.EMSubtitleView , defStyleAttr , R.style.EMSubtitleViewDefaultTheme);        for(int i = 0 ; i < ta.getIndexCount() ; i++){            int index = ta.getIndex(i);            if (index == R.styleable.EMSubtitleView_highLightTextColor) {                mHLTextColor = ta.getColor(index, getResources().getColor(R.color.emvideovisit_color_FF9000));            }        }        ta.recycle();    }    private void initHLPaint() {        mHLPaint = new Paint(mNormalPaint);        mHLPaint.setColor(mHLTextColor);        mHLPaint.setTextSize(getTextSize());    }        public void setRichText(String text){        mIsPlain = false;        reset();        setText(text);        setDuration(mDuration , true);    }        public void setPlainText(String text){        mIsPlain = true;        reset();        setText(text);    }    @Override    protected void onDraw(canvas canvas) {        if (mMeasuredWidth == 0 || mMeasuredHeight == 0) {            mMeasuredWidth = getMeasuredWidth();            mMeasuredHeight = getMeasuredHeight();        }        if(mIsPlain){            super.onDraw(canvas);            return;        }        if(mNormalPaint == null){            super.onDraw(canvas);            mNormalPaint = getPaint();            initHLPaint();            return;        }        if(mLinesTextList == null){            fillLinesEntityListJustOnce();        }        //没有pts,绘制        if(mPts <= 0){            drawNormalText(canvas);            return;        }        drawNormalText(canvas);        calculateReadLineAndWordsCount();        //绘制高亮部分歌词        drawHLText(canvas);    }    private void drawHLText(Canvas canvas) {        if(mCurHLLine >= 0){            int curLineTextCount = 0;            for(int i = 0 ; i < mLinesTextList.size() ; ++i){                LineEntity entity = mLinesTextList.get(i);                if(mCurHLLine > i){                    canvas.drawText( entity.lineText , entity.left , entity.baseLine , mHLPaint);                }else if(mCurHLLine == i && mReadSubtitleCount > 0 ){                    canvas.save();                    mLastHLRect.set(entity.left , entity.top , entity.left + (int) (mHLPaint.measureText(entity.lineText)*1.0f/entity.lineText.length()*(mReadSubtitleCount-curLineTextCount)), entity.bottom);                    canvas.clipRect(mLastHLRect );                    canvas.drawText( entity.lineText , entity.left , entity.baseLine , mHLPaint);                    canvas.restore();                    //遮挡的话需要滚动                    if(entity.baseLine > getHeight()){                        if(getScrollY() != entity.bottom - getHeight() + 1){                            setScrollY( entity.bottom - getHeight() + 1);                        }                    }                    break;                }                curLineTextCount += entity.lineText.length();            }        }    }    private void calculateReadLineAndWordsCount() {        float curSubtitleCount = 0;        for(SubtitleItem subtitleItem :  mSubtitleItemList){            //文字之间不可以有空隙,否则mCurHLLine可能一直为-1;            if(mPts >= subtitleItem.getStartTime() && mPts < subtitleItem.getEndTime()){                float lineOffset = (subtitleItem.getWords().length()*1.0f/(subtitleItem.getEndTime() - subtitleItem.getStartTime()))*(mPts-subtitleItem.getStartTime());                curSubtitleCount += lineOffset;                int curLineTextCount = 0;                for(int i = 0 ; i < mLinesTextList.size() ; ++i){                    curLineTextCount += mLinesTextList.get(i).lineText.length();                    if(curLineTextCount > curSubtitleCount){                        mCurHLLine = i;                        break;                    }                }                break;            }            curSubtitleCount += subtitleItem.getWords().length();        }        mReadSubtitleCount = curSubtitleCount;    }    private void fillLinesEntityListJustOnce() {        if(mLinesTextList != null){            return;        }        mLinesTextList = new ArrayList<>();        Layout layout = getLayout();        int line=getLayout().getLineCount();        String text=layout.getText().toString();        for(int i=0;i<line;i++){            int start=layout.getLineStart(i);            int end=layout.getLineEnd(i);            int left = (int) layout.getLineLeft(i);            int baseLine = layout.getLineBaseline(i);            Paint.FontMetrics fontMetrics = getPaint().getFontMetrics();            int top = (int) (baseLine + fontMetrics.top);            int bottom = (int) (baseLine + fontMetrics.bottom);            int ascent = (int) (baseLine + fontMetrics.ascent);            int descent = (int) (baseLine + fontMetrics.descent);            mLinesTextList.add(new LineEntity(text.substring(start, end) , top , bottom , ascent , descent ,baseLine , left));        }    }    private void drawNormalText(Canvas canvas) {        for(LineEntity entity : mLinesTextList){            canvas.drawText(entity.lineText, entity.left,  entity.baseLine , mNormalPaint);        }    }    public List<SubtitleItem> getSubtitleItemList() {        return mSubtitleItemList;    }        public void setSubtitleItemList(List<SubtitleItem> linesTextList) {        if(mSubtitleItemList != null){            mSubtitleItemList.clear();            mSubtitleItemList.addAll(linesTextList);        }else{            this.mSubtitleItemList = linesTextList;        }    }        public void setDuration(long duration){        setDuration( duration , false);    }    private void setDuration(long duration , boolean force){        if((duration > 0 && mDuration != duration) || force){            mDuration = duration;            if(mSubtitleItemList != null){                mSubtitleItemList.clear();            }else{                this.mSubtitleItemList = new ArrayList<>();            }            mSubtitleItemList.add(new SubtitleItem(getText().toString() , 0 , duration));        }    }        public void updatePts(long pts){        mPts = pts;        postInvalidate();    }        public void reset(){        mPts = 0;        mCurHLLine = 0;        mReadSubtitleCount = 0;        mLinesTextList = null;        mNormalPaint = null;        setScrollY(0);        postInvalidate();    }    static class LineEntity{       String lineText;       int top;       int bottom;       int ascent;       int descent;       int baseLine;       int left;        public LineEntity(String lineText, int top, int bottom, int ascent, int descent, int baseLine, int left) {            this.lineText = lineText;            this.top = top;            this.bottom = bottom;            this.ascent = ascent;            this.descent = descent;            this.baseLine = baseLine;            this.left = left;        }    }}

布局文件里使用类似如下:

<com.eastmoney.emvideovisit.view.EMSubtitleView        android:id="@+id/play_text"        android:layout_width="match_parent"        android:layout_height="@dimen/emvideovisit_dp_60"        android:layout_marginLeft="@dimen/emvideovisit_dp_60"        android:layout_marginRight="@dimen/emvideovisit_dp_60"        android:gravity="center_horizontal"        android:layout_marginTop="@dimen/emvideovisit_dp_20"        android:textColor="#fff"        app:highLightTextColor="#A6EA5504"        android:text="@string/emvideovisit_string_headset_tips"        android:textSize="@dimen/emvideovisit_dp_16"        android:layout_marginBottom="@dimen/emvideovisit_dp_4"/>

3、其它

处理过程中文字位置的参数需要注意:

Android如何实现文字动态高亮读取进度效果

Android是什么

Android是一种基于linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发

看完了这篇文章,相信你对“Android如何实现文字动态高亮读取进度效果”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网精选频道,感谢各位的阅读!

--结束END--

本文标题: Android如何实现文字动态高亮读取进度效果

本文链接: https://www.lsjlt.com/news/277507.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • Android如何实现文字动态高亮读取进度效果
    小编给大家分享一下Android如何实现文字动态高亮读取进度效果,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体内容如下1、效果图类似歌词的效果。播放下面文字的音频,同时音频播放的进度和文字高亮进度保持一致。2、代码结构...
    99+
    2023-06-15
  • Android实现文字动态高亮读取进度效果
    本文实例为大家分享了Android实现文字动态高亮读取进度的具体代码,供大家参考,具体内容如下 1、效果图 类似歌词的效果。播放下面文字的音频,同时音频播放的进度和文字高亮进度保持一...
    99+
    2024-04-02
  • Flutter如何实现文本滚动高亮效果
    这篇文章主要介绍“Flutter如何实现文本滚动高亮效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Flutter如何实现文本滚动高亮效果”文章能帮助大家解决问题。功能实现因为在Text中会存在两...
    99+
    2023-06-29
  • vue实现动态进度条效果
    本文实例为大家分享了vue实现动态进度条效果的具体代码,供大家参考,具体内容如下 演示效果: 结构 progress/index.js const controller = ...
    99+
    2024-04-02
  • Android 如何实现亮度自动调节
    目录源码版本概述源码梳理1、BrightnessDialog#onCreate:2、这里进行了 BrightnessController 初始化,来看下:3、回到 Brightnes...
    99+
    2024-04-02
  • 如何运用CSS3动画实现高亮光弧效果
    小编给大家分享一下如何运用CSS3动画实现高亮光弧效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!代码如下:<!Doct...
    99+
    2024-04-02
  • Qt实现炫酷启动图动态进度条效果
    目录一、简述二、动效进度条1、光效进度条2、延迟到达进度条3、接口说明三、启动图1、实现思路2、背景图切换四、测试1、构造启动图2、背景图3、其他信息4、事件循环五、源码一、简述 最...
    99+
    2024-04-02
  • Android如何实现列表元素动态效果
    这篇文章主要介绍了Android如何实现列表元素动态效果的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android如何实现列表元素动态效果文章都会有所收获,下面我们一起来看看吧。前言列表是移动应用中用得最多的...
    99+
    2023-06-29
  • bootstrap进度条动态加载效果怎么实现
    要实现进度条的动态加载效果,可以使用Bootstrap的进度条组件,并结合JavaScript来更新进度条的值。首先,在HTML中添...
    99+
    2023-08-24
    bootstrap
  • HTML如何实现滚动文字效果
    小编给大家分享一下HTML如何实现滚动文字效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在HTML中,可以使用marquee标签实现滚动文字效果,该标签可以向...
    99+
    2023-06-15
  • Android如何实现状态栏白底黑字效果
    这篇文章给大家分享的是有关Android如何实现状态栏白底黑字效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、描述在项目中有的时候Ui设计状态栏背景颜色是白色的,虽然还挺好看,不过可坑了我们做程序的,需要对...
    99+
    2023-05-30
    android
  • Flutter实现文本滚动高亮效果的示例讲解
    目录前言功能实现前言 最近有个需求是人工语音播放时文本能随语音朗读时像歌词滚动的效果. 原本第一考虑的时能随时间字体渐变成更改后的颜色, 有比较流畅的走马灯效果. 但最终实践了几次后...
    99+
    2024-04-02
  • Android实现点汇聚成字的动态效果详解
    目录前言点阵点阵图形绘制由点聚集成字的动画实现总结前言 在引入 fl_chart 绘制图表的时候,看到插件有下面这样的动效,随机散乱的圆点最后组合成了 Flutter 的 Logo,...
    99+
    2024-04-02
  • CSS如何实现图片高亮光弧效果
    这篇文章主要介绍了CSS如何实现图片高亮光弧效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 CSS3实现的一个高亮光弧效果,当鼠标ho...
    99+
    2024-04-02
  • js如何实现文字滚动的效果
    这篇文章主要介绍“js如何实现文字滚动的效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“js如何实现文字滚动的效果”文章能帮助大家解决问题。1、取值:(1)writing-mode:horizon...
    99+
    2023-07-02
  • Android怎么实现点汇聚成字的动态效果
    本篇内容主要讲解“Android怎么实现点汇聚成字的动态效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android怎么实现点汇聚成字的动态效果”吧!点阵在讲解代码实现之前,我们先科普一个知...
    99+
    2023-07-02
  • Android项目中如何实现获取状态栏的高度
    这篇文章将为大家详细讲解有关Android项目中如何实现获取状态栏的高度,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。方法一:private double getStatusBarHeigh...
    99+
    2023-05-31
    android roi 目中
  • 如何用javascript实现文字滚动效果
    这篇文章主要介绍“如何用javascript实现文字滚动效果”,在日常操作中,相信很多人在如何用javascript实现文字滚动效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解...
    99+
    2024-04-02
  • CSS3怎么实现歌词进度文字颜色填充变化动态效果的思路
    这篇文章将为大家详细讲解有关CSS3怎么实现歌词进度文字颜色填充变化动态效果的思路,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。播放音乐时,歌词会随歌曲的进度逐渐填充颜色,不是逐字改变颜色,而是从左向右横...
    99+
    2023-06-08
  • 如何利用css3实现进度条效果及动态添加百分比
    这篇文章主要介绍了如何利用css3实现进度条效果及动态添加百分比,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。代码:<!DOCTYPE html><...
    99+
    2023-06-08
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作