在此感谢鸿洋大神,因为我这是在慕课上看大神的视频做出来的。
代码中我已经添加了很多很多注释,不光是为了大家,也是为了自己能够更加透彻的理解该功能
支持原创,也不算原创了哈哈~
http://blog.csdn.net/lhk147852369/article/details/78658055
注意注意:
Android 6.0动态获取录音权限,我并没有加上,所以你们需要在写完代码后,运行时在权限管理中指定该权限
否则会崩溃哦~~, 当然你们可以改变as中的targerversion<23就可以了
话不多说,直接上效果图:
MainActivity :
主页面:需要注意:改下自定义button的包名哦,不然会找不到的
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context="com.lgoutech.weixin_recorder.MainActivity">
-
- <ListView
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:id="@+id/id_listview"
- android:background="#ebebeb"
- android:divider="@null"
- android:dividerHeight="10dp"
- ></ListView>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- >
- <View
- android:layout_width="wrap_content"
- android:layout_height="1dp"
- android:background="#ccc"
- />
- <com.lgoutech.weixin_recorder.view.AudioRecorderButton
- android:id="@+id/id_recorder_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="50dp"
- android:layout_marginRight="50dp"
- android:gravity="center"
- android:layout_marginTop="7dp"
- android:layout_marginBottom="7dp"
- android:padding="5dp"
- android:text="@string/str_recorder_normal"
- android:textColor="#727272"
- android:background="@drawable/btn_recorder_normal"
- android:minHeight="0dp"
- >
-
- </com.lgoutech.weixin_recorder.view.AudioRecorderButton>
-
-
- </LinearLayout>
- </LinearLayout>
自定义的dialog、xml文件:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:padding="20dp"
- android:gravity="center"
- android:background="@drawable/dialog_loading_bg"
- tools:context="com.lgoutech.weixin_recorder.MainActivity">
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- >
- <ImageView
- android:id="@+id/id_recorder_dialog_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/recorder"
- android:visibility="visible"
- />
- <ImageView
- android:id="@+id/id_recorder_dialog_voice"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/v1"
- android:visibility="visible"
- />
- </LinearLayout>
- <TextView
- android:id="@+id/id_recorder_dialog_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="5dp"
- android:text="手指上划,取消发送"
- android:textColor="#FFFFFF"
- />
- </LinearLayout>
ListView的Item布局:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="60dp"
- android:layout_marginTop="5dp"
- tools:context="com.lgoutech.weixin_recorder.MainActivity">
- <ImageView
- android:id="@+id/id_icon"
- android:layout_width="40dp"
- android:layout_height="40dp"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:layout_marginRight="5dp"
- android:src="@drawable/icon"
- />
-
- <LinearLayout
- android:id="@+id/id_recorder_length"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:orientation="vertical"
- android:layout_toLeftOf="@id/id_icon"
- android:background="@drawable/chatto_bg_focused"
- >
-
- <View
- android:id="@+id/id_recorder_anim"
- android:layout_width="25dp"
- android:layout_height="25dp"
- android:layout_gravity="center_vertical|right"
- android:background="@drawable/adj"
- />
-
- </LinearLayout>
-
- <TextView
- android:id="@+id/id_recorder_time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toLeftOf="@id/id_recorder_length"
- android:layout_marginRight="3dp"
- android:textColor="#ff777777"
- android:layout_centerVertical="true"
- />
-
- </RelativeLayout>
录音管理类:
最重要的自定义按钮,很多逻辑都在这里:
Dialog管理类:
- public class DialogManager {
- private Dialog mDialog;
-
- private ImageView mIcon;
- private ImageView mVoice;
-
- private TextView mLable;
-
- private Context mContext;
-
- public DialogManager(Context context){
- mContext = context;
- }
-
- public void showRecordingDialog(){
- mDialog = new Dialog(mContext, R.style.Theme_AudioDialog);
- LayoutInflater inflater = LayoutInflater.from(mContext);
- View view=inflater.inflate(R.layout.dialog_recorder,null);
- mDialog.setContentView(view);
-
- mIcon = view.findViewById(R.id.id_recorder_dialog_icon);
- mVoice = view.findViewById(R.id.id_recorder_dialog_voice);
- mLable = view.findViewById(R.id.id_recorder_dialog_label);
-
- mDialog.show();
- }
-
- //正在播放时的状态
- public void recording() {
- if (mDialog != null&&mDialog.isShowing()) {
- mIcon.setVisibility(View.VISIBLE);
- mVoice.setVisibility(View.VISIBLE);
- mLable.setVisibility(View.VISIBLE);
-
- mIcon.setImageResource(R.drawable.recorder);
- mLable.setText("手指上划,取消发送");
- }
- }
- //想要取消
- public void wantToCancel(){
- if (mDialog != null&&mDialog.isShowing()) {
- mIcon.setVisibility(View.VISIBLE);
- mVoice.setVisibility(View.GONE);
- mLable.setVisibility(View.VISIBLE);
-
- mIcon.setImageResource(R.drawable.cancel);
- mLable.setText("松开手指,取消发送");
- }
- }
- //录音时间太短
- public void tooShort() {
- if (mDialog != null&&mDialog.isShowing()) {
- mIcon.setVisibility(View.VISIBLE);
- mVoice.setVisibility(View.GONE);
- mLable.setVisibility(View.VISIBLE);
-
- mIcon.setImageResource(R.drawable.voice_to_short);
- mLable.setText("录音时间过短");
- }
- }
- //关闭dialog
- public void dimissDialog(){
- if (mDialog != null&&mDialog.isShowing()) {
- mDialog.dismiss();
- mDialog = null;
- }
- }
-
- /**
- * 通过level更新voice上的图片
- *
- * @param level
- */
- public void updateVoiceLevel(int level){
- if (mDialog != null&&mDialog.isShowing()) {
-
- int resId = mContext.getResources().getIdentifier("v" + level, "drawable", mContext.getPackageName());
- mVoice.setImageResource(resId);
- }
- }
- }
播放录音类:- /**
- * Created by Administrator on 2017/11/28.
- * 播放录音类
- */
-
- public class MediaManager {
- private static MediaPlayer mMediaPlayer;
-
- private static boolean isPause;
-
- //播放录音
- public static void playSound(String filePath, MediaPlayer.OnCompletionListener onCompletionListener){
- if (mMediaPlayer == null) {
- mMediaPlayer = new MediaPlayer();
- //播放错误 防止崩溃
- mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
- @Override
- public boolean onError(MediaPlayer mp, int what, int extra) {
- mMediaPlayer.reset();
- return false;
- }
- });
- }else{
- mMediaPlayer.reset();
- }
- try {
- mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
- mMediaPlayer.setOnCompletionListener(onCompletionListener);
- mMediaPlayer.setDataSource(filePath);
- mMediaPlayer.prepare();
- mMediaPlayer.start();
-
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
-
- /**
- * 如果 播放时间过长,如30秒
- * 用户突然来电话了,则需要暂停
- */
- public static void pause() {
- if (mMediaPlayer != null&&mMediaPlayer.isPlaying()) {
- mMediaPlayer.pause();
- isPause = true;
- }
- }
-
- /**
- * 播放
- */
- public static void resume(){
- if (mMediaPlayer != null && isPause) {
- mMediaPlayer.start();
- isPause = false;
- }
- }
-
- /**
- * activity 被销毁 释放
- */
- public static void release(){
- if (mMediaPlayer != null) {
- mMediaPlayer.release();
- mMediaPlayer = null;
- }
- }
- }
listview 的Adapter:- /**
- *list的adapter
- * Created by Administrator on 2017/11/28.
- */
-
- public class RecorderAdapter extends ArrayAdapter<Recorder> {
-
- //item 最小最大值
- private int mMinItemWidth;
- private int mMaxIItemWidth;
-
- private LayoutInflater mInflater;
-
- public RecorderAdapter(@NonNull Context context, List<Recorder> datas) {
- super(context,-1, datas);
- mInflater = LayoutInflater.from(context);
-
- //获取屏幕宽度
- WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics outMetrics = new DisplayMetrics();
- wm.getDefaultDisplay().getMetrics(outMetrics);
-
- //item 设定最小最大值
- mMaxIItemWidth = (int) (outMetrics.widthPixels * 0.7f);
- mMinItemWidth = (int) (outMetrics.widthPixels * 0.15f);
- }
-
- @NonNull
- @Override
- public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
-
- ViewHolder holder = null;
- if (convertView == null) {
- convertView = mInflater.inflate(R.layout.item_recorder, parent, false);
- holder = new ViewHolder();
- holder.seconds = convertView.findViewById(R.id.id_recorder_time);
- holder.length = convertView.findViewById(R.id.id_recorder_length);
- convertView.setTag(holder);
- }else {
- holder = (ViewHolder) convertView.getTag();
- }
- //设置时间 matt.round 四舍五入
- holder.seconds.setText(Math.round(getItem(position).time)+"\"");
- //设置背景的宽度
- ViewGroup.LayoutParams lp = holder.length.getLayoutParams();
- //getItem(position).time
- lp.width = (int) (mMinItemWidth + (mMaxIItemWidth / 60f*getItem(position).time));
-
- return convertView;
- }
-
- private class ViewHolder{
- TextView seconds;
- View length;
- }
- }
在string.xml中
- <string name="str_recorder_normal">按住说话</string>
- <string name="str_recorder_recording">松开结束</string>
- <string name="str_recorder_want_cancel">松开手指,取消发送</string>
在style.xml中
- <style name="Theme_AudioDialog">
- <item name="android:windowBackground">@android:color/transparent</item>
- <!--Dialog的windowFrame框为无-->
- <item name="android:windowFrame">@null</item>
- <!--是否浮现在activity之上-->
- <item name="android:windowIsFloating">true</item>
- <!--//是否半透明-->
- <item name="android:windowIsTranslucent">true</item>
- <!--/背景是否模糊显示-->
- <item name="android:backgroundDimEnabled">true</item>
- </style>
好了以上就是所有的代码了。
不懂得可以问我哦,或者自己查查百度吧。
我的注释已经很多了,理理逻辑,应该很好懂的。
图片资源:资源图片
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。