模仿微信语音聊天功能(2)对话框的实现

 

 

     上一篇文章里,我们介绍了整个项目以及实现了按钮功能。没有读的可以点击一下链接:

http://www.cnblogs.com/fuly550871915/p/4836042.html

 

 

     在本篇文章里,我们做第二步,也就是实现几种状态的对话框:录音状态的对话框,取消录音状态下的对话框,录音时间太短下的对话框。然后将对话框集成到我们点击时的按钮操作中。

     首先我们需要自定义一个对话框的布局。不难想出,布局中的上方需要并排放置两张图片,下方是一个用来提示状态的文本。如果对话框切换到录音时的状态,我们就让其中的一张图片显示,另外一张不显示即可。所以整体的布局是这样的,名称为dialog.xml:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="wrap_content"
 4     android:layout_height="wrap_content"
 5     android:orientation="vertical"
 6     android:background="@drawable/dialog_loading_bg">
 7     
 8     <LinearLayout 
 9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content">
11         
12         <ImageView 
13             android:id="@+id/img_recoder"
14             android:layout_width="wrap_content"
15             android:layout_height="wrap_content"
16             android:src="@drawable/recorder"
17             android:visibility="visible"/>
18         <ImageView 
19             android:id="@+id/img_voice"
20             android:layout_width="wrap_content"
21             android:layout_height="wrap_content"
22             android:src="@drawable/v1"
23             android:visibility="visible"/>
24     </LinearLayout>
25     
26     <TextView 
27         android:id="@+id/tv_dialog_txt"
28         android:layout_width="wrap_content"
29         android:layout_height="wrap_content"
30         android:text="@string/dialog_recoding"
31         android:textColor="@color/red"
32         android:layout_gravity="center"
33         android:textSize="20dip"/>
34    
35 
36    
37 
38 </LinearLayout>

  

        接下来我们定义一下对话框的样式,在这里关键是要求对话框弹出时,不要屏幕掉屏幕,也就是屏幕的其他部分仍然是点击有效的。在res的values下的styles下,加入一下代码:

 

1  <style name = "dialogStyle">
2         <item name = "android:windowBackground">@android:color/transparent</item>
3         <item name = "android:windowFrame">@null</item><!-- 设为无边框 -->
4         <item name = "android:windowIsFloating">true</item><!-- 设定为浮动的 -->
5         <item name = "android:windowIsTranslucent">true</item>
6         <item name = "android:backgroundDimEnabled">false</item><!--不屏幕屏幕  -->
7     </style>

 

      然后我们实现对话框这个类,代码如下:

 

  1 package com.fuly.util;
  2 
  3 import com.fuly.irecoder.R;
  4 
  5 import android.app.Dialog;
  6 import android.content.Context;
  7 import android.view.LayoutInflater;
  8 import android.view.View;
  9 import android.widget.ImageView;
 10 import android.widget.TextView;
 11 
 12 //对话框管理类
 13 
 14 public class DialogManager {
 15     
 16     
 17     private Dialog dialog;
 18     
 19     private ImageView imgDialogRecoder;
 20     private ImageView imgVoice;
 21     private TextView tvDialog;
 22     
 23     private Context mContext;
 24     
 25     public DialogManager(Context context){
 26         
 27         mContext = context;
 28     
 29         
 30     }
 31     
 32     
 33      public void dialogShow(){
 34          
 35             //此时我们选择我们自己的对话框样式
 36             dialog = new Dialog(mContext, R.style.dialogStyle);
 37             View view = LayoutInflater.from(mContext).inflate(R.layout.dialog, null);
 38             dialog.setContentView(view);
 39             dialog.show();
 40             
 41             //获取控件,用来在下面的代码中改变他们的状态
 42             imgDialogRecoder = (ImageView) dialog.findViewById(R.id.img_recoder);
 43             imgVoice = (ImageView) dialog.findViewById(R.id.img_voice);
 44             tvDialog = (TextView) dialog.findViewById(R.id.tv_dialog_txt);
 45             
 46      }
 47      
 48     
 49      //录音时的对话框状态
 50      public void dialogRecoding(){
 51          
 52          imgDialogRecoder.setVisibility(View.VISIBLE);
 53          imgVoice.setVisibility(View.VISIBLE);
 54          
 55             imgDialogRecoder.setImageResource(R.drawable.recorder);
 56             imgVoice.setImageResource(R.drawable.v1);
 57             
 58             tvDialog.setText(R.string.dialog_recoding);
 59          
 60      }
 61     
 62      
 63      
 64      //录音时,要更新声音等级,即让imgVoice动起来
 65      public void updateVoiceLevel(int level){
 66          
 67         //根据字符串和包名来获得所对应的资源文件,在这里获取的R.drawable下的文件
 68          int resId = mContext.getResources().getIdentifier("v"+level,"drawable",mContext.getPackageName());
 69          
 70          imgVoice.setImageResource(resId);
 71      }
 72      
 73      
 74      
 75      
 76      
 77      
 78      
 79     //录音取消时的对话框状态
 80     public void dialogRecoderCancel(){
 81         
 82         
 83         imgDialogRecoder.setVisibility(View.VISIBLE);
 84         imgVoice.setVisibility(View.GONE);
 85         
 86         imgDialogRecoder.setImageResource(R.drawable.cancel);
 87         tvDialog.setText(R.string.dialog_cacel);
 88         
 89     }
 90     
 91     
 92     public void tooShort(){
 93         
 94         imgDialogRecoder.setVisibility(View.VISIBLE);
 95         imgVoice.setVisibility(View.GONE);
 96         
 97         imgDialogRecoder.setImageResource(R.drawable.voice_to_short);
 98         tvDialog.setText(R.string.too_short);
 99         
100     }
101     
102     //取消对话框
103     public void dialogDismiss(){
104         
105         if(dialog != null){
106         dialog.dismiss();
107         }
108     }
109     
110 
111 }

 

 

      然后修改strings.xml文件。为什么所有的文字我们非得这么麻烦的放在这个文件里引用的。答案是:这样子做可以有效的防止你的app的内存占用。所以要养成良好的编程习惯。不多说了,代码如下:

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <resources>
 3 
 4     <string name="app_name">irecoder</string>
 5     <string name="action_settings">Settings</string>
 6      <string name="btn_normal">按住 录音</string>
 7      <string name="btn_recoding">松开 结束</string>
 8      <string name="btn_cancel">手指上滑,取消录音 </string>
 9      <string name="dialog_recoding">手指上滑,取消录音 </string>
10       <string name="dialog_cacel">松开手指 取消发送</string>
11     
12 
13 </resources>

     

        然后我们要配置颜色了,在res下的values文件夹下的color.xml(如果没有你就新建一个)里面写上下面的代码:

 

1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3     
4     <color name="black">#000000</color>
5      <color name="red">#CC0000</color>
6       <color name="white">#ffffff</color>
7     
8 </resources>

 

 

      好了,关于对话框的工作我们基本上算是完成了。下面将其集成到按钮中,我们打开RecoderButton类,修改其中的代码如下:

 

  1 package com.fuly.util;
  2 
  3 
  4 import com.fuly.irecoder.R;
  5 
  6 import android.content.Context;
  7 import android.util.AttributeSet;
  8 import android.view.MotionEvent;
  9 import android.widget.Button;
 10 
 11 
 12 //定义我们自己的录音按钮
 13 public class RecoderButton extends Button{
 14     
 15     //按钮的三个状态
 16     
 17     private static final int STATE_NORMAL = 1;//正常
 18     private static final int STATE_RECODING = 2;//录音状态
 19     private static final int STATE_CACLE = 3;//取消状态
 20     
 21     private int mCurState = STATE_NORMAL;//记录当前按钮状态
 22     
 23     private int Y = 50;//限定手指移动的上下宽度
 24     
 25     private DialogManager mDialogManager;//对话框管理类
 26     
 27     
 28     
 29 
 30     public RecoderButton(Context context, AttributeSet attrs) {
 31         super(context, attrs);
 32         
 33         mDialogManager = new DialogManager(context);//实例化对话框管理类
 34     
 35     }
 36     
 37     
 38     
 39     //捕捉按钮点击事件
 40     public boolean onTouchEvent(MotionEvent event) {
 41         
 42         int x = (int) event.getX();
 43         int y =(int)event.getY();
 44         
 45         switch(event.getAction()){
 46         
 47         
 48         case MotionEvent.ACTION_DOWN:
 49             
 50             mDialogManager.dialogShow();//按下按钮的同时将对话框显示出来
 51             changeState(STATE_RECODING);//按下按钮,改变按钮状态
 52             
 53             
 54             break;
 55         case MotionEvent.ACTION_MOVE:
 56             
 57             if(wantCancel(x,y)){ //如果检测到取消,则改变按钮状态为取消
 58                 
 59             changeState(STATE_CACLE);
 60             
 61             }else{
 62                 changeState(STATE_RECODING);
 63             }
 64             
 65             break;
 66         case MotionEvent.ACTION_UP:
 67             
 68             mDialogManager.dialogDismiss();
 69             
 70             reset();//各种设置复位
 71             
 72             break;
 73             default:
 74                 break;
 75         }
 76         
 77         return super.onTouchEvent(event);
 78     }
 79 
 80 
 81 
 82     //复位
 83     private void reset() {
 84         
 85         mCurState = STATE_NORMAL;
 86         changeState(STATE_NORMAL);
 87         
 88     }
 89 
 90 
 91 
 92     //检查手指移动范围,从而确定用户是否想取消录音
 93     private boolean wantCancel(int x, int y) {
 94         
 95         if(x<0||x>getWidth()){
 96             
 97             return true;
 98         }
 99         
100         if(y<0||y>getHeight()+Y){
101             return true;
102         }
103         return false;
104     }
105 
106 
107     
108     //改变状态,包括按钮等操作
109     private void changeState(int state) {
110         
111         if(mCurState != state){
112             
113             mCurState = state;
114             
115         }
116         
117         switch(mCurState){
118               
119         case STATE_NORMAL:
120             
121             setText(R.string.btn_normal);
122             
123             break;
124         case STATE_RECODING:
125             
126             setText(R.string.btn_recoding);
127             
128             mDialogManager.dialogRecoding();
129             
130             break;
131         case STATE_CACLE:
132             
133             setText(R.string.btn_cancel);
134             
135             mDialogManager.dialogRecoderCancel();//此时也要将对话框的状态显示出来
136             
137             break;
138             default:
139                 break;
140         
141         }
142         
143     }
144     
145     
146 
147 }

 

       行了,至此,我们这一阶段的工作算是完成了。下面赶紧运行以下android程序,看看有什么新的效果呢?

模仿微信语音聊天功能(2)对话框的实现

上一篇:小蚂蚁学习微信公众平台开发(1)


下一篇:模仿微信语音聊天功能(4) 音频播放实现以及项目结束