Android仿微信语音聊天(一)

AudioRecorderButton

State:STATE_NORMAL, STATE_RECORDING, STATE_WANT_TO_CANCEL


DialogManager

Style:RECORDING, WANT_TO_CANCEL, TOO_SHORT


AudioManager

prepare();

cancel();

release();

getVoiceLeval();


class AudioRecorderButton {

onTouchEvent() {

DOWN:

changeButtonState(STATE_RECORDING);

Longclick -> AudioManager.prepare() -> 

end prepared -> DIalogManager.showDialog(RECORDING)

MOVE:

if (wantCancel(x, y) {

DialogManager.showDialog(WANT_TO_CANCEL)

changeButtonState(STATE_WANT_TO_CANCEL);

} else {

DialogManager.showDialog(RECORDING)

changeButtonState(STATE_RECORDING);

}

UP:

if (wantCancel == curState) {

AudioManager.cancel();

}

if (STATE_RECORDING == curState) {

AudioManager.release();

callbackToActivity(url, time);

}

}

}


实现自定义语音按钮


strings.xml

<resources>

    <string name="app_name">RecorderDemo</string>
    <string name="action_settings">Settings</string>
    <string name="str_recorder_normal">按住 说话</string>
    <string name="str_recorder_recording">松开 结束</string>
    <string name="str_recorder_want_cancel">松开手指,取消发送</string>

</resources>



btn_recording_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#ffffff"/>
    <stroke android:color="#9b9b9b" android:width="1px"/>
    <corners android:radius="3dp"/>

</shape>


btn_recording.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#eeeeee"/>
    <stroke android:color="#9b9b9b" android:width="1px"/>
    <corners android:radius="3dp"/>

</shape>



activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/id_listview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#ebebeb"
        android:divider="@null"
        android:dividerHeight="10dp">
    </ListView>

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

        <com.example.recorderdemo.view.AudioRecorderButton
            android:id="@+id/id_recorder_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:layout_marginRight="50dp"
            android:layout_marginTop="6dp"
            android:layout_marginBottom="7dp"
            android:gravity="center"
            android:padding="5dp"
            android:text="@string/str_recorder_normal"
            android:minHeight="0dp"
            android:textColor="#727272"
            android:background="@drawable/btn_recorder_normal">
        </com.example.recorderdemo.view.AudioRecorderButton>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#ccc">
        </View>

    </FrameLayout>

</LinearLayout>


AudioRecorderButton

public class AudioRecorderButton extends Button {

    private static final int DISTANCE_Y_CANCEL = 50;

    //默认状态
    private static final int STATE_NORMAL = 1;
    //录音状态
    private static final int STATE_RECORDING = 2;
    //取消状态
    private static final int STATE_WANT_TO_CANCEL = 3;

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

    //已经开始录音
    private boolean isRecording = false;

    public AudioRecorderButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AudioRecorderButton(Context context) {
        this(context, null);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int action = event.getAction();

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

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                //TODO 用于测试
                isRecording = true;
                chanegState(STATE_RECORDING);
                break;
            case MotionEvent.ACTION_MOVE:

                if (isRecording) {
                    //根据x, y的坐标,判断是否想要取消
                    if (wantToCancel(x, y)) {
                        chanegState(STATE_WANT_TO_CANCEL);
                    } else {
                        chanegState(STATE_RECORDING);
                    }
                }

                break;
            case MotionEvent.ACTION_UP:

                if (mCurState == STATE_RECORDING) {
                    //release
                    //callbackToAct
                } else if (mCurState == STATE_WANT_TO_CANCEL) {
                    //cancel
                }

                reset();

                break;
        }

        return super.onTouchEvent(event);

    }

    /**
     * 恢复状态及标志位
     */
    private void reset() {
        isRecording = false;
        chanegState(STATE_NORMAL);
    }

    private boolean wantToCancel(int x, int y) {
        //判断手指的横坐标是否超出按钮范围
        if (x < 0 || x > getWidth()) {
            return true;
        }
        //判断手指的纵坐标是否超出按钮范围
        if (y < -DISTANCE_Y_CANCEL || y > getHeight() + DISTANCE_Y_CANCEL) {
            return true;
        }
        return false;
    }

    private void chanegState(int state) {
        if (mCurState != state) {
            mCurState = state;
            switch (state) {
                case STATE_NORMAL:
                    setBackgroundResource(R.drawable.btn_recorder_normal);
                    setText(R.string.str_recorder_normal);
                    break;
                case STATE_RECORDING:
                    setBackgroundResource(R.drawable.btn_recording);
                    setText(R.string.str_recorder_recording);
                    if (isRecording) {
                        //TODO Dialog.recording();
                    }
                    break;
                case STATE_WANT_TO_CANCEL:
                    setBackgroundResource(R.drawable.btn_recording);
                    setText(R.string.str_recorder_want_cancel);
                    //TODO Dialog.wantCancel();
                    break;
            }
        }
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值