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

系列文章

安卓原生聊天面板开发(一)整体规划
安卓原生聊天面板开发(二)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);
    }

(四)倒计时的实现

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

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

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

源码

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

即可获得:

相关推荐
emoji11111120 分钟前
vue3、原生html交互传值
vue.js·html·交互
Yang-Never25 分钟前
Git -> Git使用Patch失败error: patch failed: patch does not apply的解决办法
android·git·android studio
woodWu2 小时前
Android编译时动态插入代码原理与实践
android
百锦再3 小时前
Android Studio 实现自定义全局悬浮按钮
android·java·ide·app·android studio·安卓
百锦再3 小时前
Android Studio 项目文件夹结构详解
android·java·ide·ios·app·android studio·idea
老码识土3 小时前
Kotlin 协程源代码泛读:Continuation
android·kotlin
行墨4 小时前
Replugin 的hook点以及hook流程
android·架构
一一Null4 小时前
Access Token 和 Refresh Token 的双令牌机制,维持登陆状态
android·python·安全·flask
_祝你今天愉快5 小时前
深入理解 Android Handler
android
pengyu6 小时前
【Flutter 状态管理 - 四】 | setState的工作机制探秘
android·flutter·dart