Android自定義View實(shí)現(xiàn)可展開、會(huì)呼吸的按鈕
不專門練習(xí)的話,自定義View的知識(shí)又忘了許多。正好新項(xiàng)目里有這個(gè)需求,就再練習(xí)一下,代碼已上傳:地址
可以修改文本、文字大小、各種顏色:
1、按照國際慣例,就是新建attrs,寫各種需要的屬性,然后獲取,新建各種所需的Paint、Rect,重寫onMeasure計(jì)算寬高,重寫onDraw畫圖搞起。。
2、關(guān)于可展開效果,其實(shí)就是點(diǎn)擊發(fā)布時(shí),啟動(dòng)一個(gè)ValueAnimator,對(duì)一個(gè)圓角矩形的左邊距離不斷改變:
int mBackgroundRectFLeft; RectF mBackgroundRectF = new RectF(); @Override protected void onDraw(Canvas canvas) { mBackgroundRectF.set(mBackgroundRectFLeft, 0, getWidth(), getHeight()); canvas.drawRoundRect(mBackgroundRectF, mOuterRadius, mOuterRadius, mmBackgroundRectPaint);//圓角背景矩形 } private void openButton() { ValueAnimator rectLeftAnim = ValueAnimator.ofInt(mBackgroundRectFLeft, mArcWidth / 2); rectLeftAnim.setDuration(250); ValueAnimator textAlphaAnim = ValueAnimator.ofInt(0, mItemTextAlpha); textAlphaAnim.setDuration(120); rectLeftAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mBackgroundRectFLeft = (int) animation.getAnimatedValue(); invalidate(); } }); }
3、關(guān)于呼吸效果,就是一個(gè)對(duì)外圓圈半徑改變的ValueAnimator:
mBreatheRadius = getHeight() / 2 - mArcWidth / 4; mBreatheAnim = ValueAnimator.ofFloat(mBreatheRadius, mBreatheRadius - mArcWidth / 2); mBreatheAnim.setDuration(1000); mBreatheAnim.setRepeatMode(ValueAnimator.REVERSE); mBreatheAnim.setRepeatCount(Integer.MAX_VALUE); mBreatheAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mBreatheRadius = (float) animation.getAnimatedValue(); invalidate(); } }); mBreatheAnim.start(); @Override protected void onDraw(Canvas canvas) { canvas.drawCircle(mInnerCircleCenterX, mInnerCircleCenterY, mBreatheRadius, mBreathePaint);//呼吸圈
4、關(guān)于文字位置居中計(jì)算,以前我用一個(gè)Rect,用
paint.getTextBounds(text, 0, text.length(), mTextRect); int textWidth = mTextRect.width(); int textHeight = mTextRect.height();
這樣計(jì)算不準(zhǔn)確,可能是因?yàn)榉祷氐膶捀呤莍nt值,應(yīng)該用FontMetrics類來計(jì)算,大家可以搜一下:
float buttonTextWidth = mButtonTextPaint.measureText(mButtonStr, 0, mButtonStr.length()); Paint.FontMetrics publishFontMetrics = mButtonTextPaint.getFontMetrics(); canvas.drawText(mButtonStr, 0, mButtonStr.length(), getWidth() - mOuterRadius - mArcWidth / 2 - buttonTextWidth / 2, mOuterRadius + mArcWidth / 2 + -(publishFontMetrics.ascent + publishFontMetrics.descent) / 2, mButtonTextPaint);
5、再有就是OnTouchEvent的處理,因?yàn)檫@個(gè)控件不是一直都是展開狀態(tài),那么就要求控件在閉合的時(shí)候,要不影響該控件下層控件對(duì)點(diǎn)擊的處理。比如我這個(gè)ExpandableBreathngButton,下層是一個(gè)RecyclerView,并設(shè)置了OnItemClickListener,那我這個(gè)按鈕在閉合時(shí),點(diǎn)擊按鈕左側(cè)但還是在這個(gè)View范圍內(nèi)的地方,如下圖紅框內(nèi)
這個(gè)范圍內(nèi)應(yīng)該不處理事件,return false
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: x = (int) event.getX(); y = (int) event.getY(); if (!isOpen && x < getWidth() - 2 * mOuterRadius && y > 0 && y < getHeight()) { //未展開狀態(tài)下,點(diǎn)擊發(fā)布圓左側(cè)的位置,不處理事件 return false; } break; } }
然后在up事件中計(jì)算點(diǎn)擊了發(fā)布按鈕還是展開的item,就是計(jì)算點(diǎn)擊的坐標(biāo)是在圓半徑內(nèi),還是在item矩形范圍內(nèi)。
最后源碼奉上: 詳細(xì)地址
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android?Studio中使用SQLite數(shù)據(jù)庫實(shí)現(xiàn)登錄和注冊(cè)功能
SQLite是一款輕型的數(shù)據(jù)庫,是遵守ACID的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),它包含在一個(gè)相對(duì)小的C庫中,下面這篇文章主要給大家介紹了關(guān)于Android?Studio中使用SQLite數(shù)據(jù)庫實(shí)現(xiàn)登錄和注冊(cè)功能的相關(guān)資料,需要的朋友可以參考下2024-06-06基于Flutter制作一個(gè)長按展示操作項(xiàng)面板的桌面圖標(biāo)
Flutter是一種強(qiáng)大的跨平臺(tái)移動(dòng)應(yīng)用程序框架,它能夠幫助開發(fā)者輕松地創(chuàng)建漂亮、快速、高效的應(yīng)用程序,本文的主題是如何在Flutter中制作一個(gè)長按展示操作項(xiàng)面板的桌面圖標(biāo),在某些場景下,這個(gè)功能會(huì)讓應(yīng)用程序更加便利和易用2023-06-06Android Studio3.5開發(fā)工具(安卓開發(fā)工具)安裝步驟詳解
這篇文章主要為大家詳細(xì)介紹了Android Studio3.5開發(fā)工具安裝、安卓開發(fā)工具的安裝步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09Android Material設(shè)計(jì)中列表和卡片的創(chuàng)建方法解析
這篇文章主要介紹了Android Material設(shè)計(jì)中列表和卡片的創(chuàng)建方法解析,列表和卡片是Material Design視圖中的重要部分,需要的朋友可以參考下2016-04-04DataBinding onClick的七種點(diǎn)擊方式
這篇文章主要給大家介紹了關(guān)于DataBinding onClick的七種點(diǎn)擊方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Android自定義視圖實(shí)現(xiàn)手指移動(dòng)軌跡
這篇文章主要為大家詳細(xì)介紹了Android自定義視圖實(shí)現(xiàn)手指移動(dòng)軌跡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06Android實(shí)現(xiàn)壓縮字符串的方法示例
最近在做Android開發(fā),遇到了需要壓縮字符串的功能,下面這篇文章主要給大家介紹了Android實(shí)現(xiàn)壓縮字符串的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08Android動(dòng)態(tài)替換Application實(shí)現(xiàn)
這篇文章主要介紹了Android動(dòng)態(tài)替換Application實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05