【问题标题】:Can someone explain to me the magic behind FindViewById(1) or FindViewById(2)?有人可以向我解释 FindViewById(1) 或 FindViewById(2) 背后的魔力吗?
【发布时间】:2014-09-17 06:11:47
【问题描述】:

[更新] -- 只是想向大家确认,我同意使用硬编码数字总是一个坏主意。我的好奇是在使用 Maps API 时枚举的 1、2 常量值是什么。如果我找到像 R.id.my_current_location_view 这样的东西,我会感觉更舒服。

我看到这个问题和其他问题中散布着代码。人们怎么知道使用 findViewById(1) 等?与 findViewById(R.id.something);

Change position of Google Maps API's "My location" button

这个问题似乎有些深奥的困惑。我想知道 findViewById(1) 的神奇数字是什么。如果单击链接,您会看到没有人向 mapView 提供 setId(1) 值,但不知何故人们知道检查父视图然后 findViewById( 1) 和 findViewById(2)..

我也在那里问了这个问题,所以上下文不会丢失,但似乎没有人能解释这一点。

【问题讨论】:

  • 显然这是一个神奇的数字。 ID 来自层次结构查看器。如果 google 决定在 google play 服务中更改他们的 id,那么那里有此代码的人也必须更改它,但我已经看到了这么多地方..

标签: android


【解决方案1】:

视图 ID 只是正的非零整数。

如果您使用@+id/name 语法在XML 中设置了视图ID,则整数在R.java 中生成,您需要在代码中将其称为R.id.name

如果您在代码中使用 setId(value) 设置了视图 ID,则可以使用 findViewById(value) 从层次结构中检索具有该 ID 的视图,其中 id 值可以是硬编码的正非零整数,例如1 或 2。

一般在编写代码时,尽量避免使用这样的幻数常量。

【讨论】:

  • 正确,所以幻数.. 只是一个幻数.. 我有时会在代码中看到这一点,所以它只是人们正在做的不好的做法。他们必须知道 id 1 是什么。
【解决方案2】:

将这种方法与硬编码的 id 一起使用是个坏主意,特别是如果您不是设置它们的人,因为它们可能会发生变化。

但是,要回答问题以确定要使用的 id,一种选择是使用 Android Studio 调试器手动遍历视图层次结构进行大量猜测和检查工作。这可能会花费大量时间,因此更简单的方法是使用 Android Studio 和 Eclipse 中都提供的Hierarchy Viewer

这是我们感兴趣的布局部分的样子。我裁剪了完整的布局以显示相关部分。

我们现在可以分解以下代码:

View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);
  1. findViewById(1) 将返回 LinearLayout(红色轮廓),因为它的 id 是 1。
  2. getParent() 将返回 RelativeLayout,它是 LinearLayout(蓝色轮廓)的父级。
  3. findViewById(2) 将找到具有给定 id 的 RelativeLayout 的子 View。根据图片,我们看到我们想要的 ImageView(绿色轮廓)具有该 id。

基于此有趣的是,我们可以直接使用mapView.findViewById(2) 来直接访问ImageView 并避免其他调用。

不确定在以前的版本中是否是这种情况,但在使用当前的MapFragment 时它可以工作。如果它不适用于以前的版本,那么这有助于证明这是一种不好的做法,因为它可能会在不同版本之间发生变化。

【讨论】:

    【解决方案3】:

    它们都是相同的,在第一种情况下,您提供的是 android 自己在 R 文件中构建的资源标识符,而在第二种情况下,您提供的是 android 为您编译的资源标识符。

    没什么区别,

    【讨论】:

    • 在我提供的链接的情况下 findViewById(1) 是 MyLocationButton id。开发人员如何知道使用它与 R.id.MyLocationButtonIdIfItExists..
    • 如果您在运行时创建了一个视图,而不是通过 XML,那么您可能会提供相同的 ID,例如 setID(1),然后您可以使用 findViewById(1) 来取回相同的.在您发布的链接中,我猜 lib 会在运行时使用自定义 ID 创建小部件。
    【解决方案4】:

    您必须先使用setId(value) 设置视图id,然后您可以使用findViewById(value) 使用id 检索视图

    找到这个帖子看看:Link

    Documentation 代表setid()说:

    设置此视图的标识符。标识符在此视图的层次结构中不必是唯一的。标识符应该是一个正数。

    【讨论】:

      猜你喜欢
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      • 2012-04-09
      • 2021-02-18
      • 2015-07-30
      • 2023-02-08
      • 2011-01-08
      相关资源
      最近更新 更多