您的位置:首页 > 移动开发 > 微信开发

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

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

/article/6123592.html

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

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/dialog_loading_bg">

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<ImageView
android:id="@+id/img_recoder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/recorder"
android:visibility="visible"/>
<ImageView
android:id="@+id/img_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/v1"
android:visibility="visible"/>
</LinearLayout>

<TextView
android:id="@+id/tv_dialog_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_recoding"
android:textColor="@color/red"
android:layout_gravity="center"
android:textSize="20dip"/>

</LinearLayout>


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

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


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

package com.fuly.util;

import com.fuly.irecoder.R;

import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

//对话框管理类

public class DialogManager {

private Dialog dialog;

private ImageView imgDialogRecoder;
private ImageView imgVoice;
private TextView tvDialog;

private Context mContext;

public DialogManager(Context context){

mContext = context;

}

public void dialogShow(){

//此时我们选择我们自己的对话框样式
dialog = new Dialog(mContext, R.style.dialogStyle);
View view = LayoutInflater.from(mContext).inflate(R.layout.dialog, null);
dialog.setContentView(view);
dialog.show();

//获取控件,用来在下面的代码中改变他们的状态
imgDialogRecoder = (ImageView) dialog.findViewById(R.id.img_recoder);
imgVoice = (ImageView) dialog.findViewById(R.id.img_voice);
tvDialog = (TextView) dialog.findViewById(R.id.tv_dialog_txt);

}

//录音时的对话框状态
public void dialogRecoding(){

imgDialogRecoder.setVisibility(View.VISIBLE);
imgVoice.setVisibility(View.VISIBLE);

imgDialogRecoder.setImageResource(R.drawable.recorder);
imgVoice.setImageResource(R.drawable.v1);

tvDialog.setText(R.string.dialog_recoding);

}

//录音时,要更新声音等级,即让imgVoice动起来
public void updateVoiceLevel(int level){

//根据字符串和包名来获得所对应的资源文件,在这里获取的R.drawable下的文件
int resId = mContext.getResources().getIdentifier("v"+level,"drawable",mContext.getPackageName());

imgVoice.setImageResource(resId);
}

//录音取消时的对话框状态
public void dialogRecoderCancel(){

imgDialogRecoder.setVisibility(View.VISIBLE);
imgVoice.setVisibility(View.GONE);

imgDialogRecoder.setImageResource(R.drawable.cancel);
tvDialog.setText(R.string.dialog_cacel);

}

public void tooShort(){

imgDialogRecoder.setVisibility(View.VISIBLE);
imgVoice.setVisibility(View.GONE);

imgDialogRecoder.setImageResource(R.drawable.voice_to_short);
tvDialog.setText(R.string.too_short);

}

//取消对话框
public void dialogDismiss(){

if(dialog != null){
dialog.dismiss();
}
}

}


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

<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="app_name">irecoder</string>
<string name="action_settings">Settings</string>
<string name="btn_normal">按住 录音</string>
<string name="btn_recoding">松开 结束</string>
<string name="btn_cancel">手指上滑,取消录音 </string>
<string name="dialog_recoding">手指上滑,取消录音 </string>
<string name="dialog_cacel">松开手指 取消发送</string>

</resources>


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

<?xml version="1.0" encoding="utf-8"?>
<resources>

<color name="black">#000000</color>
<color name="red">#CC0000</color>
<color name="white">#ffffff</color>

</resources>


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

package com.fuly.util;

import com.fuly.irecoder.R;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;

//定义我们自己的录音按钮
public class RecoderButton extends Button{

//按钮的三个状态

private static final int STATE_NORMAL = 1;//正常
private static final int STATE_RECODING = 2;//录音状态
private static final int STATE_CACLE = 3;//取消状态

private int mCurState = STATE_NORMAL;//记录当前按钮状态

private int Y = 50;//限定手指移动的上下宽度

private DialogManager mDialogManager;//对话框管理类

public RecoderButton(Context context, AttributeSet attrs) {
super(context, attrs);

mDialogManager = new DialogManager(context);//实例化对话框管理类

}

//捕捉按钮点击事件
public boolean onTouchEvent(MotionEvent event) {

int x = (int) event.getX();
int y =(int)event.getY();

switch(event.getAction()){

case MotionEvent.ACTION_DOWN:

mDialogManager.dialogShow();//按下按钮的同时将对话框显示出来
changeState(STATE_RECODING);//按下按钮,改变按钮状态

break;
case MotionEvent.ACTION_MOVE:

if(wantCancel(x,y)){ //如果检测到取消,则改变按钮状态为取消

changeState(STATE_CACLE);

}else{
changeState(STATE_RECODING);
}

break;
case MotionEvent.ACTION_UP:

mDialogManager.dialogDismiss();

reset();//各种设置复位

break;
default:
break;
}

return super.onTouchEvent(event);
}

//复位
private void reset() {

mCurState = STATE_NORMAL;
changeState(STATE_NORMAL);

}

//检查手指移动范围,从而确定用户是否想取消录音
private boolean wantCancel(int x, int y) {

if(x<0||x>getWidth()){

return true;
}

if(y<0||y>getHeight()+Y){
return true;
}
return false;
}

//改变状态,包括按钮等操作
private void changeState(int state) {

if(mCurState != state){

mCurState = state;

}

switch(mCurState){

case STATE_NORMAL:

setText(R.string.btn_normal);

break;
case STATE_RECODING:

setText(R.string.btn_recoding);

mDialogManager.dialogRecoding();

break;
case STATE_CACLE:

setText(R.string.btn_cancel);

mDialogManager.dialogRecoderCancel();//此时也要将对话框的状态显示出来

break;
default:
break;

}

}

}


行了,至此,我们这一阶段的工作算是完成了。下面赶紧运行以下android程序,看看有什么新的效果呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: