Android实现客户端语音动弹界面实例代码
作者:mrr 发布时间:2023-03-04 08:27:04
今天为大家介绍一下语音动弹界面的实现,新版本的客户端大家应该都看过了,这里我就只简单的介绍一下控件布局了。你可以在这里看到本控件的完整源码:http://git.oschina.net/oschina/android-app/blob/master/osc-android-app/src/net/oschina/app/widget/RecordButton.java
首先,整体界面分三部分,最上层自定义ActionBar相信不需要我讲大家就能看出来了。
中间部分是文字动弹部分,主体就是一个设置了Padding(margin)的EditText,在EditText下面是一个剩余输入字数的描述。其实在“您还可以输入XX字”的左边还有一个用于显示录音图标的ImageView.
最下层是本文主要讲解的录音自定义控件的实现。
下面一整块整体都是自定义控件的区域,我将其命名为RecordButton,是一个继承自RelateiveLayout的ViewGroup。
在其中包括了左中右三个ImageView:试听与删除,中间的录音按钮。
在录音按钮的上下各有一个用于提示的TextView。
整体布局的载入可以通过调用 View.inflater(cxt, R.layout.xxx, null);
就行了。
同前一篇讲的一样,作为控件界面控制逻辑,我们主要看一下onTouchEvent方法:当手指按下的时候,初始化录音器。手指在屏幕上移动的时候如果滑到按钮之上的时候,event.getY会返回一个负值(因为滑出控件了嘛)。这里我写的是-50主要是为了多一点缓冲,防止误操作。
先来看代码
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mAudioFile == null) {
return false;
}
if (!mTouchInPlayButton) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initBorderLine();
break;
case MotionEvent.ACTION_MOVE:
if (event.getY() < 0) {
viewToInit();
break;
}
if (event.getX() > mRightButtonX) {
mIsCancel = true;
scaleView(mImgDelete, 1.5f);
} else if (event.getX() < mLeftButtonX) {
scaleView(mImgListen, 1.5f);
} else {
mIsCancel = false;
viewToInit();
}
break;
case MotionEvent.ACTION_UP:
if (mIsCancel || event.getY() < -50) {
cancelRecord();
} else if (event.getX() < mLeftButtonX) {// 试听
playRecord();
finishRecord();
} else if (event.getX() > mRightButtonX) {// 删除
cancelRecord();
} else {
finishRecord();
}
viewToInit();
bottomFlag.setVisibility(View.VISIBLE);
topFlag.setVisibility(View.GONE);
mIsCancel = false;
mTouchInPlayButton = false;
break;
}
return true;
}
其中录音相关的工具类还是和之前的一样,这就是把功能与视图分开的好处,随时用随时复制粘贴过来就用了。
/**
* {@link #RecordButton}需要的工具类
*
* @author kymjs(http://www.kymjs.com/)
*/
public class RecordButtonUtil {
public static final String AUDOI_DIR = Environment
.getExternalStorageDirectory().getAbsolutePath() + "/oschina/audio"; // 录音音频保存根路径
private String mAudioPath; // 要播放的声音的路径
private boolean mIsRecording;// 是否正在录音
private boolean mIsPlaying;// 是否正在播放
private OnPlayListener listener;
// 初始化 录音器
private void initRecorder() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile(mAudioPath);
mIsRecording = true;
}
/** 开始录音,并保存到文件中 */
public void recordAudio() {
initRecorder();
try {
mRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mRecorder.start();
}
/** 获取音量值,只是针对录音音量 */
public int getVolumn() {
int volumn = 0;
// 录音
if (mRecorder != null && mIsRecording) {
volumn = mRecorder.getMaxAmplitude();
if (volumn != 0)
volumn = (int) (10 * Math.log(volumn) / Math.log(10)) / 7;
}
return volumn;
}
/** 停止录音 */
public void stopRecord() {
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
mIsRecording = false;
}
}
public void startPlay(String audioPath) {
if (!mIsPlaying) {
if (!StringUtils.isEmpty(audioPath)) {
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(audioPath);
mPlayer.prepare();
mPlayer.start();
if (listener != null) {
listener.starPlay();
}
mIsPlaying = true;
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (listener != null) {
listener.stopPlay();
}
mp.release();
mPlayer = null;
mIsPlaying = false;
}
});
} catch (Exception e) {
e.printStackTrace();
}
} else {
AppContext.showToastShort(R.string.record_sound_notfound);
}
} // end playing
}
public interface OnPlayListener {
/** 播放声音结束时调用 */
void stopPlay();
/** 播放声音开始时调用 */
void starPlay();
}
}
如果细心,你会发现左右两个圆形按钮,会随着手指移动到上面的时候放大,这其实也是一个通过监听ontouch事件,对两个圆形按钮设置动画产生的效果,和谐带人就是下面这句了。(注,setScaleX和setScaleY方法只有在API10,也就是3.0以上的版本才能调用):
if (event.getX() > mRightButtonX) {
mIsCancel = true;scaleView(mImgDelete, 1.5f);
} else if (event.getX() < mLeftButtonX) {
scaleView(mImgListen, 1.5f);
} else {
mIsCancel = false;viewToInit();
}
private void scaleView(View view, float scaleXY) {
if (android.os.Build.VERSION.SDK_INT > 10) {
view.setScaleX(scaleXY);
view.setScaleY(scaleXY);
}
}
总结
以上所述是小编给大家介绍的Android实现客户端语音动弹界面实例代码网站的支持!
来源:https://my.oschina.net/kymjs/blog/424455


猜你喜欢
- 上一篇:瑞吉外卖项目:新增员工一. 员工信息分页查询1. 需求分析当系统中的用户越来越多页面展示不完整,我们需要通过实现分页的方式去展示员工
- 见过一句夸张的话,叫做“没有阅读过jdk源码的人不算学过java”。从今天起开始精读源码。而适合精读的源码无非就是java.io,.util
- 1>方法一之前在配置 Maven 的 settings.xml 时,都会设置 mirror 节点,例如:<mirrors>
- 本文实例讲述了Android自定义ViewPager的方法。分享给大家供大家参考,具体如下:package com.rong.activit
- C#编写一个简易计算器,供大家参考,具体内容如下界面代码using System;using System.Collections.Gene
- 一、概述xml整合第三方框架有两种整合方案:不需要自定义名空间,不需要使用Spring的配置文件配置第三方框架本身内容,例如:MyBatis
- 目录Handler概要构造器sendMessageAtTimedispatchMessageThreadLocalLooperMessage
- 前言介绍最近很多同学找我帮忙做一些课程设计或Web前端大作业、其中控制台项目应该是初学者必须经历的一个过程、作为java初学者这个控制台版本
- 本文实例介绍了Android实现手机震动、抖动效果,分享给大家供大家参考,具体内容如下(1)布局文件如下<RelativeLayout
- 动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的
- 快速排序是应用最广泛的排序算法,流行的原因是它实现简单,适用于各种不同情况的输入数据且在一般情况下比其他排序都快得多。快速排序是原地排序(只
- 这篇文章主要介绍了SpringBoot如何读取war包jar包和Resource资源,文中通过示例代码介绍的非常详细,对大家的学习或者工作具
- 本文实例讲述了android从系统图库中取图片的实现方法。分享给大家供大家参考。具体如下:在自己应用中,从系统图库中取图片,然后截取其中一部
- 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异
- 要获得打印机的状态,应该定义一个联合.enum PrinterStatus { 其他状态= 1, 未知, 空闲
- 一般项目做到后期,在测试的时候,需要在测试版本和正式版本之间进行频繁的切换,怎么办呢?土豪的话可以考虑使用两台机器,同时测试,然而为了方便测
- 本文实例为大家分享了javaweb购物车案列的具体代码,供大家参考,具体内容如下一、项目目录结构 二、源代码dao包——dao层:
- 一、项目简述功能包括: 用户管理,系统管理,客户管理,客户服务,客户关怀, 销售机会,统计管理等等。二、项目运行环境配置: Jdk1.8 +
- 在这篇文章中,我们将介绍如下内容:==运算符与基元类型==运算符与引用类型==运算符与String类型==运算符与值类型==运算符与泛型==
- java简单模拟微信抢红包功能,本例发100元红包,有10个人抢,为了尽可能的公平,每个人的红包金额都要随机(保证结果的不确定性,本例抢红包