异常:java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams

今天在使用LayoutParams时出现了一个问题,我是这样用的:

在gridview初始化的时候,为gridview添加了一个header(我用的是第三方GridView是可以添加header的):

headerView = new View(getActivity());
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, (int)300); 
headerView.setLayoutParams(params);     
mGridView.addHeaderView(headerView);

然后当程序执行到某处,我希望通过setLayoutParams来改变这个高度,于是我这样做:

LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, 500); 
headerView.setLayoutParams(params);

重点是,两个LayoutParams 都是ViewGroup的LayoutParams ,然后一执行就出现下列错误:

java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams

跟android中的很多异常一样,你去仔细推敲异常本来的含义往往是百思不得其姐的,异常说的是两个是不同类型的LayoutParams ,但明明都是ViewGroup的LayoutParams。而且我确定ViewGroup的LayoutParams用在GridView的header上是可以的,因为我不执行上面的第二段代码不会报错(再次强调我用的是第三方GridView是可以添加header的)。

然后就在stackoverflow上查找答案,虽然没找到满意的,但是有个人的回答倒是点醒了我,是不是第二段代码中又重新创建了一个LayoutParams的关系?于是我将第二段代码改成:

LayoutParams params = headerView.getLayoutParams();
params.height = 500;

其实就是不去新建一个LayoutParams,而是从原来的View中直接获取LayoutParams

改完运行结果没有出现异常了。

看来,当一个View已经有了LayoutParams,是不能再次添加一个新创建的LayoutParams的。

最后,这只是我结合实际情况的理解,并不确保我的分析正确,不过按照我的理解的的确确解决了问题。