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

模仿微信语音聊天功能(1)项目介绍及自定义按钮实现

2015-09-24 17:54 886 查看
前言

这几天学习了慕课网上的高仿微信语音聊天功能的课程,自己动手实现了一下。在这里将其实现的过程以及代码分享下来。由于我是android的初学者,里面有不成熟的地方欢迎大家指正。

项目中所用的图片可以在这个地方下载:

http://pan.baidu.com/disk/home

项目简单介绍

首先我们来看最终实现的几张效果图吧。如下:









我们长安按钮,就会开始录音,并且会同时弹出一个麦克风的对话框提示正在录音。如果在录音的过程中手指上滑,则会将录音取消。而如果是录音时间太短,则会提示录音时间太短,完成录音。正常录音后,会显示在按钮上方。

从图中,不难看出在整个界面里,上方是是一个 ListView用来显示录音,而下面就是一个按钮。按钮有三种状态,即正常录音,取消录音和无操作时的默认状态。与按钮对应,对话框也有三种状态,即正常录音,录音取消,录音时间太短这三种状态。因此完成这个小项目,需要我们具备ListView的基本知识,熟悉自定义按钮和自定义对话框。同时对android提供的录音器类和音频播放的类也要基本了解。

我打算将这个小项目分成以下几步来做:

(1)完成按钮的交互设计。

(2)完成对话框的设计。

(3)完成录音时的代码部分,并集成到之前的代码里。

(4)完成播放设置,项目也从此结束。

上面只是我为了学习知识,简单实现的UI。并不是很好看,读者有要求,可以自己耐心调一调,让界面好看一点。在这里我不打算讲解所涉及的android中的基础知识,而是直接写项目的代码。好了,我们开始第一步,完成按钮的设计,即实现按钮的三种状态。

按钮的实现

首先把主界面给搭建起来,即上方是LisetView,下面是一个我们自定义的按钮。新建activity_main.xml,代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<ListView
android:id="@+id/rec_listview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<com.fuly.util.RecoderButton
android:id="@+id/btn_recoder"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:background="@drawable/btn_bg"
android:layout_marginTop="5dp"
android:layout_marginBottom="3dp"
android:text="@string/btn_normal"
android:layout_gravity="center"/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/black"/>

</FrameLayout>

</LinearLayout>


接下来,在res文件下新建文件夹drawable,然后在里面新建btn_bg.xml。这是为自定义的按钮提供不同状态下的按钮背景图片。代码如下:

<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 没有触摸时的图片 -->
<item
android:state_focused="true"
android:state_enabled="true"
android:state_pressed="false"
android:drawable="@drawable/btn_normal"/>
<!-- 触摸时的图片 -->
<item
android:state_enabled="true"
android:state_pressed="true"
android:drawable="@drawable/btn_press"/>
<item
android:state_enabled="true"
android:state_checked="true"
android:drawable="@drawable/btn_press"/>

<!-- 默认时的背景图片-->
<item

android:drawable="@drawable/btn_normal"/>

</selector>


然后在res下的values文件夹下的strings里面,定义按钮需要显示的文本,如下:

<?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>

</resources>


接来准备工作都做的差不多了。然后实现我们的自定义按钮。新建类RecoderButton,该类继承自Button。具体代码如下:

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;//限定手指移动的上下宽度

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

}

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

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

switch(event.getAction()){

case MotionEvent.ACTION_DOWN:

changeState(STATE_RECODING);//按下按钮,改变按钮状态

break;
case MotionEvent.ACTION_MOVE:

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

changeState(STATE_CACLE);

}else{
changeState(STATE_RECODING);
}

break;
case MotionEvent.ACTION_UP:

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);

break;
case STATE_CACLE:

setText(R.string.btn_cancel);

break;
default:
break;

}

}

}


最后,我们在主类中加载activity_main布局。如下:

package com.fuly.irecoder;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

}


然后我们运行这个android项目即可。就会发现随着我们手指的移动,按钮呈现出我们想要的状态。

当然了,为了好看,我们在AndroidManifest文件里让app全屏显示。只需要加上这么一句即可:

android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"


好了,我们的第一步总算迈出去了。主要就是一个自定义按钮的实现。下一文章中我们将会实现对话框。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: