0

Scroll down for my answer. The question doesn't really matter and the code is just confusing.

Is there a function that will allow me to fetch the id labels so I can loop a button listener easily? Currently I have in my main "container" xml that houses fragments this line of code:

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);
}

and then one of my fragments will pick up the RMAP, and cross that with the labels I have specified. I'm doing this because I have a few buttons and specifying a huge list of listeners seemed inefficient, then I got sidetracked on this code.

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;
}

However if there was a way to iterate through the list of android:id items specifically to BottomFragment() I wouldn't have to even need the first block of code and it would eliminate the manual list of ID's I've typed in.

4

2 回答 2

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);
于 2013-07-23T03:12:08.137 回答
0

这是一个粗略的逻辑草图(在 C# 中)......它基本上对布局进行了一次自上而下的传递,构建了一个 id-to-view 映射,之后可以循环遍历。有已知的通用方法可以做到这一点,因此必须与布局文件一起维护(两者都需要一起修改)。

假设您想在托管您的片段的活动的 OnCreate 中执行此操作(也可能在片段 OnMeasure 或 OnLayout 覆盖中完成)

假设您的片段的布局文件具有以下结构


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);
       }  
   }

}

这可能不是最好的方法,但它应该有效。

于 2013-07-21T18:57:51.017 回答