不需要强制转换 findViewById 的结果?
No need to cast the result of findViewById?
最近我发现AndroidStudio 提醒我删除一些class cast。记得以前findViewById的结果要强制转换,现在不用了
findViewById的结果还是View,所以我想知道为什么我们不需要强制转换class?
我找不到任何提到的文件,谁能找到任何文件?
从 API 26 开始,findViewById
为其 return 类型使用推理,因此您不再需要强制转换。
旧定义:
View findViewById(int id)
新定义:
<T extends View> T findViewById(int id)
因此,如果您的 compileSdk
至少为 26,则意味着您可以利用它 :)
Android Studio 提醒删除转换,如果您使用 View class 中的常见属性,例如 visibility 或一些常用方法,例如 onClick()
例如:
((ImageView) findViewById(R.id.image_car)).setVisibility(View.VISIBLE);
在这种情况下你可以简单地写:
findViewById(R.id.image_car).setVisibility(View.VISIBLE);
在旧版本中:
AutoCompleteTextView name = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
来自 Android Studio 3.0 with SDK 26:
AutoCompleteTextView name = findViewById(R.id.autoCompleteTextView);
据此article:
The following function relies on Java’s generics automatic type inference in order to eliminate a need for manual casting:
protected <T extends View> T findViewById(@IdRes int id) {
return (T) getRootView().findViewById(id);
}
Android0,清理铸造
google 在 IO 2017 中宣布的其中一件事是所谓的“抛弃”:)。 Android 开发人员不必为 findViewById() 进行手动转换。例如,使用 findViewById() 获取文本视图的旧方法是这样的。
TextView txtDesc = (TextView) findViewById(R.id.textViewDesc);
txtDesc.setText(getString(R.string.info_angkot_description));
虽然新方法是这样的
TextView txtDesc = findViewById(R.id.textViewDesc);
txtDesc.setText(getString(R.string.info_angkot_description));
这是一个简单的改变。但对于一个经验丰富的程序员来说,像这样干净的代码会让你非常开心,它有助于你的编码心情:)
为了能够做到这一点,您只需要在您的应用程序中将项目编译的 sdk 版本设置为版本 26 build.gradle。
您仍然可以针对早期的 sdk 版本,因此这是一个非侵入性的更改。
现在真正的问题是,如何清理一直使用转换的旧代码。尤其是当您有数百个 activity 文件时。您可以手动完成,也可以聘请实习生来完成。但对所有这些实习生来说幸运的是,android 工作室已经准备好帮助我们了。
当您放置插入符(或单击冗余转换)时android工作室将建议 2 个选项来处理冗余转换。
首先,它会建议删除多余的转换,或者您可以 select 清理代码。它将删除该文件的所有冗余转换。这更好,但我们想要更多。我们不想打开每个文件并一个一个地清理。
IntelliJ idea 的特别之处之一是称为意图操作的功能。您所要做的就是按 ctrl+shift+A,然后键入 clean。 select 代码清理操作,select 整个项目范围。通过这几个简单的步骤,您的代码将变得更加清晰。
重要的一点是您使用一些代码版本控制系统来执行此操作。这样您就可以比较 intent 操作所做的更改并恢复您想要的任何文件。
复制自原文post:
https://medium.com/@abangkis/android-0-clean-up-casting-c30acec56cef
在ViewGroup
的源代码中,有一个return参数的转换。所以就不用再投了:
@Nullable
public final <T extends View> T findViewById(@IdRes int id) {
if (id == NO_ID) {
return null;
}
return findViewTraversal(id);
}
@Override
protected <T extends View> T findViewTraversal(@IdRes int id) {
if (id == mID) {
return (T) this; //###### cast to T
}
final View[] where = mChildren;
final int len = mChildrenCount;
for (int i = 0; i < len; i++) {
View v = where[i];
if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
v = v.findViewById(id);
if (v != null) {
return (T) v; //###### cast to T
}
}
}
return null;
}
最近我发现AndroidStudio 提醒我删除一些class cast。记得以前findViewById的结果要强制转换,现在不用了
findViewById的结果还是View,所以我想知道为什么我们不需要强制转换class?
我找不到任何提到的文件,谁能找到任何文件?
从 API 26 开始,findViewById
为其 return 类型使用推理,因此您不再需要强制转换。
旧定义:
View findViewById(int id)
新定义:
<T extends View> T findViewById(int id)
因此,如果您的 compileSdk
至少为 26,则意味着您可以利用它 :)
Android Studio 提醒删除转换,如果您使用 View class 中的常见属性,例如 visibility 或一些常用方法,例如 onClick()
例如:
((ImageView) findViewById(R.id.image_car)).setVisibility(View.VISIBLE);
在这种情况下你可以简单地写:
findViewById(R.id.image_car).setVisibility(View.VISIBLE);
在旧版本中:
AutoCompleteTextView name = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
来自 Android Studio 3.0 with SDK 26:
AutoCompleteTextView name = findViewById(R.id.autoCompleteTextView);
据此article:
The following function relies on Java’s generics automatic type inference in order to eliminate a need for manual casting:
protected <T extends View> T findViewById(@IdRes int id) {
return (T) getRootView().findViewById(id);
}
Android0,清理铸造
google 在 IO 2017 中宣布的其中一件事是所谓的“抛弃”:)。 Android 开发人员不必为 findViewById() 进行手动转换。例如,使用 findViewById() 获取文本视图的旧方法是这样的。
TextView txtDesc = (TextView) findViewById(R.id.textViewDesc);
txtDesc.setText(getString(R.string.info_angkot_description));
虽然新方法是这样的
TextView txtDesc = findViewById(R.id.textViewDesc);
txtDesc.setText(getString(R.string.info_angkot_description));
这是一个简单的改变。但对于一个经验丰富的程序员来说,像这样干净的代码会让你非常开心,它有助于你的编码心情:)
为了能够做到这一点,您只需要在您的应用程序中将项目编译的 sdk 版本设置为版本 26 build.gradle。
您仍然可以针对早期的 sdk 版本,因此这是一个非侵入性的更改。
现在真正的问题是,如何清理一直使用转换的旧代码。尤其是当您有数百个 activity 文件时。您可以手动完成,也可以聘请实习生来完成。但对所有这些实习生来说幸运的是,android 工作室已经准备好帮助我们了。
当您放置插入符(或单击冗余转换)时android工作室将建议 2 个选项来处理冗余转换。
首先,它会建议删除多余的转换,或者您可以 select 清理代码。它将删除该文件的所有冗余转换。这更好,但我们想要更多。我们不想打开每个文件并一个一个地清理。
IntelliJ idea 的特别之处之一是称为意图操作的功能。您所要做的就是按 ctrl+shift+A,然后键入 clean。 select 代码清理操作,select 整个项目范围。通过这几个简单的步骤,您的代码将变得更加清晰。
重要的一点是您使用一些代码版本控制系统来执行此操作。这样您就可以比较 intent 操作所做的更改并恢复您想要的任何文件。
复制自原文post:
https://medium.com/@abangkis/android-0-clean-up-casting-c30acec56cef
在ViewGroup
的源代码中,有一个return参数的转换。所以就不用再投了:
@Nullable
public final <T extends View> T findViewById(@IdRes int id) {
if (id == NO_ID) {
return null;
}
return findViewTraversal(id);
}
@Override
protected <T extends View> T findViewTraversal(@IdRes int id) {
if (id == mID) {
return (T) this; //###### cast to T
}
final View[] where = mChildren;
final int len = mChildrenCount;
for (int i = 0; i < len; i++) {
View v = where[i];
if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
v = v.findViewById(id);
if (v != null) {
return (T) v; //###### cast to T
}
}
}
return null;
}