How to handle button clicks using the XML onClick within Fragments

Pre-Honeycomb (Android 3), each Activity was registered to handle button clicks via the onClick tag in a Layout's XML:

android:onClick="myClickMethod"

Within that method you can use view.getId() and a switch statement to do the button logic.

With the introduction of Honeycomb I'm breaking these Activities into Fragments which can be reused inside many different Activities. Most of the behavior of the buttons is Activity independent, and I would like the code to reside inside the Fragments file without using the old (pre 1.6) method of registering the OnClickListener for each button.

final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        // Perform action on click
    }
});

The problem is that when my layout's are inflated it is still the hosting Activity that is receiving the button clicks, not the individual Fragments. Is there a good approach to either

  • Register the fragment to receive the button clicks?
  • Pass the click events from the Activity to the fragment they belong to?

  • You could just do this:

    Activity:

    Fragment someFragment;    
    
    //...onCreate etc instantiating your fragments
    
    public void myClickMethod(View v) {
        someFragment.myClickMethod(v);
    }
    

    Fragment:

    public void myClickMethod(View v) {
        switch(v.getId()) {
            // Just like you were doing
        }
    }    
    

    In response to @Ameen who wanted less coupling so Fragments are reuseable

    Interface:

    public interface XmlClickable {
        void myClickMethod(View v);
    }
    

    Activity:

    XmlClickable someFragment;    
    
    //...onCreate, etc. instantiating your fragments casting to your interface.
    
    public void myClickMethod(View v) {
        someFragment.myClickMethod(v);
    }
    

    Fragment:

    public class SomeFragment implements XmlClickable {
    
    //...onCreateView, etc.
    
    @Override
    public void myClickMethod(View v) {
        switch(v.getId()){
            // Just like you were doing
        }
    }    
    

    I prefer using the following solution for handling onClick events. This works for Activity and Fragments as well.

    public class StartFragment extends Fragment implements OnClickListener{
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
    
            View v = inflater.inflate(R.layout.fragment_start, container, false);
    
            Button b = (Button) v.findViewById(R.id.StartButton);
            b.setOnClickListener(this);
            return v;
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.StartButton:
    
                ...
    
                break;
            }
        }
    }
    

    The problem I think is that the view is still the activity, not the fragment. The fragments doesn't have any independent view of its own and is attached to the parent activities view. Thats why the event ends up in the Activity, not the fragment. Its unfortunate, but I think you will need some code to make this work.

    What I've been doing during conversions is simply adding a click listener that calls the old event handler.

    for instance:

    final Button loginButton = (Button) view.findViewById(R.id.loginButton);
    loginButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(final View v) {
            onLoginClicked(v);
        }
    });
    
    链接地址: http://www.djcxy.com/p/24156.html

    上一篇: Android:强制EditText删除焦点?

    下一篇: 如何使用Fragments中的XML onClick处理按钮点击