您的位置:首页 > 其它

ScrollView嵌套GridView冲突解析

2016-03-04 13:52 288 查看
最近项目开发中,用到了ScrollView中嵌套GridView的情况,但是这两个View都是带有滚动的,当把其中一个嵌套到另一个里面的时候(例如我将GridView嵌套到ScrollView里面),就会出现冲突了,表现为GirdView显示不全。

解决方法也比较简单,只需要我们重新定义GridView,即自定义一个GridView,重写里面的onMeasure()方法:

public class MyGridView extends GridView {

public MyGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyGridView(Context context) {
super(context);
}

public MyGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}


在这里重写了onMeasure()方法,目的是为了使GridView不会出现滚动,这个方法也适用于和ListView的嵌套。剩下的就基本上没什么变化了,在布局文件中使用自定义的GridView就可以了,这里就不在粘代码了。

OnMeasure()方法解析:

在自定义View的时候,我们是如何将一个View成功的画在了所指定的位置的呢?看看Android关于View的源码,就会发现,onMeasure()、onLayout()、onDraw()这三个方法来确定View的外观,即onMeasure()方法决定了该View本身的大小、而子View在ViewGroup中的位置由onLayout()方法来确定,至于剩下的绘制View,就交给onDraw()方法了,这个方法我们还是相对比较熟悉的,毕竟初学者自定义View的时候,基本都只是重写onDraw()方法,在里面绘制内容。

这里我截取了一段TextView.java中的onMeasure()的源码:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);

int width;
int height;

...

if (widthMode == MeasureSpec.EXACTLY) {
// Parent has told us how big to be. So be it.
width = widthSize;
} else {
if (mLayout != null && mEllipsize == null) {
des = desired(mLayout);
}

...

setMeasuredDimension(width, height);


关于里面的具体绘制我在这里就不详细的去解释了,涉及的内容比较复杂,如果不是专门去研究深层的我们只要知道怎么做就行了。

widthMeasureSpec,heightMeasureSpec这两个参数其实是有该View的父View传过来的,而子View的这两个值由父View和他们本身的一些属性来决定,如父View的layout_width,layout_height和padding以及子View本身的layout_margin共同决定。

通过这两参数来获取specMode和specSize,完事之后调用最后一行的setMeasuredDimension()来绘制,传入的参数才是真正决定View视图大小的值。

我们知道在父View中,给子View分配的空间大小并不是确定的,有可能随着具体的变化而变化,而这个变化的条件就是传到specMode中决定的,specMode一共有三种可能:

MeasureSpec.EXACTLY:父视图希望子视图的大小应该是specSize中指定的。

MeasureSpec.AT_MOST:子视图的大小最多是specSize中指定的值,也就是说不建议子视图的大小超过specSize中给定的值。

MeasureSpec.UNSPECIFIED:我们可以随意指定视图的大小。

这些值与具体的xml布局中的那些宽高设置是怎么对应的,我也没有去仔细研究,后面给出两个链接大家可以参考看一下,其实说白了也就是重新定义了父View能够给你子View的大小重新定义了一下,不再由父View的默认方法去定义,以达到我们想要的效果。

/article/7665470.html //关于重写onMeasure()方法的

/article/9205737.html // 关于MeasureSpec介绍
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: