【问题标题】:Handle a view visibility change without overriding the view处理视图可见性更改而不覆盖视图
【发布时间】:2015-12-23 00:22:33
【问题描述】:

有没有办法在不覆盖视图的情况下处理视图可见性更改(例如,从 GONE 到 VISIBLE)?

类似View.setOnVisibilityChangeListener();?

【问题讨论】:

  • 我不确定,但我想说没有这样的事情,因为它会在整个系统上投入大量工作来永久跟踪所有视图的可见性时间,以便通知可能的侦听器。

标签: android


【解决方案1】:

您可以使用GlobalLayoutListener 来确定视图可见性是否有任何变化。

myView.setTag(myView.getVisibility());
myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int newVis = myView.getVisibility();
        if((int)myView.getTag() != newVis)
        {
            myView.setTag(myView.getVisibility());
            //visibility has changed
        }
    }
});

【讨论】:

  • 这有效,但它仅适用于布局更改,分别用于从 GONE 到 VISIBLE 的更改,反之亦然,因为 INVISIBLE 不会触发布局更改。我说的对吗?
  • @ToBe 在这一行 myView.setTag(myView.getVisibility());您可以设置之后想要处理的任何内容
【解决方案2】:

您可以使用装饰来代替子类化:

class WatchedView {

    static class Listener {
        void onVisibilityChanged(int visibility);
    }

    private View v;
    private Listener listener;

    WatchedView(View v) {
        this.v = v;
    }

    void setListener(Listener l) {
        this.listener = l;
    }

    public setVisibility(int visibility) {
        v.setVisibility(visibility);
        if(listener != null) {
            listener.onVisibilityChanged(visibility);
        }
    }

}

然后

 WatchedView v = new WatchedView(findViewById(R.id.myview));
 v.setListener(this);

【讨论】:

  • 这就像为视图创建一个辅助类。在我看来,覆盖视图会比这更好。但是,这是可行的,假设每次都使用特定的setVisibility()
  • @Nicolas Tyler Submitter 明确表示“不覆盖视图”,因此您的陈述“覆盖视图会更好”是错误的。此外,覆盖视图将导致大量的 xml 更改。一般来说,您的评论毫无意义
  • 它不是假的,它只是不是 OP 要求的。 OP 正在寻找能见度变化的监听器。最好不要覆盖视图。
  • 这个解决方案似乎更好。它适合所有视图。
  • 会更喜欢使用第一次提交,因为此解决方案会强制您每次创建视图时都需要对其进行子类化。
【解决方案3】:

看看ViewTreeObserver.OnGlobalLayoutListener。如文档中所述,当全局布局状态或视图树中视图的可见性发生变化时,将调用其回调方法onGlobalLayout()。因此,您可以尝试使用它来检测视图可见性何时发生变化。

【讨论】:

    【解决方案4】:

    如果有人需要,Kotlin 似乎要容易得多。如果您需要跟踪来自 from 的不可见,则使用与接受的答案类似的方法也可以工作(设置标签),但我将其用于 GONE -> VISIBLE -> GONE

    binding.myView.viewTreeObserver.addOnGlobalLayoutListener {
        when (binding.myView.visibility) {
            View.VISIBLE -> {
                
            }
            View.GONE -> {
                
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      • 2015-04-17
      • 2016-09-18
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多