转载请注明出处:https://blog.csdn.net/a512337862/article/details/90602156

前言

因为最近的项目需要使用录音功能,开始的想法是Button+OnTouchListener+Dialog实现,在大部分手机中都没问题,只有MI8会偶尔无法触发MotionEvent.ACTION_UP,导致程序异常。所以就自己写了个自定义View来实现,主要也是通过监听
OnTouchListener+Dialog来实现。这里只实现了自定义View,并不涉及录音和播放。效果图如下:

代码

代码并不复杂,配合注释应该很容易理解。

/** * Author : BlackHao * Time : 2019/4/18 14:03 * Description : 自定义录音按钮布局界面 */public class PressedView extends View implements View.OnTouchListener {    private int normalRes;    private String normalText = "";    private int pressedRes;    private String pressedText = "";    //    private Paint paint;    private Rect rect;    //当前是否是按下状态    private boolean isPressed = false;    //    private PressCallback callback;    //按下的位置y坐标    private int pressedY = 0;    //当前是否是outSize    private boolean isOutSize = false;    //字体dp大小    private static int TEXT_SIZE = 20;    //对话框相关    private Dialog soundVolumeDialog = null;    //音量图片    private ImageView soundVolumeImg = null;    //对话框背景    private RelativeLayout soundVolumeLayout = null;    public PressedView(Context context) {        super(context);        init();    }    public PressedView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        init();    }    public PressedView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private void init() {        //        paint = new Paint();        paint.setAntiAlias(true);        paint.setTextSize(DensityUtil.dip2px(getContext(), TEXT_SIZE));        paint.setColor(Color.WHITE);        rect = new Rect();        //        normalRes = R.drawable.blue_btn_bk;        normalText = "按住 说话";        pressedRes = R.drawable.red_btn_bk;        pressedText = "松开 结束";        //        setOnTouchListener(this);        //        initSoundVolumeDlg();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        rect.set(0, 0, getWidth(), getHeight());        if (!isPressed) {            setBackgroundResource(normalRes);            drawTextOnRect(canvas, rect, normalText);        } else {            setBackgroundResource(pressedRes);            drawTextOnRect(canvas, rect, pressedText);        }    }    @Override    public boolean onTouch(View v, MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                pressedY = (int) event.getRawY();                isOutSize = false;                if (!isPressed) {                    isPressed = true;                    postInvalidate();                    if (callback != null) {                        //回调                        callback.onStartRecord();                        //按下,弹出对话框                        soundVolumeImg.setImageResource(R.mipmap.sound_volume_01);                        soundVolumeImg.setVisibility(View.VISIBLE);                        soundVolumeLayout.setBackgroundResource(R.mipmap.sound_volume_default_bk);                        soundVolumeDialog.show();                    }                }                break;            case MotionEvent.ACTION_UP:                if (isPressed) {                    isPressed = false;                    postInvalidate();                    if (callback != null) {                        int upY = (int) event.getRawY();                        if (pressedY - upY < getHeight()) {                            //录音结束                            if (soundVolumeDialog.isShowing()) {                                soundVolumeDialog.dismiss();                            }                            callback.onStopRecord();                        } else {                            //录音取消                            if (soundVolumeDialog.isShowing()) {                                soundVolumeDialog.dismiss();                            }                            callback.onCancelRecord();                        }                    }                }                break;            case MotionEvent.ACTION_MOVE:                if (isPressed && callback != null) {                    int upY = (int) event.getRawY();                    if (pressedY - upY < getHeight()) {                        if (isOutSize) {                            isOutSize = false;                            soundVolumeLayout.setBackgroundResource(R.mipmap.sound_volume_default_bk);                        }                    } else {                        if (!isOutSize) {                            isOutSize = true;                            soundVolumeLayout.setBackgroundResource(R.mipmap.sound_volume_cancel_bk);                        }                    }                }                break;        }        return true;    }    public void setCallback(PressCallback callback) {        this.callback = callback;    }    public interface PressCallback {        //开始录音        void onStartRecord();        //停止录音        void onStopRecord();        //取消录音        void onCancelRecord();    }    /**     * 在指定矩形中间drawText     *     * @param canvas     画布     * @param targetRect 指定矩形     * @param text       需要绘制的Text     */    private void drawTextOnRect(Canvas canvas, Rect targetRect, String text) {        Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();        // 获取baseLine        int baseline = targetRect.top + (targetRect.bottom - targetRect.top - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;        // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX()        paint.setTextAlign(Paint.Align.CENTER);        canvas.drawText(text, targetRect.centerX(), baseline, paint);    }    /**     * 初始化音量信息对话框     */    private void initSoundVolumeDlg() {        soundVolumeDialog = new Dialog(getContext(), R.style.SoundVolumeStyle);        soundVolumeDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);        soundVolumeDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);        soundVolumeDialog.setContentView(R.layout.tt_sound_volume_dialog);        soundVolumeDialog.setCanceledOnTouchOutside(true);        soundVolumeImg = (ImageView) soundVolumeDialog.findViewById(R.id.sound_volume_img);        soundVolumeLayout = (RelativeLayout) soundVolumeDialog.findViewById(R.id.sound_volume_bk);    }    /**     * 根据分贝值设置录音时的音量动画     */    public void setVolume(int voiceValue) {        if (voiceValue < 200.0) {            soundVolumeImg.setImageResource(R.mipmap.sound_volume_01);        } else if (voiceValue > 200.0 && voiceValue < 600) {            soundVolumeImg.setImageResource(R.mipmap.sound_volume_02);        } else if (voiceValue > 600.0 && voiceValue < 1200) {            soundVolumeImg.setImageResource(R.mipmap.sound_volume_03);        } else if (voiceValue > 1200.0 && voiceValue < 2400) {            soundVolumeImg.setImageResource(R.mipmap.sound_volume_04);        } else if (voiceValue > 2400.0 && voiceValue < 10000) {            soundVolumeImg.setImageResource(R.mipmap.sound_volume_05);        } else if (voiceValue > 10000.0 && voiceValue < 28000.0) {            soundVolumeImg.setImageResource(R.mipmap.sound_volume_06);        } else if (voiceValue > 28000.0) {            soundVolumeImg.setImageResource(R.mipmap.sound_volume_07);        }    }}

结语

  1. 源码github地址 : https://github.com/LuoChen-Hao/BlackHaoCustomView

更多相关文章

  1. Android(安卓)系统各种音量的获取及音量的上调与下调
  2. Activity生命周期和对话框
  3. Android(安卓)Dialog种类大全,让Activity显示在另外一个Activity
  4. 菜鸟的安卓实习之路---设置Activity的大小
  5. Android广播、Service、Activity综合使用
  6. Android(安卓)官方推荐 : DialogFragment 创建对话框
  7. setVolumeControlStream(int streamType)
  8. Android(安卓)dialog用法(二)
  9. Android在开发中的实用技巧之DialogFragment和AlertDialog(v7包)

随机推荐

  1. 横竖屏切换时不销毁当前activity 和 锁定
  2. 有米平台 发布android软件教程
  3. android RecyclerView adapter 封装
  4. android开发之res下的menu (xml+代码的形
  5. Android(安卓)studio 使用AIDL 无法impor
  6. android个人中心页面的设计
  7. 自定义圆角button上下间距问题
  8. Android(安卓)button靠右侧显示
  9. android vlc 编译
  10. android 录音