Pre-Honeycomb (Android 3), each Activity was registered to handle button clicks via the onClick
tag in a Layout\'s XML:
android:onClick=\"m
I've recently solved this issue without having to add a method to the context Activity or having to implement OnClickListener. I'm not sure if it is a "valid" solution neither, but it works.
Based on: https://developer.android.com/tools/data-binding/guide.html#binding_events
It can be done with data bindings: Just add your fragment instance as a variable, then you can link any method with onClick.
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.testapp.fragments.CustomFragment">
<data>
<variable android:name="fragment" android:type="com.example.testapp.fragments.CustomFragment"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_place_black_24dp"
android:onClick="@{() -> fragment.buttonClicked()}"/>
</LinearLayout>
</layout>
And the fragment linking code would be...
public class CustomFragment extends Fragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_person_profile, container, false);
FragmentCustomBinding binding = DataBindingUtil.bind(view);
binding.setFragment(this);
return view;
}
...
}
I'd like to add to Adjorn Linkz's answer.
If you need multiple handlers, you could just use lambda references
void onViewCreated(View view, Bundle savedInstanceState)
{
view.setOnClickListener(this::handler);
}
void handler(View v)
{
...
}
The trick here is that handler
method's signature matches View.OnClickListener.onClick
signature. This way, you won't need the View.OnClickListener
interface.
Also, you won't need any switch statements.
Sadly, this method is only limited to interfaces that require a single method, or a lambda.
Your Activity is receiving the callback as must have used:
mViewPagerCloth.setOnClickListener((YourActivityName)getActivity());
If you want your fragment to receive callback then do this:
mViewPagerCloth.setOnClickListener(this);
and implement onClickListener
interface on Fragment
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
}
}
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);
}
});
If you register in xml using android:Onclick="", callback will be given to the respected Activity under whose context your fragment belongs to (getActivity() ). If such method not found in the Activity, then system will throw an exception.