什么更好,android.R还是自定义R?

14

当我开始开发安卓应用程序时,我有一个习惯,在需要的地方(特别是在布局文件中)定义自定义R值。例如:

findViewById(R.id.customerName).setText(customer.getName())

有布局:

<TextView android:text="TextView" android:id="@id/customerName"
    android:layout_height="wrap_content" android:layout_width="fill_parent" />

现在我意识到,使用android.R可能会更好。

findViewById(android.R.id.text1).setText(customer.getName())

具有布局:

<TextView android:text="TextView" android:id="@android:id/text1"
    android:layout_height="wrap_content" android:layout_width="fill_parent" />

你遵循哪种实践?每种实践的优缺点是什么?


自定义工具...我认为最好使用自己的东西,而不是本地操作系统。你无法以任何方式控制它。 - gonxa87
1
我不理解那个。当我使用自定义标识符时,我会获得什么样的控制? - rds
android:id="@android:id/customerName" - 这样写是否正确?因为 customerName 似乎是在 Android SDK 的顶层定义的 ID,但实际上并不是;你可能想说的是 android:id="@+id/customerName" 吧? - Paul
1
@Paul。完全正确。复制/粘贴错误。 - rds
4个回答

17

android.R 用于利用操作系统内置的资源。

操作系统中有许多图像/布局等资源,您可以使用android.R来引用它们。

如果您引用自己创建的资源,则大多数情况下使用R。并且在大多数情况下,我建议尽量避免使用内置资源,因为它们会随版本更改。


1
如果您要使用ListActivity,那么您自己创建的布局必须定义@android:id/list。这与“始终为您自己的资源使用R.”相矛盾。 - rds
1
此外,我不相信框架资源会因版本而改变。那会导致一切都崩溃。 - rds
实际上,它们确实会改变,例如内置的动画进度指示器,在每个主要版本发布时都会在视觉上进行更改... - jondavidjohn

1

自定义。系统提供的ID存在一个风险,即在代码中引用项目中不存在的资源。只有存在相应资源(drawable、view、layout等),才存在自定义ID。


然而,如果您的自定义资源(例如R.id.customerName)在项目中定义在不同的布局中,则findViewById()将完全失败。我想您并不希望仅仅因为编译通过就拥有一个可工作的应用程序。这是代码和XML分离固有的问题。或者我错过了什么? - rds
嗯,项目的基本正确性仍然是必需的 :) 我从未说过使用自定义ID会保护您免受所有可能的错误。只是从一种特定类别的错误中 - 当您尝试加载android.R.layout.foo时,它并不存在。此外,jondavidjohn关于系统提供的资源(不仅仅是ID)的说法也是正确的。 - Seva Alekseyev
你在项目中重复使用一个资源,还是只为布局定义一个资源?例如,如果你有两个布局——主屏幕(Main Screen)客户详细信息(Customer Details),你会在两个布局中都定义@+id/CustomerNameTextView,还是会定义@+id/mainScreenCustomerNameTV@+id/customerDetailsCustomerNameTV - rds
你是指布局上视图的ID吗?有时候我会这么做。但那些仍然是我的自定义ID。为什么呢? - Seva Alekseyev
因为如果你在多个布局中重复使用@+id/CustomerNameTextView,就会遇到与使用android.R.id.text相同的问题:findViewById()可能会抛出找不到视图的异常。 - rds
我从未说过使用自定义ID将保护您免受所有可能的错误。 - Seva Alekseyev

0

在布局中,使用框架标识符和自定义标识符没有太大的优劣之分。

使用框架标识符的优点:

  • 避免创建更多的标识符。可以节省apk中的一个字段(而且有apk大小限制)。
  • 在某些情况下必须使用,比如ListActivity

使用框架标识符的缺点:

  • 不能提供描述性名称。

在这两种做法中:

  • 代码将来仍然可用。
  • 在运行时发现缺失的引用,并在编译时隐藏。

我以为SDK中的示例会帮助我做出决定,但事实并非如此。记事本和LunarLander应用程序使用android.R.id作为视图标识符,而ApiDemos项目使用自定义标识符。

GestureBuilder最佳实践是混合使用这两种方法吗?(@+id/addButton@android:id/empty)

在我看来,HelloActivity 和 JetBoy 的做法更糟糕,它们定义了 @+id/text @+id/Button01... 这不够描述性,可以用 (@andoid:id/button1) 或者 (@+id/startButton) 来替代。

-1

你需要自己的R.java类,因为它包含了对所有资源(布局、图片、字符串等)的引用。

如果你想要获取id为“myView”的视图的引用,你可以使用R.id.myView。 如果你想要获取内置的Android资源的引用,你可以使用android.R.id.text

请查看以下页面:

http://developer.android.com/guide/topics/resources/accessing-resources.html


我已经完成了我的问题,因为你没有抓住重点。 - rds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接