我可以使用重构将一个变量的类型交换为另一个吗?

Can I use refactoring to exchange the type of a variable for another?

Android Studio 提供强大的重构功能,例如重命名。我可以用它来更改变量、字段、参数的名称,但是我似乎找不到重命名类型的方法。例如:

LinearLayout layout = (LinearLayout) v.findViewById(....);
// ........
// A bunch of code using `layout` many times

如何快速将 LinearLayout 重构为 RelativeLayout 并将其应用于其余代码?我可以对字段做同样的事情吗?

简答

您要查找的功能是类型迁移!

A Type Migration 可以通过右键单击变量或字段的类型然后选择 Refactor -> 类型迁移。或者,您可以使用这些键盘快捷键:

  • 在 Mac 上:Shift + + F6
  • 在Windows上:Shift + Ctrl + F6

只需选择要迁移到的类型,单击重构,AndroidStudio 就会开始发挥它的魔力!


更长更详细的答案

您似乎误解了 Rename 的实际作用。

Rename 可用于按字面意义重命名元素。所以你可以用它改变变量、参数、方法或class的名称。例如,如果您有一个名为 Foo 的 class,并且您想将其名称更改为 Bar,您可以使用 Rename 轻松完成。

但是你不能重命名LinearLayout因为它是框架class当然不能修改那些。然而,这根本不应该成为问题,因为您实际上并不想重命名 LinearLayout,是吗?您真正想要做的是将类型从 LinearLayout 更改为 RelativeLayout。还有另一个非常有用的重构功能可以做到这一点,它被称为 Type Migration.

您可以执行类型迁移,方法是右键单击您想要交换其类型的任何变量,然后选择重构 - > 类型迁移。之后会弹出一个对话框,您可以输入要迁移到的类型,在您的例子中为 RelativeLayout。然后只需单击 Refactor,Android Studio 就会开始发挥它的魔力。可能会有一个额外的弹出窗口 window 通知您代码中无法自动迁移的所有内容。只需浏览冲突列表,完成后点击 忽略 并手动修复这些冲突。

这是工作中的类型迁移 的示例。我从这段代码开始:

private LinearLayout mLayout;

private void doStuff(ViewGroup container) {
    LinearLayout layout = (LinearLayout) container.findViewById(0);

    layout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ...
        }
    });

    mLayout = layout;
    fooTheBar(layout);   
}

private void fooTheBar(LinearLayout layout) {
    ...
}

现在我对 doStuff() 中的局部变量 layout 执行了 类型迁移RelativeLayout。结果如下所示:

private RelativeLayout mLayout;

private void doStuff(ViewGroup container) {
    // Here is the only conflict which could not be refactored automatically.
    // I had to change the cast to RelativeLayout manually.
    RelativeLayout layout = (LinearLayout) container.findViewById(R.id.linearLayout);

    layout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ...
        }
    });

    mLayout = layout;
    fooTheBar(layout);
}

private void fooTheBar(RelativeLayout layout) {
    ...
}

如您所见,类型迁移 做得非常出色。 fooTheBar()的字段类型甚至参数类型都改为RelativeLayout。只有一个冲突。 Android Studio 无法自动更改 doStuff() 最顶部的演员类型。我不得不手动修复它。正如我之前提到的,我在执行重构时收到了有关此冲突的警告。

你当然可以问自己为什么它可以自动更改字段和参数的类型但不能更改强制类型转换的类型,但如果你考虑一下这实际上很有意义:

无法自动迁移的部分代码是(LinearLayout) container.findViewById(R.id.linearLayout)。此方法当然会查找 ID 为 R.id.linearLayoutView。这个 View 可以在布局 xml 中定义,也可以在运行时动态添加到 container 但无论如何它都不是可以自动重构而没有风险的东西破坏功能。这是只有开发人员可以决定如何处理的事情,这就是为什么要警告您。

对于 Kotlin 文件中的 Type Migration

假设您想在以下函数中将输入参数从 String 更改为 Int

fun getValue(key: String){
}
  1. 将光标置于您要更改的类型(本例中为字符串)

  2. 右击 > 重构 > 更改 签名。或使用以下快捷方式执行此步骤:

    • Mac: + F6
    • Windows: Ctrl + F6 (未测试)
  3. 完成第 2 步将打开此 window,单击以蓝色突出显示的行:

  1. 将类型替换为您想要的任何内容,然后单击 Refactor