1

我想创建一个View具有显示逻辑的自定义来确定其自身的可见性。为了保持该逻辑包含并易于重用,我创建了一个View子类,覆盖getVisibility()并计划使View可能导致其可见性改变的事件发生时无效......只是发现 aView的可见性只能是通过调用setVisibility()而不是覆盖来更改getVisibility()。请参阅 Romain Guy对此问题的回答。

是否有一个特定的方法作为正常View生命周期/渲染过程的一部分被调用,这将是理想的覆盖,我会在其中调用setVisibilty()?由于我已经调用invalidate(),覆盖它调用setVisibility()工作。但那是理想的地方吗?似乎设置 aView的属性invalidate()会违反最佳实践。

澄清: Andr 指出有很多事情可能会导致 customView的可见性发生变化,并且这些场景非常具体地用于自定义视图的使用。这是非常真实的。但这个问题不是关于如何触发外观刷新 -invalidate()似乎是告诉 Android View 的外观发生变化的标准方式,不是吗?相反,这是一个关于自定义失效后在哪里调用的最佳实践问题。我不想在流程的错误部分进行更改,例如。如果有人有链接,我很想看看Android的UI渲染过程图。setVisibility()ViewonMeasure()

4

1 回答 1

0

没有这样一个通用的方法,仅仅是因为没有一种方法View可以涵盖所有可能需要重新计算其可见性的情况(想想异步事件会改变你的可见性,例如网络操作状态的改变;甚至是一个简单的计时器将关闭)。

作为开发人员,您知道在哪些情况下应该使可见性无效,并且您应该在这些点上相应地修改可见性。当然,可以始终在每次布局和绘图之前设置可见性,但是:

  • 我怀疑它不会涵盖所有情况。
  • 一两个月后理解起来可能会很奇怪。
  • 这是一种矫枉过正 - 它是您正在处理的移动设备,您应该牢记其局限性并以效率为目标。

话虽如此,我真的不明白invalidate()在设置可见性后调用的意义——它是由平台自动完成的。我会简单地建议:

private void invalidateVisibility() {
    // calculate visibility
    setVisibility(calculation_outcome);
    //invalidate();
}

并将呼叫更改invalidate()invalidateVisibility()invalidate()如果您出于某种原因确实需要拨打电话- 只需取消注释通话即可。这可能是最有效的解决方案。

编辑:

我的回答的重点是提出一些与您所描述的逻辑在撰写本文时似乎(至少对我而言)一样普遍的东西。我假设您在该invalidate()方法中正在进行一些关键处理,因此您需要调用它。但是,您的问题困扰了我一段时间,在阅读了 4 或 5 次之后,我想我终于意识到您到底在问什么!:)

如果我对您的理解正确,那么每次您的可见性可能发生变化时,您就已经在打电话了。因此,为了简单起见,您希望将视图可见性的修改合并到失效过程中。invalidate()View

如果是这种情况,那么您是对的 - 作为第一件事,这样做invalidate()是完全可以的。这就是为什么我将电话完全按照以下顺序排列invalidateVisibility()

  • 当 aView变得可见时,它的父级会收到有关需要重新绘制的通知,然后调用invalidate()应该简单地“与前一个组合”(这是因为所有待处理的绘制操作都在一批中处理)。
  • 当 aView变得不可见时,它会自动向自己发出无效信号。另一个调用invalidate()将只是一个无操作。

然后是直觉——这个:

button.setVisible(false/true);
button.invalidate();

似乎不是可疑代码。实际上,这就是您的invalidate()意愿。但是,请验证可见性的计算是一个快速操作,因为invalidate()可能会被 Android 平台每秒调用多次这主要是在 UI 动画时的情况 - 例如在捏合手势期间更新视图的边界。

希望以任何方式有所帮助:)

于 2013-02-22T00:02:37.537 回答