android仿微信聊天界面 语音录制功能

android仿微信聊天界面 语音录制功能,第1张

概述本例为模仿微信聊天界面UI设计,文字发送以及语言录制UI。1先看效果图: 

本例为模仿微信聊天界面UI设计,文字发送以及语言录制UI。

1先看效果图:

 

 

 

第一:chat.xml设计

 <?xml version="1.0" enCoding="utf-8"?> <relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"   androID:layout_wIDth="fill_parent"   androID:layout_height="fill_parent"   androID:background="@drawable/chat_bg_default" >    <!-- 标题栏 -->   <relativeLayout     androID:ID="@+ID/rl_layout"     androID:layout_wIDth="fill_parent"     androID:layout_height="45dp"     androID:background="@drawable/Title_bar"     androID:gravity="center_vertical" >      <button       androID:ID="@+ID/btn_back"       androID:layout_wIDth="70dp"       androID:layout_height="wrap_content"       androID:layout_centerVertical="true"       androID:background="@drawable/Title_btn_back"       androID:onClick="chat_back"       androID:text="返回"       androID:textcolor="#fff"       androID:textSize="14sp" />      <TextVIEw       androID:layout_wIDth="wrap_content"       androID:layout_height="wrap_content"       androID:layout_centerInParent="true"       androID:text="白富美"       androID:textcolor="#ffffff"       androID:textSize="20sp" />      <Imagebutton       androID:ID="@+ID/right_btn"       androID:layout_wIDth="67dp"       androID:layout_height="wrap_content"       androID:layout_alignParentRight="true"       androID:layout_centerVertical="true"       androID:layout_marginRight="5dp"       androID:background="@drawable/Title_btn_right"       androID:src="@drawable/mm_Title_btn_contact_normal" />   </relativeLayout>    <!-- 底部按钮以及 编辑框 -->   <relativeLayout     androID:ID="@+ID/rl_bottom"     androID:layout_wIDth="fill_parent"     androID:layout_height="wrap_content"     androID:layout_alignParentBottom="true"     androID:background="@drawable/chat_footer_bg" >      <ImageVIEw       androID:ID="@+ID/ivPopUp"       androID:layout_wIDth="wrap_content"       androID:layout_height="wrap_content"       androID:layout_alignParentleft="true"       androID:layout_centerVertical="true"       androID:layout_marginleft="10dip"       androID:src="@drawable/chatting_setmode_msg_btn" />      <relativeLayout       androID:ID="@+ID/btn_bottom"       androID:layout_wIDth="fill_parent"       androID:layout_height="wrap_content"       androID:layout_alignParentRight="true"       androID:layout_centerVertical="true"       androID:layout_toRightOf="@+ID/ivPopUp" >        <button         androID:ID="@+ID/btn_send"         androID:layout_wIDth="60dp"         androID:layout_height="40dp"         androID:layout_alignParentRight="true"         androID:layout_centerVertical="true"         androID:layout_marginRight="10dp"         androID:background="@drawable/chat_send_btn"         androID:text="发送" />        <EditText         androID:ID="@+ID/et_sendmessage"         androID:layout_wIDth="fill_parent"         androID:layout_height="40dp"         androID:layout_centerVertical="true"         androID:layout_marginleft="10dp"         androID:layout_marginRight="10dp"         androID:layout_toleftOf="@ID/btn_send"         androID:background="@drawable/login_edit_normal"         androID:singleline="true"         androID:textSize="18sp" />     </relativeLayout>      <TextVIEw       androID:ID="@+ID/btn_rcd"       androID:layout_wIDth="fill_parent"       androID:layout_height="40dp"       androID:layout_alignParentRight="true"       androID:layout_centerVertical="true"       androID:layout_marginleft="10dp"       androID:layout_marginRight="10dp"       androID:layout_toRightOf="@+ID/ivPopUp"       androID:background="@drawable/chat_send_btn"       androID:gravity="center"       androID:text="按住说话"       androID:visibility="gone" />   </relativeLayout>      <!-- 聊天内容 ListvIEw -->   <ListVIEw     androID:ID="@+ID/ListvIEw"     androID:layout_wIDth="fill_parent"     androID:layout_height="fill_parent"     androID:layout_above="@ID/rl_bottom"     androID:layout_below="@ID/rl_layout"     androID:cachecolorHint="#0000"     androID:divIDer="@null"     androID:divIDerHeight="5dp"     androID:scrollbarStyle="outsIDeOverlay"     androID:stackFromBottom="true" />      <!-- 录音显示UI层 -->   <linearLayout     androID:ID="@+ID/rcChat_popup"     androID:layout_wIDth="fill_parent"     androID:layout_height="fill_parent"     androID:gravity="center"     androID:visibility="gone" >      <include       androID:layout_wIDth="wrap_content"       androID:layout_height="wrap_content"       androID:layout_gravity="center"       layout="@layout/voice_rcd_hint_window" />   </linearLayout>  </relativeLayout> 

第二:语音录制类封装SoundMeter.java

package com.example.voice_rcd;  import java.io.IOException;  import androID.media.MediaRecorder; import androID.os.Environment;  public class SoundMeter {   static final private double EMA_FILTER = 0.6;    private MediaRecorder mRecorder = null;   private double mEMA = 0.0;    public voID start(String name) {     if (!Environment.getExternalStorageState().equals(         androID.os.Environment.MEDIA_MOUNTED)) {       return;     }     if (mRecorder == null) {       mRecorder = new MediaRecorder();       mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);       mRecorder.setoutputFormat(MediaRecorder.OutputFormat.THREE_GPP);       mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);       mRecorder.setoutputfile(androID.os.Environment.getExternalStorageDirectory()+"/"+name);       try {         mRecorder.prepare();         mRecorder.start();                  mEMA = 0.0;       } catch (IllegalStateException e) {         System.out.print(e.getMessage());       } catch (IOException e) {         System.out.print(e.getMessage());       }      }   }    public voID stop() {     if (mRecorder != null) {       mRecorder.stop();       mRecorder.release();       mRecorder = null;     }   }    public voID pause() {     if (mRecorder != null) {       mRecorder.stop();     }   }    public voID start() {     if (mRecorder != null) {       mRecorder.start();     }   }    public double getAmplitude() {     if (mRecorder != null)       return (mRecorder.getMaxAmplitude() / 2700.0);     else       return 0;    }    public double getAmplitudeEMA() {     double amp = getAmplitude();     mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;     return mEMA;   } } 
 

第三:主界面Activity源码,没写太多解释,相对比较简单的自己研究下:

package com.example.voice_rcd;  import java.io.file; import java.util.ArrayList; import java.util.Calendar; import java.util.List;  import androID.app.Activity; import androID.os.Bundle; import androID.os.Environment; import androID.os.Handler; import androID.os.SystemClock; import androID.vIEw.MotionEvent; import androID.vIEw.VIEw; import androID.vIEw.VIEw.OnClickListener; import androID.vIEw.VIEw.OntouchListener; import androID.vIEw.WindowManager; import androID.vIEw.animation.Animation; import androID.vIEw.animation.AnimationUtils; import androID.Widget.button; import androID.Widget.EditText; import androID.Widget.ImageVIEw; import androID.Widget.linearLayout; import androID.Widget.ListVIEw; import androID.Widget.relativeLayout; import androID.Widget.TextVIEw; import androID.Widget.Toast;  public class MainActivity extends Activity implements OnClickListener {   /** Called when the activity is first created. */    private button mBtnSend;   private TextVIEw mBtnRcd;   private button mBtnBack;   private EditText mEditTextContent;   private relativeLayout mBottom;   private ListVIEw mListVIEw;   private ChatMsgVIEwAdapter mAdapter;   private List<ChatMsgEntity> mDataArrays = new ArrayList<ChatMsgEntity>();   private boolean isShosrt = false;   private linearLayout voice_rcd_hint_loading,voice_rcd_hint_rcding,voice_rcd_hint_tooshort;   private ImageVIEw img1,sc_img1;   private SoundMeter mSensor;   private VIEw rcChat_popup;   private linearLayout del_re;   private ImageVIEw chatting_mode_btn,volume;   private boolean btn_vocIE = false;   private int flag = 1;   private Handler mHandler = new Handler();   private String voicename;   private long startVoiceT,endVoiceT;    public voID onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentVIEw(R.layout.chat);     // 启动activity时不自动d出软键盘     getwindow().setSoftinputMode(         WindowManager.LayoutParams.soFT_input_STATE_ALWAYS_HIDDEN);     initVIEw();      initData();   }    public voID initVIEw() {     mListVIEw = (ListVIEw) findVIEwByID(R.ID.ListvIEw);     mBtnSend = (button) findVIEwByID(R.ID.btn_send);     mBtnRcd = (TextVIEw) findVIEwByID(R.ID.btn_rcd);     mBtnSend.setonClickListener(this);     mBtnBack = (button) findVIEwByID(R.ID.btn_back);     mBottom = (relativeLayout) findVIEwByID(R.ID.btn_bottom);     mBtnBack.setonClickListener(this);     chatting_mode_btn = (ImageVIEw) this.findVIEwByID(R.ID.ivPopUp);     volume = (ImageVIEw) this.findVIEwByID(R.ID.volume);     rcChat_popup = this.findVIEwByID(R.ID.rcChat_popup);     img1 = (ImageVIEw) this.findVIEwByID(R.ID.img1);     sc_img1 = (ImageVIEw) this.findVIEwByID(R.ID.sc_img1);     del_re = (linearLayout) this.findVIEwByID(R.ID.del_re);     voice_rcd_hint_rcding = (linearLayout) this         .findVIEwByID(R.ID.voice_rcd_hint_rcding);     voice_rcd_hint_loading = (linearLayout) this         .findVIEwByID(R.ID.voice_rcd_hint_loading);     voice_rcd_hint_tooshort = (linearLayout) this         .findVIEwByID(R.ID.voice_rcd_hint_tooshort);     mSensor = new SoundMeter();     mEditTextContent = (EditText) findVIEwByID(R.ID.et_sendmessage);          //语音文字切换按钮     chatting_mode_btn.setonClickListener(new OnClickListener() {        public voID onClick(VIEw v) {          if (btn_vocIE) {           mBtnRcd.setVisibility(VIEw.GONE);           mBottom.setVisibility(VIEw.VISIBLE);           btn_vocIE = false;           chatting_mode_btn               .setimageResource(R.drawable.chatting_setmode_msg_btn);          } else {           mBtnRcd.setVisibility(VIEw.VISIBLE);           mBottom.setVisibility(VIEw.GONE);           chatting_mode_btn               .setimageResource(R.drawable.chatting_setmode_voice_btn);           btn_vocIE = true;         }       }     });     mBtnRcd.setontouchListener(new OntouchListener() {              public boolean ontouch(VIEw v,MotionEvent event) {         //按下语音录制按钮时返回false执行父类Ontouch         return false;       }     });   }    private String[] msgArray = new String[] { "有人就有恩怨","有恩怨就有江湖","人就是江湖","你怎么退出? ","生命中充满了巧合","两条平行线也会有相交的一天。"};    private String[] dataArray = new String[] { "2012-10-31 18:00","2012-10-31 18:10","2012-10-31 18:11","2012-10-31 18:20","2012-10-31 18:30","2012-10-31 18:35"};   private final static int COUNT = 6;    public voID initData() {     for (int i = 0; i < COUNT; i++) {       ChatMsgEntity entity = new ChatMsgEntity();       entity.setDate(dataArray[i]);       if (i % 2 == 0) {         entity.setname("白富美");         entity.setMsgType(true);       } else {         entity.setname("高富帅");         entity.setMsgType(false);       }        entity.setText(msgArray[i]);       mDataArrays.add(entity);     }      mAdapter = new ChatMsgVIEwAdapter(this,mDataArrays);     mListVIEw.setAdapter(mAdapter);    }    public voID onClick(VIEw v) {     // Todo auto-generated method stub     switch (v.getID()) {     case R.ID.btn_send:       send();       break;     case R.ID.btn_back:       finish();       break;     }   }    private voID send() {     String contString = mEditTextContent.getText().toString();     if (contString.length() > 0) {       ChatMsgEntity entity = new ChatMsgEntity();       entity.setDate(getDate());       entity.setname("高富帅");       entity.setMsgType(false);       entity.setText(contString);        mDataArrays.add(entity);       mAdapter.notifyDataSetChanged();        mEditTextContent.setText("");        mListVIEw.setSelection(mListVIEw.getCount() - 1);     }   }    private String getDate() {     Calendar c = Calendar.getInstance();      String year = String.valueOf(c.get(Calendar.YEAR));     String month = String.valueOf(c.get(Calendar.MONTH));     String day = String.valueOf(c.get(Calendar.DAY_OF_MONTH) + 1);     String hour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));     String mins = String.valueOf(c.get(Calendar.MINUTE));      StringBuffer sbBuffer = new StringBuffer();     sbBuffer.append(year + "-" + month + "-" + day + " " + hour + ":"         + mins);      return sbBuffer.toString();   }    //按下语音录制按钮时   @OverrIDe   public boolean ontouchEvent(MotionEvent event) {      if (!Environment.getExternalStorageDirectory().exists()) {       Toast.makeText(this,"No SDCard",Toast.LENGTH_LONG).show();       return false;     }      if (btn_vocIE) {       System.out.println("1");       int[] location = new int[2];       mBtnRcd.getLocationInWindow(location); // 获取在当前窗口内的绝对坐标       int btn_rc_Y = location[1];       int btn_rc_X = location[0];       int[] del_location = new int[2];       del_re.getLocationInWindow(del_location);       int del_Y = del_location[1];       int del_x = del_location[0];       if (event.getAction() == MotionEvent.ACTION_DOWN && flag == 1) {         if (!Environment.getExternalStorageDirectory().exists()) {           Toast.makeText(this,Toast.LENGTH_LONG).show();           return false;         }         System.out.println("2");         if (event.getY() > btn_rc_Y && event.getX() > btn_rc_X) {//判断手势按下的位置是否是语音录制按钮的范围内           System.out.println("3");           mBtnRcd.setBackgroundResource(R.drawable.voice_rcd_btn_pressed);           rcChat_popup.setVisibility(VIEw.VISIBLE);           voice_rcd_hint_loading.setVisibility(VIEw.VISIBLE);           voice_rcd_hint_rcding.setVisibility(VIEw.GONE);           voice_rcd_hint_tooshort.setVisibility(VIEw.GONE);           mHandler.postDelayed(new Runnable() {             public voID run() {               if (!isShosrt) {                 voice_rcd_hint_loading.setVisibility(VIEw.GONE);                 voice_rcd_hint_rcding                     .setVisibility(VIEw.VISIBLE);               }             }           },300);           img1.setVisibility(VIEw.VISIBLE);           del_re.setVisibility(VIEw.GONE);           startVoiceT = SystemClock.currentThreadTimeMillis();           voicename = startVoiceT + ".amr";           start(voicename);           flag = 2;         }       } else if (event.getAction() == MotionEvent.ACTION_UP && flag == 2) {//松开手势时执行录制完成         System.out.println("4");         mBtnRcd.setBackgroundResource(R.drawable.voice_rcd_btn_nor);         if (event.getY() >= del_Y             && event.getY() <= del_Y + del_re.getHeight()             && event.getX() >= del_x             && event.getX() <= del_x + del_re.getWIDth()) {           rcChat_popup.setVisibility(VIEw.GONE);           img1.setVisibility(VIEw.VISIBLE);           del_re.setVisibility(VIEw.GONE);           stop();           flag = 1;           file file = new file(androID.os.Environment.getExternalStorageDirectory()+"/"                   + voicename);           if (file.exists()) {             file.delete();           }         } else {            voice_rcd_hint_rcding.setVisibility(VIEw.GONE);           stop();           endVoiceT = SystemClock.currentThreadTimeMillis();           flag = 1;           int time = (int) ((endVoiceT - startVoiceT) / 1000);           if (time < 1) {             isShosrt = true;             voice_rcd_hint_loading.setVisibility(VIEw.GONE);             voice_rcd_hint_rcding.setVisibility(VIEw.GONE);             voice_rcd_hint_tooshort.setVisibility(VIEw.VISIBLE);             mHandler.postDelayed(new Runnable() {               public voID run() {                 voice_rcd_hint_tooshort                     .setVisibility(VIEw.GONE);                 rcChat_popup.setVisibility(VIEw.GONE);                 isShosrt = false;               }             },500);             return false;           }           ChatMsgEntity entity = new ChatMsgEntity();           entity.setDate(getDate());           entity.setname("高富帅");           entity.setMsgType(false);           entity.setTime(time+"\"");           entity.setText(voicename);           mDataArrays.add(entity);           mAdapter.notifyDataSetChanged();           mListVIEw.setSelection(mListVIEw.getCount() - 1);           rcChat_popup.setVisibility(VIEw.GONE);          }       }       if (event.getY() < btn_rc_Y) {//手势按下的位置不在语音录制按钮的范围内         System.out.println("5");         Animation mlitteAnimation = AnimationUtils.loadAnimation(this,R.anim.cancel_rc);         Animation mBigAnimation = AnimationUtils.loadAnimation(this,R.anim.cancel_rc2);         img1.setVisibility(VIEw.GONE);         del_re.setVisibility(VIEw.VISIBLE);         del_re.setBackgroundResource(R.drawable.voice_rcd_cancel_bg);         if (event.getY() >= del_Y             && event.getY() <= del_Y + del_re.getHeight()             && event.getX() >= del_x             && event.getX() <= del_x + del_re.getWIDth()) {           del_re.setBackgroundResource(R.drawable.voice_rcd_cancel_bg_focused);           sc_img1.startAnimation(mlitteAnimation);           sc_img1.startAnimation(mBigAnimation);         }       } else {          img1.setVisibility(VIEw.VISIBLE);         del_re.setVisibility(VIEw.GONE);         del_re.setBackgroundResource(0);       }     }     return super.ontouchEvent(event);   }    private static final int PolL_INTERVAL = 300;    private Runnable mSleepTask = new Runnable() {     public voID run() {       stop();     }   };   private Runnable mPollTask = new Runnable() {     public voID run() {       double amp = mSensor.getAmplitude();       updatedisplay(amp);       mHandler.postDelayed(mPollTask,PolL_INTERVAL);      }   };    private voID start(String name) {     mSensor.start(name);     mHandler.postDelayed(mPollTask,PolL_INTERVAL);   }    private voID stop() {     mHandler.removeCallbacks(mSleepTask);     mHandler.removeCallbacks(mPollTask);     mSensor.stop();     volume.setimageResource(R.drawable.amp1);   }    private voID updatedisplay(double signalEMA) {          switch ((int) signalEMA) {     case 0:     case 1:       volume.setimageResource(R.drawable.amp1);       break;     case 2:     case 3:       volume.setimageResource(R.drawable.amp2);              break;     case 4:     case 5:       volume.setimageResource(R.drawable.amp3);       break;     case 6:     case 7:       volume.setimageResource(R.drawable.amp4);       break;     case 8:     case 9:       volume.setimageResource(R.drawable.amp5);       break;     case 10:     case 11:       volume.setimageResource(R.drawable.amp6);       break;     default:       volume.setimageResource(R.drawable.amp7);       break;     }   }    public voID head_xiaohei(VIEw v) { // 标题栏 返回按钮    } } 

第四:自定义的显示适配器:

package com.example.voice_rcd;  import java.util.List;  import androID.content.Context; import androID.media.MediaPlayer; import androID.media.MediaPlayer.OnCompletionListener; import androID.vIEw.LayoutInflater; import androID.vIEw.VIEw; import androID.vIEw.VIEw.OnClickListener; import androID.vIEw.VIEwGroup; import androID.Widget.BaseAdapter; import androID.Widget.TextVIEw;  public class ChatMsgVIEwAdapter extends BaseAdapter {    public static interface imsgVIEwType {     int IMVT_COM_MSG = 0;     int IMVT_TO_MSG = 1;   }    private static final String TAG = ChatMsgVIEwAdapter.class.getSimplename();    private List<ChatMsgEntity> coll;    private Context ctx;    private LayoutInflater mInflater;   private MediaPlayer mMediaPlayer = new MediaPlayer();    public ChatMsgVIEwAdapter(Context context,List<ChatMsgEntity> coll) {     ctx = context;     this.coll = coll;     mInflater = LayoutInflater.from(context);   }    public int getCount() {     return coll.size();   }    public Object getItem(int position) {     return coll.get(position);   }    public long getItemID(int position) {     return position;   }    public int getItemVIEwType(int position) {     // Todo auto-generated method stub     ChatMsgEntity entity = coll.get(position);      if (entity.getMsgType()) {       return imsgVIEwType.IMVT_COM_MSG;     } else {       return imsgVIEwType.IMVT_TO_MSG;     }    }    public int getVIEwTypeCount() {     // Todo auto-generated method stub     return 2;   }    public VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup parent) {      final ChatMsgEntity entity = coll.get(position);     boolean isComMsg = entity.getMsgType();      VIEwHolder vIEwHolder = null;     if (convertVIEw == null) {       if (isComMsg) {         convertVIEw = mInflater.inflate(             R.layout.chatting_item_msg_text_left,null);       } else {         convertVIEw = mInflater.inflate(             R.layout.chatting_item_msg_text_right,null);       }        vIEwHolder = new VIEwHolder();       vIEwHolder.tvSendTime = (TextVIEw) convertVIEw           .findVIEwByID(R.ID.tv_sendtime);       vIEwHolder.tvUsername = (TextVIEw) convertVIEw           .findVIEwByID(R.ID.tv_username);       vIEwHolder.tvContent = (TextVIEw) convertVIEw           .findVIEwByID(R.ID.tv_chatcontent);       vIEwHolder.tvTime = (TextVIEw) convertVIEw           .findVIEwByID(R.ID.tv_time);       vIEwHolder.isComMsg = isComMsg;        convertVIEw.setTag(vIEwHolder);     } else {       vIEwHolder = (VIEwHolder) convertVIEw.getTag();     }      vIEwHolder.tvSendTime.setText(entity.getDate());          if (entity.getText().contains(".amr")) {       vIEwHolder.tvContent.setText("");       vIEwHolder.tvContent.setCompoundDrawablesWithIntrinsicBounds(0,R.drawable.chatto_voice_playing,0);       vIEwHolder.tvTime.setText(entity.getTime());     } else {       vIEwHolder.tvContent.setText(entity.getText());            vIEwHolder.tvContent.setCompoundDrawablesWithIntrinsicBounds(0,0);       vIEwHolder.tvTime.setText("");     }     vIEwHolder.tvContent.setonClickListener(new OnClickListener() {              public voID onClick(VIEw v) {         if (entity.getText().contains(".amr")) {           playMusic(androID.os.Environment.getExternalStorageDirectory()+"/"+entity.getText()) ;         }       }     });     vIEwHolder.tvUsername.setText(entity.getname());          return convertVIEw;   }    static class VIEwHolder {     public TextVIEw tvSendTime;     public TextVIEw tvUsername;     public TextVIEw tvContent;     public TextVIEw tvTime;     public boolean isComMsg = true;   }    /**    * @Description    * @param name    */   private voID playMusic(String name) {     try {       if (mMediaPlayer.isPlaying()) {         mMediaPlayer.stop();       }       mMediaPlayer.reset();       mMediaPlayer.setDataSource(name);       mMediaPlayer.prepare();       mMediaPlayer.start();       mMediaPlayer.setonCompletionListener(new OnCompletionListener() {         public voID onCompletion(MediaPlayer mp) {          }       });      } catch (Exception e) {       e.printstacktrace();     }    }    private voID stop() {    }  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的android仿微信聊天界面 语音录制功能全部内容,希望文章能够帮你解决android仿微信聊天界面 语音录制功能所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147687.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存