无需强制转换findViewById的结果?

时间:2017-07-04 09:52:23

标签: android casting findviewbyid

最近我发现AndroidStudio提醒我删除一些类强制转换。我记得在旧时代,我们必须抛出findViewById的结果,但现在没有必要。

findViewById的结果仍然是View,所以我想知道为什么我们不需要演员?

我找不到提到的任何文件,任何人都可以找到任何文件吗?

6 个答案:

答案 0 :(得分:213)

从API 26开始,findViewById对其返回类型使用推理,因此您不再需要进行强制转换。

旧定义:

View findViewById(int id)

新定义:

<T extends View> T findViewById(int id)

因此,如果您的compileSdk至少为26,则表示您可以使用此功能:)

答案 1 :(得分:12)

根据article

  

以下函数依赖于Java的泛型自动类型推断,以消除手动转换的需要:

protected <T extends View> T findViewById(@IdRes int id) {
    return (T) getRootView().findViewById(id);
}

答案 2 :(得分:11)

旧版本:

AutoCompleteTextView name = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);

来自带有SDK 26的Android Studio 3.0:

AutoCompleteTextView name = findViewById(R.id.autoCompleteTextView);

答案 3 :(得分:1)

如果您使用查看类的常用属性(如可见性)或某些常用方法(如 onClick()

例如:

((ImageView) findViewById(R.id.image_car)).setVisibility(View.VISIBLE);

在这种情况下,你可以简单地写:

findViewById(R.id.image_car).setVisibility(View.VISIBLE);

答案 4 :(得分:0)

Android 0,清理投射

google在IO 2017中宣布的一件事是被称为“ castaway”的东西:)。 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想法特别的一件事是称为意图动作的功能。您所要做的就是按ctrl + shift + A,然后键入clean。然后选择“代码清理”操作,然后选择整个项目范围。通过这些简单的步骤,您的代码将变得更加整洁。

重要的一点是,您可以使用某些代码版本控制系统来执行此操作。这样,您可以比较intent操作所做的更改并还原所需的任何文件。

从原始帖子复制:

https://medium.com/@abangkis/android-0-clean-up-casting-c30acec56cef

答案 5 :(得分:0)

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;
}