I have two fragmnent.Say fragment A and fragment B.Now after clicking on certain button in fragment A I am starting fragment B using below code
getFragmentManager()
.beginTransaction()
.replace(R.id.framelayout, companyDetailsFragment)
.addToBackStack(null)
.commit();
Now I have another back button in fragment B.After clicking that button
I am removing that particular fragment using below code
getFragmentManager().popBackStack()
Now what I want is when the user click on back button I want to pass some certain data to previous fragment A.And the problem is
onStart() method is not getting called,so I am not getting any values.
So how to get the data?Any help will be appreciated.
I am able to solve it.Here is my answer
1.Create an interface
public interface OnButtonPressListener {
public void onButtonPressed(String msg);
}
2.Implemented this in Fragment B
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
buttonListener = (OnButtonPressListener) getActivity();
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onButtonPressed");
}
}
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getFragmentManager().popBackStack();
buttonListener.onButtonPressed("Message From First Fragment");
}
});
3.Used that listener in the Activity class
public class ParentActivity extends FragmentActivity implements OnButtonPressListener {
#Override
public void onButtonPressed(String msg) {
FragmentA Obj=(FragmentA) getSupportFragmentManager().findFragmentById(R.id.framelayout);
Obj.setMessage(msg);
}
}
4.Created the method in Fragment A class
public void setMessage(String msg){
System.out.print("got it");
}
Got the reference from this .Hope this will help others.If anyone has other good solution please answer this question.
You have a few options:
Store the value you want to pass in a globally scoped variable (SharedPrefs, using a singleton accessible from your Application class, etc).
Start a new instance of your Fragment, and include the variable as a Intent Extra.
AFAIK, there is not a way to add extras to a fragment when starting from the stack (you would access this in the onResume() if the variable could be passed).
Related
Like I said in the title, I want to send data from an activity to a fragment, but the fragment needs to use the data received when it is created, not after a button is pressed like usual. The activity that puts the values in the bundle is the one before the activity that calls the fragment, so that the bundle is already filled when the fragment is called.
From my research the best way to do this is using a bundle, but when I do String data = bundle.getString("value"), I get a null pointer exception, meaning the bundle is empty, but I already checked and the values are there. How do I fix this?
Better to use Eventbus for passing data activity to fragment, which is simple and concise.
1- Register/unregister to an event bus
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
2- Define an event class
public class Message{
public final String message;
public Message(String message){
this.message = message;
}
}
3- Post this event in anywhere in your application
EventBus.getDefault().post(new Message("hello world"));
4- Subscribe to that event to receive it in your Fragment
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(Message event){
mytextview.setText(event.message);
}
More details:
https://github.com/greenrobot/EventBus
How to pass data between fragments
https://androidwave.com/fragment-communication-using-eventbus/
I have implemented a master-detail view. With two fragments being displayed side by side on a large 10-inch screen. Fragment A Displays a list of orders. When an order is selected the details of that order are displayed in Fragment B. In fragments B after processing the order items. I want to notify Fragment A to update the UI and colour the processed order in the list of orders.
The current method that I have tried was creating an interface in Fragment B implementing the interface in Fragment A. However, this method does not seem to work as when I try and set the instance of the interface in the onAttach method the application crashes as the context is still the context of Fragment A.
#Override
public void onAttach(#NonNull Context context)
{
super.onAttach(context);
if (context instanceof OnStockAddedListener)
{
onStockAddedListener = (OnStockAddedListener) this.getActivity();
} else
{
throw new ClassCastException(context.toString());
}
}
How can i go about doing this.
Your fragments are hosted in an Activity, and that activity is what's passed to onAttach(). So your activity needs to be responsible for dispatching communication between your fragments.
So, in FragmentB, you cast your Activity to your listener interface when you're attached:
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.onStockAddedListener = (OnStockAddedListener) context;
}
And you implement the interface in your Activity:
public class MyActivity implements OnStockAddedListener {
#Override
public void onStockAdded(Stock stock) {
FragmentA fragmentA = (FragmentA) getSupportFragmentManager()
.findFragmentByTag(/* insert tag here */);
fragmentA.handleStockAdded(stock);
}
}
And you receive these messages in FragmentA:
public class FragmentA {
public void handleStockAdded(Stock stock) {
// update ui, or whatever else you need
}
}
The main thing is to not think about FragmentA talking to FragmentB, or FragmentB talking to FragmentA. Instead, FragmentA and FragmentB both talk to the Activity, and the Activity can talk (as required) with either FragmentA or FragmentB. Everything flows through the activity.
I have my app working with fragment called into the main activity. Everything works great but i would like to be able to control the menu above the fragment layout.
So lets say you navigate to fragment blog posts i would like to the text view i set in the menu above the fragment to update or hide a button or show a button with set visibility.
I have no clue how to control the things who are not in the current fragment.
How should i go about this.
Thanks
Define an interface in your fragment and have your Activity implement that interface.
public interface MyInterface {
// add methods here
}
In onAttach, get the interface:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof MyInterface) {
mMyInterface = (MyInterface) activity;
} else {
throw new ClassCastException(activity + " must implement interface MyInterface");
}
}
#Override
public void onDetach() {
mMyInterface = null;
super.onDetach();
}
Then simply call mMyInterface methods as needed.
I am writing an Android app (4.4) that uses Fragments. Each Fragment is in it's own .java file (and its own class), and each one has it's own .XML (layout) file. In the main FragmentActivity, my "getItem" routine reads the "position" argument, and creates instances of these classes as needed.
When the app starts, when Fragment 0 (zero) starts up, it runs some code in the "onCreateView." Based on what happens in that code, I need to change the UI of the Fragment 1 (buttons appear & disappear based on that logic).
However, the code RUNS with no errors, but the UI changes do not take effect. I'm thinking that perhaps I need to run my "startup" code somewhere else with a wider scope. I could be wrong.
Can anyone suggest a way for me to be able to control the UI of various layouts at startup?
Thanks!
If you can post some of your code, would be easier.
anyway if I got your problem, you need to change the UI of the fragment 1 from the fragment 0.
What you need is what is explained in the document Communicating with Other Fragments
you should do something like:
public class MyActivity extends FragmentActivity implements MyInterface{
#Override
public void changeUI(String sometext) {
Fragment1 fragment1 = (Fragment1) getFragmentManager().findFragmentByTag("tagCommittedFragment1");
fragment1.applyChange(sometext);
}
}
public class Fragment0 extends Fragment{
MyInterface mMyInterface;
public interface MyInterface {
public void changeUI(String sometext);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mMyInterface = (MyInterface) activity;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mMyInterface.changeUI("newtext");
}
}
public class Fragment1 extends Fragment{
public void applyChange(String sometext){
// do your work
}
}
You must make an interface to communicate between Fragments which would be implemented by your MainActivity:
public interface Communicator {
public void respond(String data);
}
Now you need to use this Interface to send data from FragmentA:
Communicator comm = getAcitivity(); //your activity must implement this interface
comm.respond(data);
As your MainActivity implements the above interface, it will also implement the respond() method which can be used to pass data to FragmentB:
public void respond(String data){
FragmentManager manager = getSupportFragmentManager();
FragmentB fragB = manager.findFragmentById(R.id.fragment_b);
fragB.changeData(data);
}
Now all you need to do is collect this data and make changes in FragmentB using a changeData() method:
public void changeData(String data){
textView.setText(data);
}
NOTE: As FragmentB has no use of the Interface, it should not be visible to it, therefore you can also create the interface inside FragmentA instead.
I have a custom DialogFragment with a couple of options inside of it. The user is simply presented with a "Done" button in the Dialog to signal that they have completed their choice and to resume the activity. I have a textView on the activity below the dialog. My first thought was to use either a database (overkill) or sharedPreferences, but sharedPreferences is not an option in my specific case. So, my question is how do I setText on an textView from a DialogFragment with no sharedPreferences. Thanks
This can be easily done via Interface:
In your DialogFragment class:
public interface OnDoneClickListener {
void onDoneClicked() {}
}
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
try {
mCallback = (OnDoneClickListener) activity;
} catch (ClassCastException e) {
Log.d("Error", "activity must implement OnDoneClickListener");
}
}
Now simply put mCallback.onDoneClicked() in your desire onClick event.
Back to your Activity which need to implement OnDoneClickListener,
#Override
public void onDoneClicked() {
tv.setText("Done Clicked!!");
}
If you're using an AlertDialog (simplest) then you just need to provide an onClickListener:
http://developer.android.com/reference/android/app/DialogFragment.html#AlertDialog
That page also has an example when using a more "standard" Fragment, basically call a method on the activity.