最近我发现AndroidStudio提醒我删除一些类转换。我记得以前我们必须对findViewById的结果进行强制转换,但现在不需要了。
findViewById的结果仍然是View,所以我想知道为什么我们不需要强制转换类?
我找不到任何提到的文件,有人能找到任何文件吗?
从 API 26 开始,
findViewById
对其返回类型使用推理,因此您不再需要进行强制转换。
旧定义:
View findViewById(int id)
新定义:
<T extends View> T findViewById(int id)
所以如果你的
compileSdk
至少是26,这意味着你可以利用这个:)
根据这篇文章:
以下函数依赖于 Java 的泛型自动类型推断,以消除手动转换的需要:
protected <T extends View> T findViewById(@IdRes int id) {
return (T) getRootView().findViewById(id);
}
在旧版本中:
AutoCompleteTextView name = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
来自带有 SDK 26 的 Android Studio 3.0:
AutoCompleteTextView name = findViewById(R.id.autoCompleteTextView);
Android 0,清理铸造
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));
这是一个简单的改变。但对于一个经验丰富的程序员来说,这样干净的代码可以让你非常高兴,并且有助于你的编码心情:)
要执行此操作,您只需在应用程序 build.gradle 中将项目编译的 sdk 版本设置为版本 26。
您仍然可以针对早期的 sdk 版本,因此这是一个非侵入性的更改。
现在真正的问题是,如何清理一直使用强制转换的旧代码。特别是当您有数百个活动文件时。您可以手动完成,也可以聘请实习生来完成 😛。但幸运的是,对于所有这些实习生来说,Android Studio 已经准备好帮助我们解决这个问题。
当您放置插入符号(或单击冗余转换)时,Android Studio 会建议 2 个选项来处理冗余转换。
首先,它会建议删除多余的强制转换,或者您可以选择清理代码。它将删除该文件的所有冗余转换。这更好,但我们想要更多。我们不想打开每个文件并逐一进行清理。
IntelliJ idea 的特殊之处之一是一个称为“意图操作”的功能。您所要做的就是按 ctrl+shift+A,然后输入 clean。并选择代码清理操作,并选择整个项目范围。通过这几个简单的步骤,您的代码将会变得更加干净。
重要的一点是您可以使用某些代码版本控制系统来执行此操作。这样您就可以比较意图操作所做的更改并恢复您想要的任何文件。
从原帖复制:
https://medium.com/@abangkis/android-0-clean-up-casting-c30acec56cef
Android Studio 会提醒您删除强制转换,如果您使用 View 类中的常用属性,例如 visibility 或一些常用方法,例如 onClick()
例如:
((ImageView) findViewById(R.id.image_car)).setVisibility(View.VISIBLE);
在这种情况下你可以简单地写:
findViewById(R.id.image_car).setVisibility(View.VISIBLE);
在
ViewGroup
的源代码中,有一个返回参数的强制转换。所以不需要再投:
@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;
}