写在前面的几句话
上面一篇介绍了下简单的堆叠式布局,但是实现上相对来说还是比较简单,而且效果也并没有特别好,那么这一篇呢,就对堆叠式布局进行更加深入的讲解,主要是通过对子控件的测量和布局,通过这篇的讲解,大家应该可以实现出各种不同风格的堆叠式的布局
首先看一下最终实现的效果
图1 稍复杂的堆叠式布局
是不是看起来酷炫了很多,没错,揍是这么炫酷,
那其实简单分析一下是怎么实现的,
从静态到动态,首先将第一个初始的界面实现出来
Snip20160412_2.png
通过这张图,我们可以看出来其实是5个item堆叠起来的,随着item的position越往后,那么他的宽和高会有一定的变化,最后一个item的透明度和其他4个的透明度不相同。
第一步呢就是修改之前的attachChildViews方法里面的添加子View个数的限制,修改为<5
由于在子View绘制之前需要将子View的相关宽高和位置进行修改,所以在重写onMeasure与onLayout的方法以满足我们的需要
Step1.重写onMeasure方法
首先通过onMeasure方法来看看,对宽高的修改
通过截图我们可以分析一下在onMeasure中究竟需要做一些什么?
父布局的高度需要调整
子View的宽度需要调整
父布局的高度的调整
上代码通过代码分析
private int itemsMarginTop = dp2px(8);
//获取父控件的高度
private int calculateWrapContentHeight(){
int maxChildHeight = 0;
for (int index = 0; index < getChildCount(); index++){
final View childView = getChildAt(index);
measureChildView(childView);
if (childView.getVisibility() != View.GONE){
maxChildHeight = Math.max(childView.getMeasuredHeight(),maxChildHeight);
}
}
int itemsElevationPadding = itemsMarginTop * getViewsCount();
int measuredHeight = maxChildHeight + getPaddingTop() + getPaddingBottom() + itemsElevationPadding;
return measuredHeight;
}
//
private int getViewsCount() {
return (getChildCount() - 1);
}
通过代码来看呢,主要是先遍历子View寻找出item高度最大的一个,虽然我使用的item高度都是一致的,但是也不排除会有高度不一致的需求,然后把这个子View最大的高度加上getPaddingTop()与getPaddingBottom(),最后加上每个item之间间隔的高度就好了,这样父控件的高度就计算出来了。
子View的宽度的调整
上代码通过代码分析
//测量子View的宽高
private void configureChildViewsMeasureSpecs(int widthMeasureSpec){
int childWidthMeasureSpec;
int childHeightMeasureSpec;
final int parentWidth = MeasureSpec.getSize(widthMeasureSpec)
- getPaddingLeft()
- getPaddingRight();
int viewWidth;
int viewHeight;
for (int index = getViewsCount(); index >= 0; index--){
final View childView = getChildAt(index);
measureChildView(childView);
viewWidth = caculateViewWidth(parentWidth, index);
viewHeight = childView.getMeasuredHeight();
childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY);
childHeightM