<declare-styleable name="GridImageViewGroup"><attr name="childVerticalSpace" format="dimension"/><attr name="childHorizontalSpace" format="dimension"/><attr name="columnNum" format="integer"/> </declare-styleable>GridImageViewGroup.java 代码
public class GridImageViewGroup extends ViewGroup { private int childVerticalSpace = 0; private int childHorizontalSpace = 0; private int columnNum = 3; private int childWidth = 0; private int childHeight = 0; public GridImageViewGroup(Context context, AttributeSet attrs) {super(context, attrs);TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.GridImageViewGroup);if (attributes != null) { childVerticalSpace = attributes.getDimensionPixelSize(R.styleable.GridImageViewGroup_childVerticalSpace, 0); childHorizontalSpace = attributes.getDimensionPixelSize(R.styleable.GridImageViewGroup_childHorizontalSpace, 0); columnNum = attributes.getInt(R.styleable.GridImageViewGroup_columnNum, 3); attributes.recycle();} } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int rw = MeasureSpec.getSize(widthMeasureSpec);int rh = MeasureSpec.getSize(heightMeasureSpec);int childCount = getChildCount();if (childCount > 0) { childWidth = (rw - (columnNum - 1) * childHorizontalSpace) / columnNum; childHeight = childWidth; int vw = rw; if (childCount < columnNum) {vw = childCount * (childHeight + childVerticalSpace); } int rowCount = childCount / columnNum + (childCount % columnNum != 0 ? 1 : 0); int vh = rowCount * childHeight + (rowCount > 0 ? rowCount - 1 : 0) * childVerticalSpace; setMeasuredDimension(vw, vh);} } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {int left = 0;int top = 0;int count = getChildCount();for (int i = 0; i < count; i++) { View child = getChildAt(i); left = (i % columnNum) * (childWidth + childHorizontalSpace); top = (i / columnNum) * (childHeight + childVerticalSpace); child.layout(left, top, left + childWidth, top + childHeight);} }在xml中引用:
<com.whoislcj.animation.GridImageViewGroup android:id="@+id/image_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:animateLayoutChanges="true" lee:childHorizontalSpace="10dp" lee:childVerticalSpace="10dp" lee:columnNum="3"/>在Activity中调用:
private void initViews() {mImageViewGroup = (GridImageViewGroup) findViewById(R.id.image_layout);ImageView imageView = new ImageView(this);imageView.setImageResource(R.mipmap.add_image);imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {addImageView(); }});mImageViewGroup.addView(imageView); } public void addImageView() {final ImageView imageView = new ImageView(MainActivity4.this);imageView.setImageResource(R.mipmap.lottery);imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {mImageViewGroup.removeView(imageView); }});mImageViewGroup.addView(imageView, 0); }实现效果如下:
布局动画产生的背景:
凡事总要问个明白,为何要引入布局动画呢?其实通过上面的实现效果可以看出,在添加和删除图片时都显得很突兀,不知道该用什么语言形容了,总之就是感觉不舒服。其实我平时在开发中调用View.setVisibility()方法时也会有这种感受,这也是布局动画产生的一个背景吧。
布局动画:
布局动画是指ViewGroup在布局时产生的动画效果 。实现布局动画有如下几种方式
第一种方式:在xml中,对ViewGrope设置android:animateLayoutChanges="true"属性:
<com.whoislcj.animation.GridImageViewGroup android:id="@+id/image_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:animateLayoutChanges="true" lee:childHorizontalSpace="10dp" lee:childVerticalSpace="10dp" lee:columnNum="3"/>就这么简单的一句话实现的效果就可以实现了,看看效果如何
这种方式虽然简单但是实现的布局动画比较单一,下面看第二种方式。
第二种方式:LayoutTransition实现
LayoutTransition mLayoutTransition = new LayoutTransition();//设置每个动画持续的时间mLayoutTransition.setStagger(LayoutTransition.CHANGE_APPEARING, 50);mLayoutTransition.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 50);mLayoutTransition.setStagger(LayoutTransition.APPEARING, 50);mLayoutTransition.setStagger(LayoutTransition.DISAPPEARING, 50);PropertyValuesHolder appearingScaleX = PropertyValuesHolder.ofFloat("scaleX", 0.5f, 1.0f);PropertyValuesHolder appearingScaleY = PropertyValuesHolder.ofFloat("scaleY", 0.5f, 1.0f);PropertyValuesHolder appearingAlpha = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);ObjectAnimator mAnimatorAppearing = ObjectAnimator.ofPropertyValuesHolder(this, appearingAlpha, appearingScaleX, appearingScaleY);//为LayoutTransition设置动画及动画类型mLayoutTransition.setAnimator(LayoutTransition.APPEARING, mAnimatorAppearing);PropertyValuesHolder disappearingAlpha = PropertyValuesHolder.ofFloat("alpha", 1f, 0f);PropertyValuesHolder disappearingRotationY = PropertyValuesHolder.ofFloat("rotationY", 0.0f, 90.0f);ObjectAnimator mAnimatorDisappearing = ObjectAnimator.ofPropertyValuesHolder(this, disappearingAlpha, disappearingRotationY);//为LayoutTransition设置动画及动画类型mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, mAnimatorDisappearing);ObjectAnimator mAnimatorChangeDisappearing = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);//为LayoutTransition设置动画及动画类型mLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mAnimatorChangeDisappearing);ObjectAnimator mAnimatorChangeAppearing = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);//为LayoutTransition设置动画及动画类型mLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, mAnimatorChangeAppearing);//为mImageViewGroup设置mLayoutTransition对象mImageViewGroup.setLayoutTransition(mLayoutTransition);上面通过自定义LayoutTransition 修改系统提高的默认动画效果,如果不需要自定义的动画效果的话,不调用mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, mAnimatorDisappearing);就行了。
第三种方式:通过设置LayoutAnimation来实现布局动画
AlphaAnimation alphaAnimation = new AlphaAnimation(0f, 1f);alphaAnimation.setDuration(200);LayoutAnimationController animationController = new LayoutAnimationController(alphaAnimation, 0.5f);animationController.setOrder(LayoutAnimationController.ORDER_NORMAL);mImageViewGroup.setLayoutAnimation(animationController);显示顺序有以下几种:
<?xml version="1.0" encoding="utf-8"?><layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:delay="0.5" android:animationOrder="normal" android:animation="@anim/alpha" />ViewGroup xml添加android:layoutAnimation属性
<com.whoislcj.animation.GridImageViewGroup android:id="@+id/image_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:layoutAnimation="@anim/layoutanimation" lee:childHorizontalSpace="10dp" lee:childVerticalSpace="10dp" lee:columnNum="3"/>由于这种方式采用的是补间动画,个人不再推荐使用这种方式,原因很简单实现的动画效果相对单一。