【问题标题】:Get Actual Height of View获取实际视图高度
【发布时间】:2020-03-08 08:05:26
【问题描述】:

简单的问题,也许是令人沮丧的复杂但希望是简单的答案?

获取大小设置为 FILL_PARENT 的元素的实际高度的“最佳实践”是什么?

【问题讨论】:

  • 这可能是这个 SO 问题的副本:stackoverflow.com/questions/2864331/…
  • 谢谢 - 我的搜索 fu 已经出发去度假了。我将首先尝试下面的答案,但有选择是很好的。

标签: android size android-layout


【解决方案1】:

肯定比看起来更复杂。与建议问题中的答案相比,我发现的一种更简单的方法是使用 ViewTreeObserver。在您的 onCreate() 方法中,您可以使用如下代码:

TextView textView = (TextView)findViewById(R.id.my_textview);
ViewTreeObserver observer = textView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //in here, place the code that requires you to know the dimensions.
        //this will be called as the layout is finished, prior to displaying.
    }
});

【讨论】:

  • 为我工作 - 谢谢。唯一需要注意的是,您需要注意您已经参加过一次活动(或仅在需要时参加)这一事实 - 否则,您将陷入无休止的布局循环。
  • 你能解释一下你的意思吗?我不太明白。不会只在 onCreate() 或 onResume() 期间调用一次吗?
  • (抱歉耽搁了 - 圣诞假期)不 - 您正在创建一个事件处理程序,所以它会在布局更改时被调用。如果您没有显示“我已进行必要的布局更改”的标志,它将在您进行更改时再次调用它,并在进行更改后再次调用它,并且...
  • 因此,如果您实际上修改了布局中的某些内容,那么您只会陷入循环,然后呢?所以你可以让 onGlobalLayout 修改另一个变量,然后只删除 OnGlobalLayoutListener ? (有趣的说明:在 ViewTreeObserver 文档中,remove 的方法似乎被错误地命名为 removeGlobalOnLayoutListener 而不是 removeOnGlobalLayoutListener。)
  • 哦,等等,我刚刚意识到您可能在 API 16 之前编写了这个。好吧现在这两种方法都存在!我猜他们注意到 API 和文档之间的差异,并认为 API 是错误的!
【解决方案2】:

如果您需要对视图中多个组件的尺寸执行任何操作,只需对上述答案进行额外修改。当布局完成时,每个视图都会调用布局侦听器。这在根视图组件之前是递归的(即子元素生成布局事件,然后父元素生成其布局事件)。这意味着您可以简单地挂钩根视图组件的布局事件,以便在任何视图的布局更改时得到通知。

ViewTreeObserver observer = this.findViewById(android.R.id.content).getViewTreeObserver();

现在您可以期望您的所有视图都将在 onGlobalLayout 中设置宽度和高度值,因为它们都执行了布局。这显然比为需要公开其实际尺寸的每个视图创建多个侦听器更可取(当然,除非您绝对必须拥有哪个视图生成事件的范围,这通常不是必需的)。

【讨论】:

  • 另外,请确保您没有测量处于 visibility="gone" 状态的元素的尺寸。或者您可能会发现递归“不起作用”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 2011-08-09
  • 1970-01-01
相关资源
最近更新 更多