Android自定義View實現可展開、會呼吸的按鈕

這篇文章主要爲大家詳細介紹了Android自定義View實現可展開、會呼吸的按鈕,具有一定的參考價值,感興趣的小夥伴們可以參考一下

不專門練習的話,自定義View的知識又忘了許多。。正好新項目裏有這個需求,就再練習一下,代碼已上傳:地址

可以修改文本、文字大小、各種顏色:

1、按照國際慣例,就是新建attrs,寫各種需要的屬性,然後獲取,新建各種所需的Paint、Rect,重寫onMeasure計算寬高,重寫onDraw畫圖搞起。。

2、關於可展開效果,其實就是點擊發布時,啓動一個ValueAnimator,對一個圓角矩形的左邊距離不斷改變:

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、關於呼吸效果,就是一個對外圓圈半徑改變的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、關於文字位置居中計算,以前我用一個Rect,用

paint.getTextBounds(text, 0, text.length(), mTextRect);
int textWidth = mTextRect.width();
int textHeight = mTextRect.height();

這樣計算不準確,可能是因爲返回的寬高是int值,應該用FontMetrics類來計算,大家可以搜一下:

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的處理,因爲這個控件不是一直都是展開狀態,那麼就要求控件在閉合的時候,要不影響該控件下層控件對點擊的處理。比如我這個ExpandableBreathngButton,下層是一個RecyclerView,並設置了OnItemClickListener,那我這個按鈕在閉合時,點擊按鈕左側但還是在這個View範圍內的地方,如下圖紅框內

這個範圍內應該不處理事件,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()) {
    //未展開狀態下,點擊發布圓左側的位置,不處理事件
    return false;
   }
   break;
 }
}

然後在up事件中計算點擊了發佈按鈕還是展開的item,就是計算點擊的座標是在圓半徑內,還是在item矩形範圍內。

最後源碼奉上: 詳細地址

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章