来个效果图吧先~
哎╮(╯▽╰)╭本月的开发项目终于在月底的时候拿到了接口,所以赶紧用迅雷掩耳不及盗铃之响叮当之势撸完了那个从Eclipse中导入的古董级项目.今天早上看到了个效果,感觉还挺有意思的,照着撸了一下,记录总结一下实现过程吧
Github地址 https://github.com/fushuangdage/CustomView
其实也没啥,这个动画效果是RecyclerView 自带的,之前一直用notifyDateSetChange(),一直没有发现,其实recyclerview很好心的自带了插入动画,调用notifyItemInserted()插入即可 自己写的也就两个部分,第一自定义Drawable ,类似自定义view吧,将图片化成六边形.第二,通过自定义LayoutManager实现按照六边形位置摆放1~7个子控件(原文是可以添加很多圈的,我就简单写写了)
package com.example.admin.customview.hive; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; /** * Created by fushuang on 2017/8/23. */ public class HiveDrawable extends Drawable { private Bitmap mBitmap; private Paint paint; private Path path; private Rect rect; public HiveDrawable(Bitmap bitmap) { init(); if (bitmap!=null){ BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); paint.setShader(shader); } } @Override public int getIntrinsicHeight() { if (mBitmap!=null){ return mBitmap.getHeight(); }else { return super.getIntrinsicHeight(); } } @Override public int getIntrinsicWidth() { if (mBitmap!=null){ return mBitmap.getWidth(); }else { return super.getIntrinsicWidth(); } } @Override public void setBounds(int left, int top, int right, int bottom) { super.setBounds(left, top, right, bottom); rect = new Rect(); rect.set(left,top,right,bottom); int l = rect.width() / 2; //考虑横向的情况 int h = rect.height(); double v = Math.sqrt(3) / 2; path.reset(); path.moveTo(left,h/2); path.lineTo(left+l/2, (float) (h/2-v*l)); path.lineTo(right-l/2, (float) (h/2-v*l)); path.lineTo(right,h/2); path.lineTo(right-l/2, (float) (h/2+v*l)); path.lineTo(left+l/2, (float) (h/2+v*l)); path.moveTo(left,h/2); path.close(); } private void init() { if (paint==null){ paint = new Paint(); paint.setAntiAlias(true); paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(3f); } if (path==null){ path = new Path(); } } @Override public void draw(@NonNull Canvas canvas) { canvas.drawPath(path,paint); } @Override public void setAlpha(@IntRange(from = 0, to = 255) int alpha) { if (paint!=null){ paint.setAlpha(alpha); } } @Override public void setColorFilter(@Nullable ColorFilter colorFilter) { if (paint!=null) paint.setColorFilter(colorFilter); } @Override public int getOpacity() { return 0; } }自定义LayouManager
package com.example.admin.customview.hive; import android.graphics.RectF; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; /** * Created by fushuang on 2017/8/25. */ public class HiveLayoutManager extends RecyclerView.LayoutManager { private List<List<RectF>> positionList=new ArrayList(); @Override public RecyclerView.LayoutParams generateDefaultLayoutParams() { return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); } @Override public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { detachAndScrapAttachedViews(recycler); // removeAllViews(); int childCount = state.getItemCount(); View first = recycler.getViewForPosition(0); measureChildWithMargins(first,0,0); int left = (getWidth() - getDecoratedMeasuredWidth(first)) / 2; int right=(getWidth() + getDecoratedMeasuredWidth(first)) / 2; int top=(getHeight()-getDecoratedMeasuredHeight(first))/2; int bottom=(getHeight()+getDecoratedMeasuredHeight(first))/2; //数学计算 每一层的最后一个都为 n*n*3+3*n+1 addView(first); layoutDecoratedWithMargins(first,left,top,right,bottom); int num=childCount>7?7:childCount; int cX = getWidth() / 2; int cY = getHeight() / 2; for (int i = 1; i <num; i++) { View view = recycler.getViewForPosition(i); addView(view); measureChildWithMargins(view,0,0); int height = getDecoratedMeasuredHeight(view); int width = getDecoratedMeasuredWidth(view); double cos = Math.cos(Math.PI /3* (i - 1)); double sin = Math.sin(Math.PI /3 *(i - 1)); double viewCY = getHeight()/2-height * cos; double viewCX = getWidth()/ 2 - height * sin; layoutDecoratedWithMargins(view, ((int) (viewCX - width / 2)), ((int) (viewCY - height / 2)) ,((int) (viewCX + width / 2)), ((int) (viewCY + height / 2))); } } }