在上一篇中,我们实现了核心的录音功能。当然,此时你是没有感觉的,因为我们还没法把它播放出来,所以你还不知道到底有没有录音实现。没读过上一篇的朋友,请点击一下链接:
http://www.cnblogs.com/fuly550871915/p/4836204.html
在这一篇中,我们将实现把录音显示在我们早就设计好的ListView里面,并且点击时,会播放录音。实现过程相对来说比较复杂一些。但是只要有耐心,就能做的好。好了,废话不多说,我们直接看代码。
首先,我们来实现播放器,代码如下:
1 package com.fuly.util; 2 3 import java.io.IOException; 4 5 import android.media.AudioManager; 6 import android.media.MediaPlayer; 7 import android.media.MediaPlayer.OnErrorListener; 8 9 10 //播放录音的类 11 public class RecoderPlayer { 12 13 14 private static MediaPlayer mMediaPlayer; 15 private static boolean isPause = false;//是否为暂停播放 16 17 18 //播放音乐 19 20 public void playSound(String filePath) { 21 22 if(mMediaPlayer == null){ 23 24 mMediaPlayer = new MediaPlayer(); 25 mMediaPlayer.setOnErrorListener(new OnErrorListener() { 26 27 public boolean onError(MediaPlayer mp, int what, int extra) { 28 29 mMediaPlayer.reset(); 30 return false; 31 } 32 }); 33 }else{ 34 mMediaPlayer.reset(); 35 36 } 37 38 39 40 try { 41 mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 42 mMediaPlayer.setDataSource(filePath); 43 mMediaPlayer.prepare(); 44 mMediaPlayer.start(); 45 } catch (IllegalArgumentException e) { 46 e.printStackTrace(); 47 } catch (SecurityException e) { 48 e.printStackTrace(); 49 } catch (IllegalStateException e) { 50 e.printStackTrace(); 51 } catch (IOException e) { 52 e.printStackTrace(); 53 } 54 55 } 56 57 58 //暂停播放 59 public static void pause(){ 60 61 if(mMediaPlayer != null && mMediaPlayer.isPlaying()){ 62 mMediaPlayer.pause(); 63 isPause = true; 64 } 65 66 } 67 68 //复位播放 69 70 public static void reset(){ 71 72 if(mMediaPlayer != null && isPause){ 73 74 mMediaPlayer.start(); 75 isPause = false; 76 } 77 } 78 79 //释放资源 80 public static void release(){ 81 82 if(mMediaPlayer != null){ 83 mMediaPlayer.release(); 84 mMediaPlayer = null; 85 } 86 } 87 88 }
接下来就要考虑将播放器集成到ListView中了。首先我们需要一个封装音频信息的类,包括录音的时长和录音存放的绝对路径。代码如下:
1 package com.fuly.util; 2 3 //封装录音信息的类 4 public class Recoder { 5 6 public int mTime; 7 public String filePath; 8 9 10 public Recoder(int mTime, String filePath) { 11 super(); 12 this.mTime = mTime; 13 this.filePath = filePath; 14 } 15 16 17 public int getmTime() { 18 return mTime; 19 } 20 21 22 public void setmTime(int mTime) { 23 this.mTime = mTime; 24 } 25 26 27 public String getFilePath() { 28 return filePath; 29 } 30 31 32 public void setFilePath(String filePath) { 33 this.filePath = filePath; 34 } 35 36 37 38 39 40 }
然后为ListView的子项编写布局:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="@color/white"> 6 7 <ImageView 8 android:id="@+id/id_icon" 9 android:layout_width="65dp" 10 android:layout_height="65dp" 11 android:src="@drawable/icon" 12 android:layout_marginRight="5dp" 13 android:layout_marginTop="5dp" 14 android:layout_alignParentRight="true"/> 15 16 <FrameLayout 17 android:id= "@+id/id_frame" 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content" 20 android:layout_toLeftOf="@id/id_icon" 21 android:background="@drawable/chatto_bg_focused" 22 android:layout_marginRight="5dp" 23 android:layout_marginTop="5dp"> 24 25 <ImageView 26 android:id="@+id/img_voice" 27 android:layout_width="match_parent" 28 android:layout_height="match_parent" 29 android:background="@drawable/adj"/> 30 31 </FrameLayout> 32 33 <TextView 34 android:id ="@+id/tv_time" 35 android:layout_width="wrap_content" 36 android:layout_height="wrap_content" 37 android:layout_toLeftOf="@id/id_frame" 38 android:layout_marginRight="3dp" 39 android:text="" 40 android:textColor="@color/red" 41 android:layout_marginTop="20dp"/> 42 43 44 45 46 </RelativeLayout>
然后ListView需要一个适配器,我们建立出来,如下:
1 package com.fuly.util; 2 3 import java.util.List; 4 5 import com.fuly.irecoder.R; 6 7 import android.content.Context; 8 import android.util.DisplayMetrics; 9 import android.view.LayoutInflater; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.view.ViewGroup.LayoutParams; 13 import android.view.WindowManager; 14 import android.widget.ArrayAdapter; 15 import android.widget.FrameLayout; 16 import android.widget.ImageView; 17 import android.widget.TextView; 18 19 public class MyAdapter extends ArrayAdapter<Recoder> { 20 21 private Context mContext; 22 23 private int width;//屏幕宽度 24 25 public MyAdapter(Context context, List<Recoder> datas) { 26 super(context, -1,datas ); 27 mContext = context; 28 29 //下面的代码为获得屏幕宽度 30 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 31 DisplayMetrics metric = new DisplayMetrics(); 32 wm.getDefaultDisplay().getMetrics(metric); 33 width = metric.widthPixels; 34 35 } 36 37 38 public View getView(int position, View convertView, ViewGroup parent) { 39 40 ViewHolder vh = null; 41 42 if(convertView == null){ 43 44 convertView = LayoutInflater.from(mContext).inflate(R.layout.listitem, parent, false); 45 vh = new ViewHolder(); 46 47 vh.tv = (TextView) convertView.findViewById(R.id.tv_time); 48 vh.fl = (FrameLayout) convertView.findViewById(R.id.id_frame); 49 50 convertView.setTag(vh); 51 52 }else{ 53 54 vh = (ViewHolder) convertView.getTag(); 55 } 56 57 58 vh.tv.setText(getItem(position).mTime+"\"");//设定显示的时间 59 //下面三句为设定vh.fl的宽度 60 LayoutParams lp = vh.fl.getLayoutParams(); 61 int w = width*getItem(position).mTime/35; 62 lp.width = w>(width*3/4)?(width*3/4):w; 63 64 65 return convertView; 66 } 67 68 class ViewHolder{ 69 70 private TextView tv; 71 private FrameLayout fl; 72 } 73 }
最后再MainActivity里,我们集成播放器,设置ListView。代码如下:
1 package com.fuly.irecoder; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import com.fuly.util.MyAdapter; 7 import com.fuly.util.Recoder; 8 import com.fuly.util.RecoderButton; 9 import com.fuly.util.RecoderButton.RecoderButtonListener; 10 import com.fuly.util.RecoderPlayer; 11 12 import android.media.MediaPlayer; 13 import android.os.Bundle; 14 import android.app.Activity; 15 import android.view.Menu; 16 import android.view.View; 17 import android.widget.AdapterView; 18 import android.widget.AdapterView.OnItemClickListener; 19 import android.widget.ArrayAdapter; 20 import android.widget.ListView; 21 22 public class MainActivity extends Activity { 23 24 25 private ListView mListView ; 26 private MyAdapter mAdapter; 27 private List<Recoder> mDatas = new ArrayList<Recoder>(); 28 29 private RecoderPlayer mPlayer; 30 31 32 protected void onCreate(Bundle savedInstanceState) { 33 super.onCreate(savedInstanceState); 34 setContentView(R.layout.activity_main); 35 36 mListView = (ListView) findViewById(R.id.rec_listview); 37 RecoderButton button = (RecoderButton) findViewById(R.id.btn_recoder); 38 39 button.setOnRecoderButtonListener(new RecoderButtonListener() { 40 41 42 public void onFinish(int mTime, String filePath) { 43 44 Recoder recoder = new Recoder(mTime,filePath); 45 46 mDatas.add(recoder); 47 48 mAdapter.notifyDataSetChanged();//通知状态发生改变,即有新数据添加进来 49 50 //设置ListView为最后一一项 51 mListView.setSelection(mDatas.size()-1); 52 53 54 } 55 }); 56 57 mAdapter = new MyAdapter(this, mDatas); 58 mListView.setAdapter(mAdapter); 59 60 61 mListView.setOnItemClickListener(new OnItemClickListener() { 62 63 public void onItemClick(AdapterView<?> parent, View view, 64 int position, long id) { 65 66 67 //播放音频 68 69 mPlayer = new RecoderPlayer(); 70 71 //OnCompletionListener是播放结束的监听器 72 mPlayer.playSound(mDatas.get(position).filePath); 73 74 75 76 } 77 }); 78 79 } 80 81 82 @Override 83 protected void onPause() { 84 RecoderPlayer.pause(); 85 super.onPause(); 86 } 87 88 @Override 89 protected void onRestart() { 90 RecoderPlayer.reset(); 91 super.onRestart(); 92 } 93 94 @Override 95 protected void onDestroy() { 96 RecoderPlayer.release(); 97 mDatas.clear(); 98 super.onDestroy(); 99 } 100 101 102 }
至此,我们的整个项目算是完成了。赶快运行一下,看看效果吧。如果对界面不满意,可以自己再调调哦。