如何一次添加多个按钮监听器?

时间:2013-07-21 17:09:35

标签: java android xml

向下滚动我的回答。问题并不重要,代码只是令人困惑。

是否有一个允许我获取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;
}

但是,如果有一种方法可以迭代遍历android:id项目列表到BottomFragment()我甚至不需要第一个代码块,它将消除我输入的ID的手动列表英寸

2 个答案:

答案 0 :(得分:0)

这是一个粗略的逻辑草图(在C#中)......它基本上在布局上做了一个自上而下的传递,构建了一个可以在之后循环的id到视图。有一般的方法可以做到这一点,因此必须与布局文件一起维护(两者都需要一起修改)。

假设您想在托管片段的活动的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);
       }  
   }

}

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

答案 1 :(得分: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);