Android: a findViewById() method that returns values we don't need to cast

笑着哭i 提交于 2019-12-06 08:05:17

问题


As I'm tired of writing a cast operator for EVERY Activity.findViewById() that returns raw View, I finally tried one way that was suggested by Internet.

public abstract class MyActivity extends Activity {

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

Note this isn't overloaded (the last "D" is upper case). The compiler says we can't cast View into T. Is there anything wrong with my implementing? Strangely, this suggestion was hardly seen in English websites (e.g. even in our lovely Stack Overflow), and the exception was the site posted above.


回答1:


This works fine in my test project. No compiler error:




回答2:


To be honest, this approach adds some subtle complexity overhead for the next Android maintainer (who would be used to the casting approach) to save a few characters in the code files.

I would propose to cast the Views in the traditional way, or opt for a reflection-based solution like Roboguice.




回答3:


I solved this by using a custom eclipse-builder that generates classes with references for each layout-file, because:

  • It's typesafe and easy to use
  • RoboGuice and all other reflection-based APIs are very slow on Android.

In my opinion this is the cleanest and most performant way of solving this problem.

See my gist here for the builder: https://gist.github.com/fab1an/10533872

Layout: 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>

usage: 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();
    }
}

generated file (in 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);
    }


}


来源:https://stackoverflow.com/questions/11433722/android-a-findviewbyid-method-that-returns-values-we-dont-need-to-cast

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!