2012-07-11 62 views
3

因爲我厭倦了爲每個Activity.findViewById()編寫一個演員操作符,它返回原始的View,我終於試了one way that was suggested by InternetAndroid:一個findViewById()方法,返回我們不需要投的值

public abstract class MyActivity extends Activity { 

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

此未過載(最後一個 「d」 是大寫)。編譯器說我們不能將View轉換成T。我的實施有什麼問題嗎?奇怪的是,這個建議很難在英文網站上看到(例如,甚至在我們可愛的堆棧溢出中),並且上面發佈的網站例外。

+0

什麼是您的JDK和Android版本? – 2012-07-11 13:40:38

+0

Mine是Android 2.2和JDK 1.6。 – Quv 2012-07-11 13:51:56

回答

4

這在我的測試項目中正常工作。沒有編譯器錯誤: screenshot

+0

什麼是您的JDK和Android版本? – 2012-07-11 13:40:47

+0

即將發佈相同的東西 - @Quv是否仍在項目中的其他地方使用Activity.findViewById()?也許使用更明顯的方法名來區分兩者... – seanhodges 2012-07-11 13:41:39

+0

JDK 1.6.0_30,Android Target API-16 – chrulri 2012-07-11 13:46:12

2

說實話,這種做法增加了一些微妙的複雜性開銷在未來的Android維護者(誰被用來鑄造方法)來保存一些字符的代碼文件。

我會建議以傳統方式投射視圖,或選擇基於反射的解決方案,如Roboguice

+0

謝謝。在我的小項目後面只有一個人,維護者是我,但你的介紹看起來很有趣。 – Quv 2012-07-11 14:41:39

0

我解決了這個使用一個自定義的Eclipse的生成器,爲每個佈局文件引用生成的類,因爲:

  • 它是類型安全和易於使用的
  • 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(); 
    } 
} 

生成的文件(以):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); 
    } 


} 
相關問題