ScrollView实例之--侧滑

这个问题也是我看公司项目的时候发现的,之前确实没有看过任何第三方的,也不知道out没,反正写下来吧。
这里写图片描述
公司的一款app实现这样一个侧滑效果,即刚开始,左边占满全屏,右边的button隐藏,当用户向左滑动时,右边的button则显示出来。这个侧滑感觉就是QQ里面的,但我忘记他是怎么实现的了,反正看一看我的吧,觉得蛮不错的。
注:在这里我们只讨论Width,MATCH_PARENT=-1,WRAP_CONTENT=-2;
如果我们只是简单的让child_01为-1,child_02为-2,其实程序会崩掉……你需要在他们的外面再套一层,我们这里套一层LinearLayout.
那么之后的显示是
这里写图片描述
为什么会这样呢?
因为ScrollView是一个特殊的控件,我们看一看他是怎么测量的吧,直接走他父亲(FrameLayout)的测量方法。 FrameLayout走到这一步,measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);HorizontalScrollView重写了这个方法,里面有这么一句

final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
                lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);

它写这么一句的意思是什么呢,其实是说,因为我是ScrollView,我里面可能装了很多东西,他们的宽度可能远远超过了我,所以我不必限定他们的宽度了,他们爱多宽有多宽。
好了,那么现在外层的LinearLayout现在的高度模式是UNSPECIFIED了,他将一直把这个模式给他们子孩子,让他们爱多宽有多宽。
在LinearLayout的onMeasure()方法中,又有这么一段代码

 if (useLargestChild &&
                (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED)) {

大概意思就是,我的宽度此时取决于孩子的宽度。
再看看他的两个孩子吧,都是Button,看看他的onMeasure()方法。如果不是EXACTLY那么正常的显示就是包裹内容的大小。很显然,我们这里Width的模式是父亲给的UNSPECIFIED。所以,最终我们LinearLayout的宽度是他的子孩子的宽度的和。
那么且看这里的一个特殊情况,子孩子的MeasureWidth在什么情况下比父亲大呢?
假设我们在这里把child_01的文字写很多,让他足以超出屏幕,那么最后显示是这样的
这里写图片描述
然后我将他们的宽度都打印了出来
这里写图片描述
从上到下依次是,HorizontalScrollView,LinearLayout,child_01,child_02
所以,在有ScollView的情况下,这种事情是会出现的。但是对于线性布局来说,这是绝对不允许的。
经过上面的分析,我们大致可以知道,如果我们想自定义child_01的宽度,那么肯定要对他进行重新测量。
我们让他的宽度是屏幕的宽度

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(wm.getDefaultDisplay().getWidth(),
                MeasureSpec.EXACTLY);
        super.onMeasure(expandSpec, heightMeasureSpec);
    }

这里写图片描述
这里写图片描述
我这里采用的是320x480的屏幕。
这里面难以理解的就是ScrollView测量时的特殊性,UNSPECIFIED模式的突然出现。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值