Android Studio fragment - onButtonPressed method
Fragments get attached to activity, the onFragmentInteraction
is a call back method that your activity use to interact with the fragment
For example, the following activity implements the interface from your fragment
public static class YourActivity extends Activity
implements YourFragment.onFragmentInteraction{
...
public void onFragmentInteraction(Uri uri) {
// Do something with uri
}
}
But as the TODO
suggest
// TODO: Rename method, update argument and hook method into UI event
Feel free to adapt it to your need or delete it if not needed. example:
mYourButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (mListener != null) {
mListener.onFragmentInteraction(Uri.parse("http://www.google.com"));
}
}
});
I found the other answers to be a touch vague as a noob myself. Meda points out that the fragment is attached to the activity, the docs state it is more of an extention to it. Personally I feel it's more proper to state that the FRAGMENT
instance encapsulates an ACTIVITY
instance.
Let's consider the code for each component; that is the INTERFACE
, ACTIVITY
, FRAGMENT
and finally the LAYOUT
.
Note : I'm using Kotlin so there is a chance some of this is getting rewired in the background when it is transpiled into Java, though this seems unlikely.
Interface
Names the
CALLBACK
specifying it's signature.interface ConcessionSelection { fun selectConcession(view : View) }
Note : I've moved the interface into it's own class, so the activity is declared as
class ACTIVITY : AppCompatActivity(), INTERFACE
instead ofclass ACTIVITY : AppCompatActivity(), FRAGMENT.INTERFACE
Activity
Provides the logic for the
CALLBACK
.class ACTIVITY : AppCompatActivity(), INTERFACE { ... override fun CALLBACK (view: View) { Log.i("ACTIVITY:CALLBACK","Activity Callback") } ... }
Fragment
Makes provision for a listener and attaches or detaches such instances during the execution of the application.
class FRAGMENT : Fragment() { private var listener: ACTIVITY? = null ... override fun onAttach(context: Context) { super.onAttach(context) if (context is ACTIVITY) { listener = context } else { throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener") } } override fun onDetach() { super.onDetach() listener = null } ... }
Layout
Specifies the
CALLBACK
<...> ... <Button android:id="@+id/button" android:text="Button" android:onClick="CALLBACK"/> # Usually highlighted in red by IDE since this is resolved at runtime. ... </...>
note : This is the layout file for the fragment not the activity, I don't show the activities file as it's not relevant.
If you've looked at the code carefully you will notice there isn't a CALLBACK
set upon the FRAGMENT
, rather it is set upon the ACTIVITY
instead. The FRAGMENT
delegates the call from the onClickListener
to it's listener
, which happens to be the ACTIVITY
, during operation. This confuses the Android IDE somewhat as it is not smart enough to realize that the CALLBACK
belongs to the listener, that is the ACTIVITY
implementing the INTERFACE
, and it highlights the relevant XML accordingly. In fact setting a CALLBACK
upon the fragment gets ignored unless one takes additional steps to trap the relevant signals e.g. I believe ListFragment
does this to redirect to onItemSelected
.
The example onButtonPressed
provided by the template appears to simply be just that and does not provide a very useful implementation. Perhaps there is a tutorial on the android site that explains how to trap events and redirect to this method.