模仿微信語音聊天功能(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程序,看看有什么新的效果呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM