拥有自定义视图可确定自己的可见性

时间:2013-02-21 22:07:20

标签: android android-custom-view

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

是否有一个特定的方法作为普通View生命周期/渲染过程的一部分被调用,这是理想的覆盖,我会称之为setVisibilty()?由于我已经致电invalidate(),因此覆盖它以致电setVisibility()有效。但这是理想的地方吗?似乎在View中设置invalidate()的属性会违反最佳做法。

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

1 个答案:

答案 0 :(得分:0)

没有这样的通用方法,只是因为View的任何方法都不能涵盖重新计算其可见性的所有可能情况(只需考虑异步事件改变您的可见性,例如改变状态网络操作;甚至是简单的计时器关闭)。

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

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

话虽如此,我确实没有看到在设置可见性后调用invalidate()的意义 - 它由平台自动完成。我建议简单地说:

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

并将invalidate()的来电更改为invalidateVisibility()。如果您确实需要出于某种原因致电invalidate() - 请取消注释。这可能是最有效的解决方案。

修改

我的回答是在撰写本文时提出一些与你所描述的逻辑似乎一致的东西(至少对我而言)。我假设你在invalidate()方法中进行了一些重要的处理,所以你需要调用它。但是,你的问题在我看了一段时间后,在阅读了4到5次之后,我想我终于意识到你究竟在问什么! :)

如果我理解正确,那么每当invalidate()的可见性发生变化时,您已经致电View由于,为了简单起见,您希望将视图可见性的修改合并到失效过程中。

如果是这样,那么你是对的 - 在invalidate()中做第一件事就完全可以了。这就是我在invalidateVisibility()

中完全按照该顺序调用的原因
  • View变得可见时,其父级会收到有关需要重新绘制和调用invalidate()的通知,之后只需“与前一个分组”(这是因为所有待处理的绘制操作都在一批)。
  • View变为不可见时,它会自动发出信号以表示无效。对invalidate()的另一次调用只是一个无操作。

然后有直觉 - 这个:

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

似乎不是可疑代码。实际上,这就是你的invalidate()会变成什么样的。但是,验证可见性的计算是一种快速操作,因为Android平台每秒可以调用{em>多次invalidate()。这主要是UI动画时的情况 - 例如在捏合手势期间更新视图的边界。

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