国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android仿微信語音聊天界面設計

2019-12-12 04:31:50
字體:
來源:轉載
供稿:網友

有段時間沒有看視頻了,昨天晚上抽了點空時間,又看了下鴻洋大神的視頻教程,又抽時間寫了個學習記錄。代碼和老師講的基本一樣,網上也有很多相同的博客。我只是在AndroidStudio環境下寫的。

―-主界面代碼――

 public class MainActivity extends Activity { private ListView mListView; private ArrayAdapter<Recorder> mAdapter; private List<Recorder> mDatas = new ArrayList<Recorder>(); private AudioRecorderButton mAudioRecorderButton; private View animView; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  mListView = (ListView) findViewById(R.id.id_listview);  mAudioRecorderButton = (AudioRecorderButton) findViewById(R.id.id_recorder_button);  mAudioRecorderButton.setFinishRecorderCallBack(new AudioRecorderButton.AudioFinishRecorderCallBack() {   public void onFinish(float seconds, String filePath) {    Recorder recorder = new Recorder(seconds, filePath);    mDatas.add(recorder);    //更新數據    mAdapter.notifyDataSetChanged();    //設置位置    mListView.setSelection(mDatas.size() - 1);   }  });  mAdapter = new RecoderAdapter(this, mDatas);  mListView.setAdapter(mAdapter);  //listView的item點擊事件  mListView.setOnItemClickListener(new OnItemClickListener() {   public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {    // 聲音播放動畫    if (animView != null) {     animView.setBackgroundResource(R.drawable.adj);     animView = null;    }    animView = view.findViewById(R.id.id_recoder_anim);    animView.setBackgroundResource(R.drawable.play_anim);    AnimationDrawable animation = (AnimationDrawable) animView.getBackground();    animation.start();    // 播放錄音    MediaPlayerManager.playSound(mDatas.get(position).filePath, new MediaPlayer.OnCompletionListener() {     public void onCompletion(MediaPlayer mp) {      //播放完成后修改圖片      animView.setBackgroundResource(R.drawable.adj);     }    });   }  }); } @Override protected void onPause() {  super.onPause();  MediaPlayerManager.pause(); } @Override protected void onResume() {  super.onResume();  MediaPlayerManager.resume(); } @Override protected void onDestroy() {  super.onDestroy();  MediaPlayerManager.release(); }

―自定義Button――-

/** * @param * @author ldm * @description 自定義Button * @time 2016/6/25 9:26 */public class AudioRecorderButton extends Button { // 按鈕正常狀態(默認狀態) private static final int STATE_NORMAL = 1; //正在錄音狀態 private static final int STATE_RECORDING = 2; //錄音取消狀態 private static final int STATE_CANCEL = 3; //記錄當前狀態 private int mCurrentState = STATE_NORMAL; //是否開始錄音標志 private boolean isRecording = false; //判斷在Button上滑動距離,以判斷 是否取消 private static final int DISTANCE_Y_CANCEL = 50; //對話框管理工具類 private DialogManager mDialogManager; //錄音管理工具類 private AudioManager mAudioManager; //記錄錄音時間 private float mTime; // 是否觸發longClick private boolean mReady; //錄音準備 private static final int MSG_AUDIO_PREPARED = 0x110; //音量發生改變 private static final int MSG_VOICE_CHANGED = 0x111; //取消提示對話框 private static final int MSG_DIALOG_DIMISS = 0x112; /**  * @description 獲取音量大小的線程  * @author ldm  * @time 2016/6/25 9:30  * @param  */ private Runnable mGetVoiceLevelRunnable = new Runnable() {  public void run() {   while (isRecording) {//判斷正在錄音    try {     Thread.sleep(100);     mTime += 0.1f;//錄音時間計算     mHandler.sendEmptyMessage(MSG_VOICE_CHANGED);//每0.1秒發送消息    } catch (InterruptedException e) {     e.printStackTrace();    }   }  } }; private Handler mHandler = new Handler() {  @Override  public void handleMessage(Message msg) {   switch (msg.what) {    case MSG_AUDIO_PREPARED:     //顯示對話框     mDialogManager.showRecordingDialog();     isRecording = true;     // 開啟一個線程計算錄音時間     new Thread(mGetVoiceLevelRunnable).start();     break;    case MSG_VOICE_CHANGED:     //更新聲音     mDialogManager.updateVoiceLevel(mAudioManager.getVoiceLevel(7));     break;    case MSG_DIALOG_DIMISS:     //取消對話框     mDialogManager.dimissDialog();     break;   }   super.handleMessage(msg);  } }; public AudioRecorderButton(Context context, AttributeSet attrs) {  super(context, attrs);  mDialogManager = new DialogManager(context);  //錄音文件存放地址  String dir = Environment.getExternalStorageDirectory() + "/ldm_voice";  mAudioManager = AudioManager.getInstance(dir);  mAudioManager.setOnAudioStateListener(new AudioManager.AudioStateListener() {   public void wellPrepared() {    mHandler.sendEmptyMessage(MSG_AUDIO_PREPARED);   }  });  // 由于這個類是button所以在構造方法中添加監聽事件  setOnLongClickListener(new OnLongClickListener() {   public boolean onLongClick(View v) {    mReady = true;    mAudioManager.prepareAudio();    return false;   }  }); } public AudioRecorderButton(Context context) {  this(context, null); } /**  * @description 錄音完成后的回調  * @author ldm  * @time 2016/6/25 11:18  * @param */ public interface AudioFinishRecorderCallBack {  void onFinish(float seconds, String filePath); } private AudioFinishRecorderCallBack finishRecorderCallBack; public void setFinishRecorderCallBack(AudioFinishRecorderCallBack listener) {  finishRecorderCallBack = listener; } /**  * @param  * @description 處理Button的OnTouchEvent事件  * @author ldm  * @time 2016/6/25 9:35  */ @Override public boolean onTouchEvent(MotionEvent event) {  //獲取TouchEvent狀態  int action = event.getAction();  // 獲得x軸坐標  int x = (int) event.getX();  // 獲得y軸坐標  int y = (int) event.getY();  switch (action) {   case MotionEvent.ACTION_DOWN://手指按下    changeState(STATE_RECORDING);    break;   case MotionEvent.ACTION_MOVE://手指移動    if (isRecording) {     //根據x,y的坐標判斷是否需要取消     if (wantToCancle(x, y)) {      changeState(STATE_CANCEL);     } else {      changeState(STATE_RECORDING);     }    }    break;   case MotionEvent.ACTION_UP://手指放開    if (!mReady) {     reset();     return super.onTouchEvent(event);    }    if (!isRecording || mTime < 0.6f) {//如果時間少于0.6s,則提示錄音過短     mDialogManager.tooShort();     mAudioManager.cancel();     // 延遲顯示對話框     mHandler.sendEmptyMessageDelayed(MSG_DIALOG_DIMISS, 1000);    } else if (mCurrentState == STATE_RECORDING) {     //如果狀態為正在錄音,則結束錄制     mDialogManager.dimissDialog();     mAudioManager.release();     if (finishRecorderCallBack != null) {      finishRecorderCallBack.onFinish(mTime, mAudioManager.getCurrentFilePath());     }    } else if (mCurrentState == STATE_CANCEL) { // 想要取消     mDialogManager.dimissDialog();     mAudioManager.cancel();    }    reset();    break;  }  return super.onTouchEvent(event); } /**  * 恢復狀態及標志位  */ private void reset() {  isRecording = false;  mTime = 0;  mReady = false;  changeState(STATE_NORMAL); } private boolean wantToCancle(int x, int y) {  // 超過按鈕的寬度  if (x < 0 || x > getWidth()) {   return true;  }  // 超過按鈕的高度  if (y < -DISTANCE_Y_CANCEL || y > getHeight() + DISTANCE_Y_CANCEL) {   return true;  }  return false; } /**  * @param  * @description 根據狀態改變Button顯示  * @author ldm  * @time 2016/6/25 9:36  */ private void changeState(int state) {  if (mCurrentState != state) {   mCurrentState = state;   switch (state) {    case STATE_NORMAL:     setBackgroundResource(R.drawable.btn_recorder_normal);     setText(R.string.str_recorder_normal);     break;    case STATE_RECORDING:     setBackgroundResource(R.drawable.btn_recorder_recording);     setText(R.string.str_recorder_recording);     if (isRecording) {      mDialogManager.recording();     }     break;    case STATE_CANCEL:     setBackgroundResource(R.drawable.btn_recorder_recording);     mDialogManager.wantToCancel();     setText(R.string.str_recorder_want_cancel);     break;   }  } }}

―-對話框管理工具類――

/**  * @description 對話框管理工具類  * @author ldm  * @time 2016/6/25 11:53  * @param  */public class DialogManager { //彈出對話框 private Dialog mDialog; //錄音圖標 private ImageView mIcon; //音量顯示 圖標 private ImageView mVoice; //對話框上提示文字 private TextView mLable; //上下文對象 private Context mContext; public DialogManager(Context context) {  this.mContext = context; } /**  * @param  * @description 顯示對話框  * @author ldm  * @time 2016/6/25 9:56  */ public void showRecordingDialog() {  //根據指定sytle實例化Dialog  mDialog = new Dialog(mContext, R.style.AudioDialog);  LayoutInflater inflater = LayoutInflater.from(mContext);  View view = inflater.inflate(R.layout.dialog_recorder, null);  mDialog.setContentView(view);  mIcon = (ImageView) view.findViewById(R.id.id_recorder_dialog_icon);  mVoice = (ImageView) view.findViewById(R.id.id_recorder_dialog_voice);  mLable = (TextView) view.findViewById(R.id.id_recorder_dialog_label);  mDialog.show(); } /**  * @param  * @description 正在錄音狀態的對話框  * @author ldm  * @time 2016/6/25 10:08  */ 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("手指上滑,取消發送");  } } /**  * @param  * @description 取消錄音狀態對話框  * @author ldm  * @time 2016/6/25 10:08  */ 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("松開手指,取消發送");  } } /**  * @param  * @description時間過短提示的對話框  * @author ldm  * @time 2016/6/25 10:09  */ 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("錄音時間過短");  } } /**  * @param  * @description  * @author ldm  * @time 2016/6/25 取消(關閉)對話框  */ public void dimissDialog() {  if (mDialog != null && mDialog.isShowing()) { //顯示狀態   mDialog.dismiss();   mDialog = null;  } } // 顯示更新音量級別的對話框 public void updateVoiceLevel(int level) {  if (mDialog != null && mDialog.isShowing()) { //顯示狀態   mIcon.setVisibility(View.VISIBLE);   mVoice.setVisibility(View.VISIBLE);   mLable.setVisibility(View.VISIBLE);   //設置圖片的id,我們放在drawable中的聲音圖片是以v+數字格式的   int resId = mContext.getResources().getIdentifier("v" + level, "drawable", mContext.getPackageName());   mVoice.setImageResource(resId);  } }}

―-聲音播放工具類――

/** * @param * @author ldm * @description 播放聲音工具類 * @time 2016/6/25 11:29 */public class MediaPlayerManager { //播放音頻API類:MediaPlayer private static MediaPlayer mMediaPlayer; //是否暫停 private static boolean isPause; /**  * @param  * filePath:文件路徑  * onCompletionListener:播放完成監聽  * @description 播放聲音  * @author ldm  * @time 2016/6/25 11:30  */ public static void playSound(String filePath, MediaPlayer.OnCompletionListener onCompletionListener) {  if (mMediaPlayer == null) {   mMediaPlayer = new MediaPlayer();   //設置一個error監聽器   mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {    public boolean onError(MediaPlayer arg0, int arg1, int arg2) {     mMediaPlayer.reset();     return false;    }   });  } else {   mMediaPlayer.reset();  }  try {   mMediaPlayer.setAudioStreamType(android.media.AudioManager.STREAM_MUSIC);   mMediaPlayer.setOnCompletionListener(onCompletionListener);   mMediaPlayer.setDataSource(filePath);   mMediaPlayer.prepare();   mMediaPlayer.start();  } catch (Exception e) {  } } /**  * @param  * @description 暫停播放  * @author ldm  * @time 2016/6/25 11:31  */ public static void pause() {  if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { //正在播放的時候   mMediaPlayer.pause();   isPause = true;  } } /**  * @param  * @description 重新播放  * @author ldm  * @time 2016/6/25 11:31  */ public static void resume() {  if (mMediaPlayer != null && isPause) {   mMediaPlayer.start();   isPause = false;  } } /**  * @param  * @description 釋放操作  * @author ldm  * @time 2016/6/25 11:32  */ public static void release() {  if (mMediaPlayer != null) {   mMediaPlayer.release();   mMediaPlayer = null;  } }

主站蜘蛛池模板: 冀州市| 临颍县| 柘城县| 高雄县| 江北区| 沈丘县| 永登县| 衡阳县| 浠水县| 横峰县| 太仆寺旗| 巴楚县| 新民市| 普兰县| 平定县| 集贤县| 微山县| 正阳县| 巴林左旗| 巴林右旗| 三亚市| 阜阳市| 高清| 沁阳市| 银川市| 恩施市| 遂平县| 洛宁县| 马关县| 诸城市| 开江县| 高阳县| 乐清市| 应城市| 东乡县| 扎赉特旗| 诸城市| 鄯善县| 霞浦县| 乌海市| 漳州市|