2013-07-21 46 views
0

向下滾動我的答案。這個問題並不重要,代碼只是令人困惑。如何一次添加多個按鈕監聽器?

是否有一個函數可以讓我獲取id標籤,以便我可以輕鬆地循環按鈕偵聽器?目前,我有我的主「容器」的xml,裏面片段這行代碼:

public static final Map<String, Integer> RMAP = createMapR(); 
// Map of widget id's in R 

private static Map<String, Integer> createMapR() { 
    Map<String, Integer> result = new HashMap<String, Integer>(); 
    for (Field f : R.id.class.getDeclaredFields()) { 
     String key = f.getName(); 
     Integer value = 0; 
     try { 
      value = f.getInt(f); 
     } 
     catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
     } 
     catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
     result.put(key, value); 
    } 
    return Collections.unmodifiableMap(result); 
} 

,然後我的碎片將拿起RMAP和交叉與我指定的標籤之一。我這樣做是因爲我有幾個按鈕,並且指定了一大堆聽衆似乎效率低下,然後我就偏離了這個代碼。

public class BottomFragment extends Fragment { 
private final String[] LABELS = {"button_do_1", "button_woah_2", "button_foo_1", 
           "button_hi_2"}; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.bottom_fragment, container, false); 
    for (String item : LABELS) { 
      if (Container.RMAP.containsKey(item)) { 
      ((Button) v.findViewById(Container.RMAP.get(item))) 
       .setOnClickListener(this); 
     } 
    } 
    return v; 
} 

然而,如果有一種方法,通過機器人的列表進行迭代:ID項目專門BottomFragment()我也不會,甚至需要的一個代碼塊,它會消除ID的的手動列表我已經輸入了。

+0

上面的代碼工作。但是,如果我能夠獲得該特定片段的ID列表,我可以在一個很好的循環中添加onClick監聽器,而不是超過15行setOnCLickListener(this)。現在我正在使用兩個列表。一個自動填充,其中包含每個R.id()變量。在我的情況下,它大多是按鈕和其他一些小部件。 – Steven

+0

如果該類型的函數不存在或者可以用來獲取該視圖的窗口小部件ID的函數的組合,那麼很好,上面的代碼工作,它只是不是自動的,因爲我有LABELS鍵入ID的手動。 – Steven

+1

你應該使用SparseArray來實現這種功能:https://developer.android.com/reference/android/util/SparseArray.html – hwrdprkns

回答

0

我想通了。解決方案位於ViewGroup的子項中。此代碼爲該特定視圖中的每個按鈕添加偵聽器。在這種情況下,視圖是僅有按鈕的片段。只要有很多按鈕,並且您想要爲每個按鈕添加一個偵聽器,此代碼都非常方便。

public static void addButtonListeners(View v, OnClickListener clickListener) 
{ 
    ViewGroup widgets = (ViewGroup) v; 
    for(int i = 0; i < widgets.getChildCount(); ++i) 
    { 
     View child = widgets.getChildAt(i); 
     if (child instanceof Button) 
     { 
      Button nextButton = (Button) child; 
      nextButton.setOnClickListener(clickListener); 
     } 
    } 
} 

您需要將視圖和偵聽器傳遞給此函數。聽衆可以通過只是通過「this」,即:

addButtonListeners(v, this); 
0

下面是一個粗略的邏輯草圖(用C#)......它基本上在佈局上做了一個單獨的自上而下的傳遞,構建了一個可以循環遍歷的id-to-view地圖。有一種通用的方法可以做到這一點,因此必須與佈局文件一起維護(兩者都需要一起修改)。

說你想這樣做,在承載您的片段(S)(它可能在片段OnMeasure完成或OnLayout覆蓋過)

假設你的片段佈局文件中的活動的OnCreate中有如下結構


LinearLayout 

    TextView 
    TextView 

    RelativeLayout 

     EditText 
     EditText 

    TextView 

public override OnCreate() 
{ 
    Map<int, view> idLabels = new Map<int, view>(); 

    View v = fragment.View; 

    LinearLayout ll = (LinearLayout) v; 
    idLabels.Add(ll.Id, ll) 

    TextView tv1 = (TextView) ll.GetChildAt(0); 
    idLabels.Add(tv1.Id, tv1) 

    TextView tv2 = (TextView) ll.GetChildAt(1); 
    idLabels.Add(tv2.Id, tv2) 

    RelativeLayout rl = (RelativeLayout) ll.GetChildAt(2); 
    idLabels.Add(rl.Id, rl) 

    // notice the numbers being passed to GetChildAt, its a traversal of Views and Viewgroups ! 

    EditText et1 = (EditText) rl.GetChildAt(0); 
    idLabels.Add(et1.Id, et1) 

    EditText et2 = (EditText) rl.GetChildAt(1); 
    idLabels.Add(et2.Id, et2) 

    // now, go back "up" to top-most, linear layout viewgroup and get remaining views, if any 

    TextView tv3 = (TextView) ll.GetChildAt(3); 
    idLabels.Add(tv3.Id, tv3) 

    ... 

    foreach(int id in idLabels) 
    { 
     if(id == R.id.myViewIdLabel) // your R file will have all your id's in the literal form. 
     { 
      View v = idLabels.Map(id); 
      v.SetOnClickListener(this); 
     } 
    } 

} 

這可能不是最好的辦法,但它應該工作。