Reputation: 600
I'm new to android and I'm trying to get a hang of creating and using Fragments.
I have a fragment that shows a simple list of multiple dates to choose from and implements an onClickListener. The idea is once a user chooses a date, the fragments sends the date back to the MainActivity which then runs a query in database and sends the database response to another fragment.
I'm stuck on the point of sending the date back to MainActivity, elegantly. I can't find much info. I found this:
Activity activity = getActivity();
if(activity instanceof MyActivity){
MyActivity myactivity = (MyActivity) activity;
myactivity.myMethod();
}
I'm very new to this but this seems hacky to me. Is this the right way or is there another way?
Any input is appreciated
Upvotes: 0
Views: 168
Reputation: 21766
YES this is absolutely right. You can use this, if you are not sure that your Fragment
is attached to Activity
You can also achieve this by using Interface
, using an EventBus
like LocalBroadcastManager
, or starting a new Activity
with an Intent
and some form of flag
passed into its extras
Bundle or something else.
Here is an example about using Interface:
1. Add function sendDataToActivity() into the interface (EventListener
).
//EventListener.java
public interface EventListener {
public void sendDataToActivity(String data);
}
2. Implement this functions in your MainActivity
.
// MainActivity.java
public class MainActivity extends AppCompatActivity implements EventListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void sendDataToActivity(String data) {
Log.i("MainActivity", "sendDataToActivity: " + data);
}
}
3. Create the listener in MyFragment
and attach
it to the Activity
.
4. Finally, call function using listener.sendDataToActivity("Hello World!")
.
// MyFragment.java
public class MyFragment extends Fragment {
private EventListener listener;
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
if(activity instanceof EventListener) {
listener = (EventListener)activity;
} else {
// Throw an error!
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my, container, false);
// Send data
listener.sendDataToActivity("Hello World!");
return view;
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Hope this will help~
Upvotes: 1
Reputation: 16224
I prefer the interface based approach because is very clean. You can declare a nested interface in your Fragment
or an external one:
interface OnMyStuffListener {
void myMethod();
}
Make the Activity
to implement that interface:
public class MainActivity extends Activity implements OnMyStuffListener {
@Override
public void myMethod() {
// Do whatever you want.
}
}
The Fragment
will be attached to the Activity
so you can check the instance of the Context
and cast it to the Activity
:
public class MyFragment extends Fragment implements View.OnClickListener {
private OnMyStuffListener mListener;
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnMyStuffListener) {
mListener = (OnMyStuffListener) context;
} else {
throw new IllegalArgumentException("The context " + context.getClass().getName() +
"must implement " + OnMyStuffListener.class.getName());
}
}
@Override
public void onDetach() {
super.onDetach();
// Release it avoiding memory leak.
mListener = null;
}
@Override
public void onClick(View v) {
mListener.myMethod();
}
}
Upvotes: 2