溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android自定義View實現微信語音界面

發(fā)布時間:2020-10-14 09:07:47 來源:腳本之家 閱讀:233 作者:Black_Hao 欄目:移動開發(fā)

前言

因為最近的項目需要使用錄音功能,開始的想法是Button+OnTouchListener+Dialog實現,在大部分手機中都沒問題,只有MI8會偶爾無法觸發(fā)MotionEvent.ACTION_UP,導致程序異常。所以就自己寫了個自定義View來實現,主要也是通過監(jiān)聽
OnTouchListener+Dialog來實現。這里只實現了自定義View,并不涉及錄音和播放。效果圖如下:

Android自定義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;
  //當前是否是按下狀態(tài)
  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);
    }
  }

}

結語

源碼github地址:仿微信語音界面

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI