在Android中如何检查一个视图是否可见?

215

我在Android上使用以下方式将visibility设置为不可见:

myImageView.setVisibility(View.INVISIBLE);

然后使它可见:

myImageView.setVisibility(View.VISIBLE);

现在我不知道myImageView是否可见,如何像这样检查它:

现在我不确定myImageView是否可见,如何进行检查:

if (myImageView IS VISIBLE) {
    Do something
} else {
    Do something else
}

我该怎么做?在括号里要写什么?

4个回答

526

虽然View.getVisibility()可以获得视图的可见性,但它不是一个简单的真/假值。视图的可见性可以设置为以下三种之一:

View.VISIBLE 视图可见。

View.INVISIBLE 视图不可见,但它通常占用的任何间距仍将被使用。它是“不可见”的。

View.GONE 视图已经消失了,你看不到它,也不会占据“位置”。

因此,要回答你的问题,你需要查找:

if (myImageView.getVisibility() == View.VISIBLE) {
    // Its visible
} else {
    // Either gone or invisible
}

5
有些情况下虽然它不在可见屏幕之内,仍然可以被显示出来,因此它可能不总是准确的。然而,Bill Mote 的答案总是有效的。 - ForceMagic
1
ForceMagic是正确的,这也是我发布答案的原因。一个View可以被设置为View.VISIBLE,你的if逻辑会返回true,但是,该视图可能实际上对用户不可见。我的解决方案将在屏幕视口上实际看到View的任何部分时返回true。 - Bill Mote
@BillMote 我的解决方案是解决原始问题。如何获取可见性属性的值。 - William
@William 谢谢您先生 - Gowthaman M
简短明了,完美回答。 - Raj Bedi

140

或者您可以简单地使用

View.isShown()

7
这样更准确,因为它检查视图是否在显示列表中,因为视图可能是“可见的”,但没有父级。 - user123321
4
尽管它不在可见屏幕的范围内也可能是正确的,因此在某些情况下可能不准确。然而,Bill Mote的答案始终有效。 - ForceMagic
View#isShown() 遍历所有父视图的可见性以验证其是否显示在屏幕上。这个过程有时可能会很昂贵。 - Ian Wong
我认为这应该是被接受的答案。 - Stanley Ko

71
如果图像是布局的一部分,那么它可能是"View.VISIBLE",但这并不意味着它在可见屏幕范围内。如果你想要的是这样,这将起作用:
Rect scrollBounds = new Rect();
scrollView.getHitRect(scrollBounds);
if (imageView.getLocalVisibleRect(scrollBounds)) {
    // imageView is within the visible window
} else {
    // imageView is not within the visible window
}

你介意解释一下这个为什么有效吗?我看了View.getLocalVisibleRect的源代码,但不确定它是如何工作的。 - yarian
1
这里有两件事情。1)View.getHitRect(scrollBounds) 获取其父级坐标系中的命中矩形,并将其填充到scrollBounds中;2)我们使用scrollBounds初始化ImageView的View.getLocalVisibleRect(scrollBounds)。如果ImageView在scrollBounds的边界内,则该方法返回true。 - Bill Mote
1
好的,我的错误在于没有明确说明。混淆点确切是 imageView.getLocalVisibleRect(scrollBounds) 的调用。从 grepcode: public final boolean getLocalVisibleRect(Rect r) { Point offset = new Point(); if (getGlobalVisibleRect(r, offset)) { r.offset(-offset.x, -offset.y); // make r local return true; } return false; } - yarian
它没有考虑ScrollView的填充! - Ali
1
这个(getLocalVisibleRect)看起来很有前途,但我们能否改用getGlobalVisibleRect()呢?如果不行,为什么?谢谢。 - Henry
scrollView.getHitRect(scrollBounds) is not doing anything, the rect is overwritten when getLocalVisibleRect calls getGlobalVisibleRect - hmac

3
你会使用相应的方法getVisibility()。以'get'和'set'为前缀的方法名是Java表示属性的惯例。一些语言有实际的语言结构来表示属性,但Java不是其中之一。因此,当你看到标记为'setX'的东西时,你可以99%确定有一个相应的'getX'将告诉你该值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接