android自定義帶箭頭對話框

本文實例為大傢分享瞭android自定義帶箭頭對話框的具體代碼,供大傢參考,具體內容如下

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
 
import com.sankuai.shangou.stone.util.DensityUtil;
import com.sankuai.waimai.store.search.R;
 
/**
 * Created by Android Studio. User: liangyongyao Date: 2021/3/7 Des: 帶倒三角的氣泡
 */
public class BubbleArrowTextView extends android.support.v7.widget.AppCompatTextView {
 
 private final static int TRIANGLE_DIRECTION_TOP = 1;
 private final static int TRIANGLE_DIRECTION_BOTTOM = 2;
 private final static int TRIANGLE_DIRECTION_LEFT = 1;
 private final static int TRIANGLE_DIRECTION_RIGHT = 2;
 
 
 private Paint mPaint;
 private Paint mStrokePaint;
 
 private int mBgColor;
 private int mStrokeColor;
 private int mStrokeWidth;
 private int mTotalHeight;
 private int mTotalWidth;
 private int mLabelHeight;
 private int mTriangleHeight;
 private int mTriangleWidth;
 private int mRadius;
 private int triangleDirection;
 
 public BubbleArrowTextView(Context context) {
  this(context, null);
 }
 
 public BubbleArrowTextView(Context context,
   @Nullable AttributeSet attrs) {
  this(context, attrs, 0);
 }
 
 public BubbleArrowTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init(context, attrs, defStyleAttr);
 }
 
 public void init(Context context, AttributeSet attrs, int defStyleAttr) {
  if (attrs != null) {
   TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BubbleArrowTextView);
   mBgColor = a.getColor(R.styleable.BubbleArrowTextView_bubbleColor, 0);
   mStrokeColor = a.getColor(R.styleable.BubbleArrowTextView_bubbleStrokeColor, 0);
   mRadius = a.getDimensionPixelOffset(R.styleable.BubbleArrowTextView_bubbleRadius, 0);
   mStrokeWidth = a.getDimensionPixelOffset(R.styleable.BubbleArrowTextView_bubbleStrokeWidth, 0);
   mTriangleHeight = a.getDimensionPixelOffset(R.styleable.BubbleArrowTextView_triangleHeight,
     DensityUtil.dip2px(context, 6));
   mTriangleWidth = a.getDimensionPixelOffset(R.styleable.BubbleArrowTextView_triangleWidth, DensityUtil.dip2px(context, 3.5f));
   triangleDirection = a.getInt(R.styleable.BubbleArrowTextView_triangleDirection, 0);
   a.recycle();
  }
 
  setGravity(Gravity.CENTER);
  initPaint();
 }
 
 //初始化畫筆
 public void initPaint() {
  mPaint = new Paint();
  mPaint.setAntiAlias(true);
  mPaint.setStyle(Paint.Style.FILL);
  mPaint.setTextSize(getPaint().getTextSize());
  mPaint.setDither(true);
 }
 
 //初始化邊框線畫筆
 public void initStrokePaint() {
  mStrokePaint = new Paint();
  mStrokePaint.setAntiAlias(true);
  mStrokePaint.setStyle(Paint.Style.FILL);
  mStrokePaint.setDither(true);
 }
 
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  mLabelHeight = getFontHeight() + getPaddingTop() + getPaddingBottom();
  mTotalHeight = mLabelHeight + mTriangleHeight * 2 + mStrokeWidth * 2;
  mTotalWidth = getPaddingLeft() + getFontWidth() + getPaddingRight() + mStrokeWidth * 2;
  setMeasuredDimension(mTotalWidth, mTotalHeight);
 }
 @Override
 protected void onDraw(Canvas canvas) {
  drawView(canvas);
  super.onDraw(canvas);
 }
 
 //繪制氣泡
 private void drawView(Canvas canvas) {
  if (mStrokeColor != 0 && mStrokeWidth != 0) {
   initStrokePaint();
   mStrokePaint.setColor(mStrokeColor);
   drawRound(canvas, mStrokePaint, 0);
   drawTriangle(canvas, mStrokePaint, 0);
  }
  if (mBgColor != 0) {
   mPaint.setColor(mBgColor);
   drawRound(canvas, mPaint, mStrokeWidth);
   drawTriangle(canvas, mPaint, mStrokeWidth);
  }
 }
 
 //繪制矩形
 private void drawRound(Canvas canvas, Paint paint, int strokeWidth) {
  canvas.drawRoundRect(strokeWidth, mTriangleHeight + strokeWidth,
    mTotalWidth - strokeWidth, mTotalHeight - mTriangleHeight - strokeWidth,
    mRadius, mRadius, paint);
 }
 
 //繪制三角形
 private void drawTriangle(Canvas canvas, Paint paint, int strokeWidth) {
  Path path = new Path();
  switch (triangleDirection) {
   //上
   case TRIANGLE_DIRECTION_TOP:
    path.moveTo(mTotalWidth * 0.8f - mTriangleWidth / 2 + strokeWidth / 2, mTriangleHeight + strokeWidth);
    path.lineTo(mTotalWidth * 0.8f, strokeWidth + strokeWidth / 2);
    path.lineTo(mTotalWidth * 0.8f + mTriangleWidth / 2 - strokeWidth / 2, mTriangleHeight + strokeWidth);
    break;
   //下
   case TRIANGLE_DIRECTION_BOTTOM:
    path.moveTo(mTotalWidth * 0.8f - mTriangleWidth/2 + strokeWidth / 2, mTotalHeight - mTriangleHeight
      - strokeWidth);
    path.lineTo(mTotalWidth * 0.8f, mTotalHeight - strokeWidth - strokeWidth / 2);
    path.lineTo(mTotalWidth * 0.8f + mTriangleWidth/2 - strokeWidth / 2, mTotalHeight - mTriangleHeight
      - strokeWidth);
    break;
   default:
    return;
  }
  canvas.drawPath(path, paint);
 }
 
 //根據字號求字體高度
 private int getFontHeight() {
  Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
  return Math.round(fontMetrics.descent - fontMetrics.ascent);
 }
 
 //根據字號求字體寬度
 private int getFontWidth() {
  return (int) mPaint.measureText(getText().toString());
 }
} 

xml:

<declare-styleable name="BubbleArrowTextView">
    <attr name="bubbleColor" format="reference|color" />
    <attr name="bubbleStrokeColor" format="reference|color" />
    <attr name="bubbleStrokeWidth" format="dimension" />
    <attr name="triangleHeight" format="dimension" />
    <attr name="triangleWidth" format="dimension" />
    <attr name="bubbleRadius" format="dimension" />
    <attr name="triangleDirection">
      <flag name="top" value="1" />
      <flag name="bottom" value="2" />
    </attr>
</declare-styleable>

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

推薦閱讀: