模仿微信语音聊天功能(2)对话框的实现
2015-09-24 18:19
826 查看
上一篇文章里,我们介绍了整个项目以及实现了按钮功能。没有读的可以点击一下链接:
/article/6123592.html
在本篇文章里,我们做第二步,也就是实现几种状态的对话框:录音状态的对话框,取消录音状态下的对话框,录音时间太短下的对话框。然后将对话框集成到我们点击时的按钮操作中。
首先我们需要自定义一个对话框的布局。不难想出,布局中的上方需要并排放置两张图片,下方是一个用来提示状态的文本。如果对话框切换到录音时的状态,我们就让其中的一张图片显示,另外一张不显示即可。所以整体的布局是这样的,名称为dialog.xml:
接下来我们定义一下对话框的样式,在这里关键是要求对话框弹出时,不要屏幕掉屏幕,也就是屏幕的其他部分仍然是点击有效的。在res的values下的styles下,加入一下代码:
然后我们实现对话框这个类,代码如下:
然后修改strings.xml文件。为什么所有的文字我们非得这么麻烦的放在这个文件里引用的。答案是:这样子做可以有效的防止你的app的内存占用。所以要养成良好的编程习惯。不多说了,代码如下:
然后我们要配置颜色了,在res下的values文件夹下的color.xml(如果没有你就新建一个)里面写上下面的代码:
好了,关于对话框的工作我们基本上算是完成了。下面将其集成到按钮中,我们打开RecoderButton类,修改其中的代码如下:
行了,至此,我们这一阶段的工作算是完成了。下面赶紧运行以下android程序,看看有什么新的效果呢?
/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程序,看看有什么新的效果呢?
相关文章推荐
- weiphp微信支付开发教程
- ios9适配 微信支付/支付宝支付
- 模仿微信语音聊天功能(1)项目介绍及自定义按钮实现
- iOS 9系统策略更新,使用微信SDK的开发者注意升级
- 免费课程《微信公众号开发》开讲啦!!!
- Nagios 安装及微信短信提醒
- JSSDK,微信JS接口,分享朋友圈狀態捕獲,項目實例
- ios9适配中的分享(微信、新浪微博、QQ、QQ空间、支付宝)
- 微信开发的资料
- iOS 9系统策略更新,使用微信SDK的开发者注意升级
- java编写的九九乘法表小程序
- 自定义控件--CircleImageView(类似于QQ、微信圆形头像自定义控件)
- Nagios 安装及微信短信提醒
- 爱快云微信连wifi3.1用户前期准备工作
- 微信红包体系设计分析
- 一个c#即时监控小程序
- iOS 微信支付接入最新的完整流程
- 使用zookeeper来解决在分布式系统中单节点维护微信token生命周期的容灾demo【已抽象分离】[分布式锁][9.28更新]
- 微信连wifi3.1总结
- 模拟微信平台token验证