使用 View.isShown 显示闪烁

using View.isShown shows flickering

为了显示 "New" 图标,我在覆盖 onScroll 方法中编码如下。

public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    if (user.hasNewPost && !imageViewNew.isShown())
        imageViewNew.setVisibility(View.VISIBLE);
    else   
        imageViewNew.setVisibility(View.INVISIBLE);
}

我不太明白为什么用isShown()方法时imageViewNew会闪烁。我删除了 isShown() 方法,它在 onScroll 事件期间提供了稳定的可见性。

我打印了 Log.d(TAG, String.valueOf(imageViewNew.isShown()));,它确实在每个滚动事件中相应地给出了 true/false,如下所示。

07-06 22:47:10.132    6831-6831/com.sample D/TestViewFragment﹕ false
07-06 22:47:10.192    6831-6831/com.sample D/TestViewFragment﹕ true
07-06 22:47:10.242    6831-6831/com.sample D/TestViewFragment﹕ false
07-06 22:47:10.302    6831-6831/com.sample D/TestViewFragment﹕ true

怎么会这样?
请注意,它发生在 2.3.6 到 5.0.1 之间,因此可能是与设备无关的问题。

下面的代码是 android.view.

中的 View.isShown() 方法
public boolean isShown() {
    View current = this;
    //noinspection ConstantConditions
    do {
        if ((current.mViewFlags & VISIBILITY_MASK) != VISIBLE) {
            return false;
        }
        ViewParent parent = current.mParent;
        if (parent == null) {
            return false; // We are not attached to the view root
        }
        if (!(parent instanceof View)) {
            return true;
        }
        current = (View) parent;
    } while (current != null);

    return false;
}

我无法检查哪一行 returns false 因为我的 Android Studio 没有在源上应用断点。

"I hardly understand why imageViewNew is flickering when I use isShown() method"

onScroll方法连续被调用了好几次,我们来看看处理过程"stack":

onScroll -> !isShown == true -> 
              setVisibility(View.VISIBLE); // next call !isShow will be false
onScroll -> !isShown == false -> 
              setVisibility(View.INVISIBLE); // next call !isShow will be true
onScroll -> !isShown == true -> 
              setVisibility(View.VISIBLE); // next call !isShow will be false
onScroll -> !isShown == false -> 
              setVisibility(View.INVISIBLE); // next call !isShow will be true

在每次调用中,您都在更改比较的最终值。闪烁的感觉似乎很合乎逻辑。

也许您想用另一种方法调用此代码,一种不会一次又一次调用多次的方法。