安卓原生聊天面板开发(三)录音交互实现

系列文章

安卓原生聊天面板开发(一)整体规划
安卓原生聊天面板开发(二)emoji功能实现
安卓原生聊天面板开发(三)录音交互实现
安卓原生聊天面板开发(四)整体交互实现

背景

产品喝大了,说开发一个聊天界面,功能参照微信即可。

这是应了那句话:新人一开口,便知有没有~~真是风趣幽默。

问题分析

其实仔细看微信的聊天面板,功能拆分出来,主要有以下几点:

(1)emoji表情,自定义表情等等。这里可以归类为"表情"tab。

(2)语音交互,音频录制播放压缩。

(3)媒体交互,选择图片,视频,文件等等。

核心就是上面的内容,锦上添花的功能就不再叙述了。

实现效果

开发环境

win10

jdk8+

as2024+

本文内容

本文将会讲解实现录音动画的最核心思路。文末将会有源码地址。

先看效果图

思路大纲

对于实现这种需求,正常的做法就是拆分,看看到底有哪些状态。

(1)没有录音

(2)录音中--手指在移动范围

(2)录音中--手指在超过范围

(4)录音结束

总体就是这四个小状态。而其中,难点就是动画的播放,特别是黑色提示框的显示与收起(插件是一个view,而提示框是一个全局的,可以是任何位置的view,有可能覆盖在输入框上面)

核心实现

(一)动画

动画的播放,这里选择的是svga,因为其轻量,保真度高,所以选这个。官方提供的示例代码中,有两种方式可以实现动画的播放:

(1)使用提供的控件,在xml布局中声明好相关属性,进行播放

(2)先加载资源文件生成一个svgadrawable,然后动态设置到控件中,进行处理。

博主选择了第二种。第二种的好处就是,可以复用,也可以按需加载,定制度高,而且还能有自己的动画对象管理。

加载svga文件核心代码如下:

        mSvgaAnimManager.loadAssets(getContext(), ChatInputResConst.SVGA_RECORD, null, new SVGALoadListener() {
            @Override
            public void complete(SVGAVideoEntity entity) {
                //播放完成
                mSvgaDrawable = new SVGADrawable(entity);
                mSvgaInit = true;
            }

            @Override
            public void error() {
                //错误
            }
        });

暂停,开始播放相关代码:

    private void startAnim() {
        if (!mSvgaInit || mSvgaAnimView == null) {
            return;
        }
        stopAnim();
        mSvgaAnimView.setImageDrawable(mSvgaDrawable);
        mSvgaAnimView.startAnimation();
    }

    private void stopAnim() {
        if (mSvgaAnimView == null) {
            return;
        }
        mSvgaAnimView.stopAnimation();
        mSvgaAnimView.setImageDrawable(null);
    }

在初始化的时候,就进行svga的资源获取,至于什么使用进行播放,就按需处理。这样做的最大好处,就是能够统一管理播放资源。

(二)黑色提示框

这个提示框,其实并不是在当前布局中实现的,因为不能贴合需求。

那么怎样能够让这个提示框,不再收到当前布局的约束?

答案就是decoreview

通过activity context,可以获取到一个DecoreView。至于DecoreView是什么,请自行百度,因为细节有很多细节。

那么有了这个DecoreView,我们是不是可以在里面,添加view(AddView),和移除view(removeView)了?

再者,结合view.getViewWindowLocation方法,就可以获取你想要显示的位置了。当然要注意的是,宽高获取以及处理。

请注意svga控件的用法,如播放完清空画布等操作

就是这么简单~~

(三)触摸事件的分发

需求就是,点击录音按钮,就做动画,移动超过了范围,就另作处理。

核心就是,子控件(录音按钮)只做一个触发,当收到按下的事件时,就开始录音,然后其父控件,做全部的事件分发处理,这些事件,都可以在父控件中捕获,前提是重写了父控件的事件分发方法。核心代码如下:

父控件分发:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                ChatLogUtils.log("root ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                dealMoveEvent(event);
                break;
            case MotionEvent.ACTION_UP:
                ChatLogUtils.log("root ACTION_UP");
                stopRecordEvent(mIsIntRange);
                break;
            case MotionEvent.ACTION_CANCEL:
                ChatLogUtils.log("root ACTION_CANCEL");
                stopRecordEvent(mIsIntRange);
                break;
        }
        return true;
    }

子控件分发:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                ChatLogUtils.log("button ACTION_DOWN");
                if (mListener != null) {
                    mListener.click();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                ChatLogUtils.log("button ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                ChatLogUtils.log("button ACTION_UP");
                break;
            case MotionEvent.ACTION_CANCEL:
                ChatLogUtils.log("button ACTION_CANCEL");
                break;
        }
        return super.onTouchEvent(event);
    }

(四)倒计时的实现

那么上面的事件分发,我们可以做到:开始,播放中,停止。这些周期的监听,那么倒计时也是一样的,在这些周期方法中,进行停止计时,开始计时,即可。

注意一个点,在按下的过程中,倒计时到头了,那么,也要处理好一个调整到初始状态的操作。

上述就是整个录音交互实现的思路,详细源码,文末可获取。

源码

源码获取方式,关注回复: 安卓原生聊天面板源码

即可获得:

相关推荐
诸神黄昏EX42 分钟前
Android 分区相关介绍
android
大白要努力!2 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee2 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood2 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-5 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen7 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年14 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿17 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
dot.Net安全矩阵18 小时前
.NET 通过模块和驱动收集本地EDR的工具
windows·安全·web安全·.net·交互
1024小神18 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri