3

由于我厌倦了为Activity.findViewById()返回 raw的 EVERY 编写转换运算符View,我终于尝试了 Internet 建议的一种方法

public abstract class MyActivity extends Activity {

    @SuppressWarnings("unchecked")
    protected <T extends View> T findViewByID(int id) {
        return (T) this.findViewById(id);
    }
}

请注意,这没有重载(最后一个“D”是大写的)。编译器说我们不能View转换成T. 我的实施有什么问题吗?奇怪的是,这个建议在英文网站上几乎没有出现(例如,甚至在我们可爱的 Stack Overflow 中),但上面发布的网站是个例外。

4

3 回答 3

4

这在我的测试项目中运行良好。没有编译器错误: 截屏

于 2012-07-11T13:38:52.680 回答
2

老实说,这种方法为下一个 Android 维护者(他们将习惯于转换方法)增加了一些微妙的复杂性开销,以便在代码文件中保存一些字符。

我建议以传统方式投射视图,或者选择像Roboguice这样的基于反射的解决方案。

于 2012-07-11T13:54:48.500 回答
0

我通过使用自定义 eclipse-builder 解决了这个问题,该构建器为每个布局文件生成带有引用的类,因为:

  • 它是类型安全且易于使用的
  • RoboGuice 和所有其他基于反射的 API 在 Android 上都非常慢。

在我看来,这是解决这个问题的最干净和最有效的方法。

在这里查看我的构建器要点:https ://gist.github.com/fab1an/10533872

布局:test.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >

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

    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/text1" />

    <ScrollView
        android:id="@+id/scroll"
        android:layout_width="match_parent"
        android:layout_height="350px"
        android:layout_below="@id/text2"
        android:layout_marginTop="50px" />

</merge>

用法:TestView.java

public final class TestView extends RelativeLayout {

    //~ Constructors ---------------------------------------------------------------------------------------------------
    private final ViewRef_test v;

    public TestView(final Context context) {
        super(context);

        LayoutInflater.from(context).inflate(R.layout.test, this, true);
        this.v = ViewRef_test.create(this);

        this.v.text1.setText();
        this.v.scroll.doSomething();
    }
}

生成的文件(在gen/):ViewRef_test.java

package org.somecompany.somepackage;

import android.view.*;
import android.widget.*;
import java.lang.String;


@SuppressWarnings("unused")
public final class ViewRef_test {

    public final TextView text1;
    public final TextView text2;
    public final ScrollView scroll;


    private ViewRef_test(View root) {
        this.text1 = (TextView) root.findViewById(R.id.text1);
        this.text2 = (TextView) root.findViewById(R.id.text2);
        this.scroll = (ScrollView) root.findViewById(R.id.scroll);
    }

    public static ViewRef_test create(View root) {
        return new ViewRef_test(root);
    }


}
于 2014-04-12T12:50:46.950 回答