自定義View之案列篇(一):鞭炮
老規矩,先來看看類似過年放的鞭炮的效果圖:
block
學習博客也是學習一種變通的思想,能夠舉一反三,才能掌握真正的精髓。
這里留下一個小小的挑戰:
block
怎么獲取菱形區域的點擊事件?歡迎留言,歡迎討論,謝謝。
我臨時的處理方法是以菱形的內切圓來處理點擊事情的。
鞭炮布局(BlockFrameLayout)
分析效果圖,可以看出魔方布局是由一塊塊小的菱形按照某種規律組合而成的,我們這里以繁化簡,先來看看一塊小的菱形:
block
接著看看三塊菱形組成的圖案:
block
看看最后的效果圖:
block
是不是已經發現規律了啊?對的,以三塊菱形為一組,從上往下就組成了最終的圖案。
核心思想:分析前三塊菱形和后三塊菱形的坐標變化。
相信你已經找到了:
if ((i + 1) % 3 == 1) { //第一塊 startX = getWidth() / 2 - mChildSize / 2; startY = mChildSize * bulge; } else if ((i + 1) % 3 == 2) { //第二塊 startX = getWidth() / 2 - mChildSize; startY = mChildSize * bulge + mChildSize / 2; } else if ((i + 1) % 3 == 0) { //第三塊 startX = getWidth() / 2; startY = mChildSize * bulge + mChildSize / 2; bulge++; }
那么 onLayout 方法:
final int childCount = getChildCount(); int startX = 0; int startY = 0; int bulge = 0; for (int i = 0; i < childCount; i++) { View childView = getChildAt(i); if (childView.getVisibility() == GONE) { continue; } if ((i + 1) % 3 == 1) { startX = getWidth() / 2 - mChildSize / 2; startY = mChildSize * bulge; } else if ((i + 1) % 3 == 2) { startX = getWidth() / 2 - mChildSize; startY = mChildSize * bulge + mChildSize / 2; } else if ((i + 1) % 3 == 0) { startX = getWidth() / 2; startY = mChildSize * bulge + mChildSize / 2; bulge++; } childView.layout(startX, startY, startX + mChildSize, startY + mChildSize); }
如果對于自定義 ViewGroup 流程有什么疑問的童鞋,請查看我自定義系類前面的幾篇博客。
菱形(BlockView )
BlockView 類比較簡單,我這里就直接貼出代碼,有什么疑問的請留言,會第一時間給你回復。
package com.github.blockdemo.widget; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * Created by Administrator on 10/17 0017. */ public class BlockView extends View { private Context mContext; private Paint mPaint; private Paint mTextPaint; private Path mPath; private String mText; private Paint.FontMetrics mMetrics; private OnClickListener mOnClickListener; private boolean mClickEnable = true; public BlockView(Context context) { this(context, null); } public BlockView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public BlockView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(Color.parseColor("#3F51B5")); mTextPaint = new Paint(); mTextPaint.setAntiAlias(true); mTextPaint.setStyle(Paint.Style.FILL); mTextPaint.setColor(Color.parseColor("#FFFFFF")); mPath = new Path(); mText = "8"; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPath.reset(); mPath.moveTo(getWidth() / 2, 0); mPath.lineTo(0, getHeight() / 2); mPath.lineTo(getWidth() / 2, getHeight()); mPath.lineTo(getWidth(), getHeight() / 2); mPath.close(); canvas.drawPath(mPath, mPaint); mTextPaint.setTextSize(getWidth() / 4); mMetrics = mTextPaint.getFontMetrics(); mTextPaint.setTextAlign(Paint.Align.CENTER); canvas.drawText(mText, getWidth() / 2, getHeight() / 2 + (mMetrics.bottom - mMetrics.top) / 2 - mMetrics.bottom, mTextPaint); } public void setPaintColor(int... colors) { if (colors != null) mPaint.setColor(colors[0]); } public void setText(String text) { mText = text; } public int dip2px(float dpValue) { final float scale = mContext.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: float x = event.getX(); float y = event.getY(); int centerX = getWidth() / 2; int centerY = getHeight() / 2; //注意下這里以菱形的內切圓來處理點擊事件,如果你有什么好的方案請留言 if ((centerX - x) * (centerX - x) + (centerY - y) * (centerY - y) <= getWidth() * getWidth() / 8) { if (mOnClickListener != null && mClickEnable) { mOnClickListener.BlockOnClickListener(mText); mClickEnable = false; } } break; case MotionEvent.ACTION_UP: mClickEnable = true; break; default: break; } return true; } public interface OnClickListener { void BlockOnClickListener(String text); } public void setBlockOnClickListener(OnClickListener onClickListener) { this.mOnClickListener = onClickListener; } }
本文由用戶 licqi 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!