2015-04-25 103 views
0

的後裔,我有以下佈局設置(我省略了不相關的標籤):分配唯一的ID包含佈局

main.xml: 
<include 
    android:id="@+id/test1" 
    layout="@layout/mylayout" 
    /> 

<include 
    android:id="@+id/test2" 
    layout="@layout/mylayout" 
    /> 

mylayout.xml: 
<LinearLayout 
    <EditText 
     android:id="@+id/myedittext" 
    /> 
</LinearLayout> 

注意,這個特殊的例子是關鍵過於簡單,我的實際mylayout.xml是複雜的,包含很多sublayouts和子視圖與很多id和我會真的不喜歡把它內聯到main.xml

因此,我想重複使用多次佈局mylayout.xml。您可能會注意到這兩個EditText會有重複的ID。這似乎不成問題,因爲我只在活動初始​​化時使用R.id.myedittext來查找test1test2佈局作爲findViewById的根,之後我通過View對象直接訪問這些EditText。我覺得Butterknife這個很方便,代碼如下:當我試圖改變屏幕的方向

class LayoutHolder { 
    @InjectView(R.id.myedittext) 
    EditText editText; 
    // ... 
    static LayoutHolder create(View root) { 
     LayoutHolder holder = new LayoutHolder(); 
     ButterKnife.inject(holder, root); 
     return holder; 
    } 
} 

的問題出現了:既EditTexts恢復相同的狀態,由於這些非唯一ID。好吧,我想,我只需要在values目錄中定義一些ID,然後在EditTexts上使用View.setId方法。但是,這種方法存在一些問題:特別是,我將不得不手動設置這些ID並以編程方式爲ID爲mylayout.xml以內的每個視圖進行設置。更重要的是,即使我這樣做,我也不能以統一的方式訪問這些子視圖,因爲它們都有不同的ID(特別是,我不能做這些漂亮的Butterknife注射)。

我已經想出瞭解決這個問題的其他方法,但它們更加複雜和醜陋。那麼,是否有一些很好的通用方法可以滿足我的需求?我不知道我無法在網上找到任何東西,因爲重複使用佈局以避免代碼重複(實際上是xml重複,但無論如何)似乎是非常自然的事情。

回答

0

我一直在使用我在開源項目中找到的這段代碼。

public class Utils { 

    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1); 
    /** 
    * Generate a value suitable for use in setId(int}. 
    * This value will not collide with ID values generated at build time by aapt for R.id. 
    * 
    * @return a generated ID value 
    */ 
    private static int generateViewId() { 
     for (; ;) { 
      final int result = sNextGeneratedId.get(); 
      // aapt-generated IDs have the high byte nonzero; clamp to the range under that. 
      int newValue = result + 1; 
      if (newValue > 0x00FFFFFF) { 
       newValue = 1; // Roll over to 1, not 0. 
      } 
      if (sNextGeneratedId.compareAndSet(result, newValue)) { 
       return result; 
      } 
     } 
    } 

    @SuppressLint("NewApi") 
    public static int generateId() { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { 

      return generateViewId(); 
     } 
     else { 

      return View.generateViewId(); 
     } 
    } 
} 
0

各地butterknife補丁,因此它將支持兩個ID這樣

@InjectView(R.id.mylayout, R.id.myedittext)