android自定義帶箭頭對(duì)話框
本文實(shí)例為大家分享了android自定義帶箭頭對(duì)話框的具體代碼,供大家參考,具體內(nèi)容如下
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();
}
//初始化畫(huà)筆
public void initPaint() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextSize(getPaint().getTextSize());
mPaint.setDither(true);
}
//初始化邊框線畫(huà)筆
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);
}
//根據(jù)字號(hào)求字體高度
private int getFontHeight() {
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
return Math.round(fontMetrics.descent - fontMetrics.ascent);
}
//根據(jù)字號(hào)求字體寬度
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>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android自定義日歷Calender代碼實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Android自定義日歷Calender實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
android為L(zhǎng)istView每個(gè)Item上面的按鈕添加事件
本篇文章主要介紹了android為L(zhǎng)istView每個(gè)Item上面的按鈕添加事件,有興趣的同學(xué)可以了解一下。2016-11-11
Android xUtils更新到3.0后的基本使用規(guī)則詳解
xUtils是基于android的開(kāi)發(fā)框架,簡(jiǎn)化了很多的開(kāi)發(fā)步驟,可以說(shuō)是非常好的開(kāi)發(fā)工具。下面小編給大家?guī)?lái)了Android xUtils更新到3.0后的基本使用規(guī)則詳解,感興趣的朋友一起學(xué)習(xí)吧2016-08-08
Android如何防止apk程序被反編譯(尊重勞動(dòng)成果)
作為Android應(yīng)用開(kāi)發(fā)者,不得不面對(duì)一個(gè)尷尬的局面,就是自己辛辛苦苦開(kāi)發(fā)的應(yīng)用可以被別人很輕易的就反編譯出來(lái),天下痛苦之事莫過(guò)于此啊,本文會(huì)介紹一種防止apk程序被反編譯的方法,感興趣的朋友可以了解下哦2013-01-01
Android 使用Zbar實(shí)現(xiàn)掃一掃功能
這篇文章主要介紹了Android 使用Zbar實(shí)現(xiàn)掃一掃功能,本文用的是Zbar實(shí)現(xiàn)掃一掃,因?yàn)楦鶕?jù)本人對(duì)兩個(gè)庫(kù)的使用比較,發(fā)現(xiàn)Zbar解碼比Zxing速度要快,實(shí)現(xiàn)方式也簡(jiǎn)單,需要的朋友可以參考下2023-03-03
手把手教學(xué)Android用jsoup解析html實(shí)例
本篇文章主要介紹了手把手教學(xué)Android用jsoup解析html實(shí)例,jsoup 是一款Java 的HTML解析器。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
Android開(kāi)發(fā)使用自定義View將圓角矩形繪制在Canvas上的方法
這篇文章主要介紹了Android開(kāi)發(fā)使用自定義View將圓角矩形繪制在Canvas上的方法,結(jié)合實(shí)例形式分析了Android自定義view繪制圓角矩形的相關(guān)方法與使用技巧,需要的朋友可以參考下2017-10-10

