Android實現(xiàn)三角形氣泡效果方式匯總

在開發(fā)過程中惦积,我們可能會經(jīng)常遇到這樣的需求樣式:

這張圖是截取京東消息通知的彈出框昔馋,我們可以看到右上方有個三角形的氣泡效果筹吐,這只是其中一種,三角形的方向還可以是上绒极、下骏令、左、右垄提。

通過截圖可以發(fā)現(xiàn)榔袋,氣泡由正三角形和圓角長方形組成,于是可以通過組合來形成三角形氣泡的效果铡俐,下面我們通過三種方式進行實現(xiàn)凰兑。

實現(xiàn)方式:
1、通過.9圖進行實現(xiàn)审丘;
2吏够、通過shape方式實現(xiàn);
3滩报、通過自定義view的方式實現(xiàn)锅知;

實現(xiàn)邏輯:

1、通過.9圖進行實現(xiàn)

這種方式就不用說了吧脓钾,找你們UI小姐姐切一個.9圖售睹,使用即可,不過這種方式的圖片需要占一定體積哦可训。

2昌妹、通過shape方式實現(xiàn)

  • 正三角形
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <rotate
            android:fromDegrees="45"
            android:pivotX="-40%"
            android:pivotY="80%">
            <shape android:shape="rectangle">
                <size
                    android:width="15dp"
                    android:height="15dp" />
                <solid android:color="#ffffff" />
            </shape>
        </rotate>
    </item>
</layer-list>
  • 倒三角形
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item>
        <rotate
            android:fromDegrees="45"
            android:pivotX="135%"
            android:pivotY="15%">
            <shape android:shape="rectangle">
                <size
                    android:width="15dp"
                    android:height="15dp" />
                <solid android:color="#ffffff" />
            </shape>
        </rotate>
    </item>
</layer-list>
  • 左三角形
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <rotate
            android:fromDegrees="-45"
            android:pivotX="85%"
            android:pivotY="-35%">>
            <shape android:shape="rectangle">
                <size
                    android:width="15dp"
                    android:height="15dp" />
                <solid android:color="#ffffff" />
            </shape>
        </rotate>
    </item>
</layer-list>
  • 右三角形
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <rotate
            android:fromDegrees="-45"
            android:pivotX="15%"
            android:pivotY="135%">>
            <shape android:shape="rectangle">
                <size
                    android:width="15dp"
                    android:height="15dp" />
                <solid android:color="#ffffff" />
            </shape>
        </rotate>
    </item>
</layer-list>

上面就是通過shape方式實現(xiàn)各個方向的代碼,這種方式缺點比較明顯握截,如果要變化不同的角的位置需要再寫不同的布局飞崖。

3、通過自定義view的方式實現(xiàn)

由于是比較簡單這里就不講解每個怎么搞了谨胞,可以復(fù)制過去直接用

  • 添加自定義屬性
<declare-styleable name="TriangleView">
        <attr name="trv_color" format="color" />
        <attr name="trv_direction">
            <enum name="top" value="0" />
            <enum name="bottom" value="1" />
            <enum name="right" value="2" />
            <enum name="left" value="3" />
        </attr>
 </declare-styleable>
  • 自定義代碼文件

public class TriangleView extends View {
    private static final int TOP = 0;
    private static final int BOTTOM = 1;
    private static final int RIGHT = 2;
    private static final int LEFT = 3;
    private static final int DEFUALT_WIDTH = 10;
    private static final int DEFUALT_HEIGHT = 6;
    private static final int DEFUALT_COLOR = R.color.FFF;
    private Paint mPaint;
    private int mColor;
    private int mWidth;
    private int mHeight;
    private int mDirection;
    private Path mPath;

    public TriangleView(final Context context) {
        this(context, null);
    }

    public TriangleView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TriangleView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TriangleView, 0, 0);
        mColor = typedArray.getColor(R.styleable.TriangleView_trv_color, ContextCompat.getColor(getContext(), DEFUALT_COLOR));
        mDirection = typedArray.getInt(R.styleable.TriangleView_trv_direction, mDirection);
        typedArray.recycle();
        mPaint.setColor(mColor);
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
        mPath = new Path();
        mDirection = TOP;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = MeasureSpec.getSize(widthMeasureSpec);
        mHeight = MeasureSpec.getSize(heightMeasureSpec);
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (mWidth == 0 || widthMode != MeasureSpec.EXACTLY) {
            mWidth = (int) PixelUtil.dp2px(DEFUALT_WIDTH);
        }
        if (mHeight == 0 || heightMode != MeasureSpec.EXACTLY) {
            mHeight = (int) PixelUtil.dp2px(DEFUALT_HEIGHT);
        }
        setMeasuredDimension(mWidth, mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        switch (mDirection) {
            case TOP:
                mPath.moveTo(0, mHeight);
                mPath.lineTo(mWidth, mHeight);
                mPath.lineTo(mWidth / 2, 0);
                break;
            case BOTTOM:
                mPath.moveTo(0, 0);
                mPath.lineTo(mWidth / 2, mHeight);
                mPath.lineTo(mWidth, 0);
                break;
            case RIGHT:
                mPath.moveTo(0, 0);
                mPath.lineTo(0, mHeight);
                mPath.lineTo(mWidth, mHeight / 2);
                break;
            case LEFT:
                mPath.moveTo(0, mHeight / 2);
                mPath.lineTo(mWidth, mHeight);
                mPath.lineTo(mWidth, 0);
                break;
            default:
                break;
        }

        mPath.close();
        canvas.drawPath(mPath, mPaint);
    }
}
  • 布局文件添加
<com.sjl.keeplive.triange.TriangleView
        android:layout_width="10dp"
        android:layout_height="6dp"
        app:trv_color="@color/FFF"
        app:trv_direction="top" />

通過自定義的方式可以搞定四個方向固歪,而且在代碼中也可以使用,動態(tài)添加胯努,動態(tài)改變顏色牢裳,還是比較好的方式术瓮。

到這里就完成啦.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市贰健,隨后出現(xiàn)的幾起案子胞四,更是在濱河造成了極大的恐慌,老刑警劉巖伶椿,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辜伟,死亡現(xiàn)場離奇詭異,居然都是意外死亡脊另,警方通過查閱死者的電腦和手機导狡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來偎痛,“玉大人旱捧,你說我怎么就攤上這事〔嚷螅” “怎么了枚赡?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谓谦。 經(jīng)常有香客問我贫橙,道長,這世上最難降的妖魔是什么反粥? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任卢肃,我火速辦了婚禮,結(jié)果婚禮上才顿,老公的妹妹穿的比我還像新娘莫湘。我一直安慰自己,他們只是感情好郑气,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布幅垮。 她就那樣靜靜地躺著,像睡著了一般竣贪。 火紅的嫁衣襯著肌膚如雪军洼。 梳的紋絲不亂的頭發(fā)上巩螃,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天演怎,我揣著相機與錄音,去河邊找鬼避乏。 笑死爷耀,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拍皮。 我是一名探鬼主播歹叮,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼跑杭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了咆耿?” 一聲冷哼從身側(cè)響起德谅,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎萨螺,沒想到半個月后窄做,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡慰技,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年椭盏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吻商。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡掏颊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出艾帐,到底是詐尸還是另有隱情乌叶,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布柒爸,位于F島的核電站枉昏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏揍鸟。R本人自食惡果不足惜兄裂,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望阳藻。 院中可真熱鬧晰奖,春花似錦、人聲如沸腥泥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛔外。三九已至蛆楞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間夹厌,已是汗流浹背豹爹。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留矛纹,地道東北人臂聋。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親孩等。 傳聞我的和親對象是個殘疾皇子艾君,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容