constraintLayout中设置view.setVisibility(View.GONE)不生效问题

1,241 阅读1分钟

某次开发中在xml中使用constraintLayout布局,某个子view设置了android:visiblity="gone",但是在代码跑起来后竟然显示了。

百思不得其解。

猜测肯定是某个地方设置了可见性,查看了一下setVisibility方法,view的可见性是通过设置flag的方式标识的。 于是覆写了该view的setVisibility方法来断点调试。

image.png

在断点来到此处时,查看一下调用链,豁然开朗了。 原来是项目中使用了代码动态调整约束规则,约束规则在应用的时候会改变view的显示规则。

调用栈如下(省略了调试信息中的类型和包名):

image.png

在constraintset的applyToInternal方法中,会遍历子view,然后通过view的visibilityMode属性来设置visible状态。

image.png

applyToInternal方法中对view设置可见性状态代码如下:

image.png

在constraintLayout中,每个子view的mVisibilityMode默认都是VISIBILITY_MODE_NORMAL,而这个值会导致系统在应用约束规则时将view设置为可见状态。 这个也就是为什么设置了gone状态无效的原因。

image.png

知道了原因后,就可以尝试修改属性值来避免该问题。 在constraintset内部提供了setVisibilityMode方法来修改属性值。有两种属性值可选, VISIBILITY_MODE_NORMAL和VISIBILITY_MODE_IGNORE,

image.png

通过如上方法将view的mVisibilityMode设置成VISIBILITY_MODE_IGNORE就可以避免view的visible状态被改变。