How to send date from parent Fragment to Child Fragment? - android

I'm an Android novice.
As with the title, I want to convey some data from Parents Fragment to child Fragment.
But I'm stuck in it and very hard.

Maybe try saving your child Fragment as a variable in your parent Pragment. Then you are able to call public methods like in your case childFragment.setDate(date).

To transfer information from the parent fragment to the child create an interface
interface YourListner{
void methodToPassData(Date date);
}
After which the child fragment should implement this interface
Then you can cast the fragment to the type of the interface and pass the date to it by calling the method.
ChildFragment fragment = new ChuldFragment();
//display fragment
YourListner fragmentListener = (YourListner)fragmentListener;
fragmentListener.methodToPassData(date);
You can also do this using the constructor in the child fragment.

Related

How to start a fragment from a RecyclerView Adapter which is inside another fragment?

I have a tab view with two fragments. Those two fragments contain a recycler view with cards.
Each card in both fragments had a button.
Clicking on fragment 1's button should open the fragment 2 as a separate page and vice-versa.
I am struggling to find a method to implement this without making every too complex and tightly coupled.
This is fragment one with its own Adapter.
And this is fragment two:
Clicking on that SELECT DONOR button in Donees page should open donor fragment in a new page where the user will be able to assign a donor for the selected donee.
So I have two needs here
1) To start a fragment from a fragment
2) To Keep track from which Donee the new donor page was opened so that I can assign a donor for that specific donee.
I hope this is understandable.
so far I have tried LocalBroadcast and FragmentManager but its hard to keep track of what I'm doing with the code.
Can you guys suggest a better technique to achieve this ?
the easiest solution would probably be, starting a new activity, passing something like an ID, name or something to the intent on an Button click.
Context.startActivity(new Intent(Context, YourAssigneeActivity.class)
.putExtra("ID",id));
So I assume that you do not switch to the other tab when you click a button on one tab. Therefore the fragment should fill the whole screen.
With this assumption in mind you most likely have to switch the Activity. This can be dones easily with an Intent:
Intent intent = new Intent(getActivity(), ActivityB.class)
intent.putExtra("KEY", <your required data to transfer>);
getActivity().startActivityForResult(intent);
Note that when you use putExtra() don't forget that you need to implement Parcelable in those objects (explained here)
To get to know which item was clicked you can use the following pattern (pseudocode - I personally think it's really clean):
FragmentA implements YourAdapter.callback {
onItemClicked(<YourObject> item) {
<starting new activity as described above>
}
}
class YourAdapter extends RecyclerView.Adapter {
Callback mCallback;
YourAdapter(Context context, otherStuff) {
mCallback = (Callback) context;
}
interface Callback {
onItemClicked(<YourObject> item)
}
YourViewHolder implements View.OnClickListener {
onClick(View v) {
mCallback.onItemClicked(<YourObject> item)
}
}
}
Once you are in your Activity, you can set the Fragment in onCreate() of your Activity. In the Activity retrieve the data with getIntent() in the onCreate before creating the Fragment. Then you can put your data in the Fragment with setArguments(<Bundle>). In the Fragment in the onCreateview() retrieve it with getArguments().
I know this is kind of conmplicated. A better solution would be to just switch to an Activity and forget about the Fragment. This would remove one layer of complexity.
If you directly go from Fragment to Fragment you can ignore the Activity part but the rest should stay the same.
Hope this was the answer you were looking for!
Edit: Note that mCallback = (Callback) context is null if the Activity is not implementing Callback

Updating Parent Fragment from Child Fragment

In my android application, I have two Fragments. Parent Fragment contains list of available Filter Types and when a particular Filter Type is clicked (in Parent Fragment - Yellow Background) corresponding Child Fragment (Pink Background) opens with list of available options for selected filter type. My requirement is once User select/deselect an option in child fragment, it should reflect/update option count (Green color) in parent Fragment.
Please check attached wireframe.
You can use Otto Bus for comunications between Fragments, fragments-activities, services, etc.
Maybe, the first time you can be a little weird if you have not used before but it is very powerful and very easy to use. You can find the library and a tutorial here:
http://square.github.io/otto/
An example. In your adapter or where you have your item click event you cand send a Object by the Bus.
In your bus you invoque the post method and pass the object. (I recommended create a singleton for Bus).
The singleton Bus Provider.
/**
* Canal de comunicacion
*/
public class BusProvider {
private static final Bus REST_BUS = new Bus(ThreadEnforcer.ANY);
private static final Bus UI_BUS = new Bus();
private BusProvider() {};
public static Bus getRestBusInstance() {
return REST_BUS;
}
public static Bus getUIBusInstance () {
return UI_BUS;
}
}
You send a Object in the bus (in your child fragment) like this:
BusProvider.getUIBusInstance().post(itemSelected);
And in your parent fragment you subscribe for this event:
#Subscribe
public void activitySelected(final Item itemSelected) {
}
Hope it helps you!!
Even though my answer might be late, I guess it still could help :
The solution is simple, in case you need to access a parent fragment from a child one, then use a specific tag for the parent when adding it to the stack, like in the following code example :
1) In the containing activity :
// We instanciate the parent fragment
ParentFragment parentFragment = new ParentFragment();
FragmentTransaction ft = fm.beginTransaction();
// We add the parent fragment with a tag, so we can use it later to fetch
// the current instance of the parent fragment from the child fragment
ft.replace(R.id.content_frame, parentFragment, "parent_fragment_tag");
ft.addToBackStack(null);
// Commit transaction
ft.commit();
2) In the child fragment, we get the current parent fragment instance like this :
Fragment parentFragment = getFragmentManager().findFragmentByTag("parent_fragment_tag");
I hope this answer can be of help.

How to get the object of fragmentA from fragmentB in a Activity

What i have
I have an activity
MainActivity.java here in this activity I have a
fragment(MainFragment.java)
In MainFragment.java I have two child fragments ChildOne.java and
ChildTwo.java
I have a editText in ChildOne.java
What I am trying to do:
I need to get the value in the editText of ChildOne.java from
ChildTwo.java
how to achieve this !
You can achieve this in multiple ways, but I'll give you one supposing that both Fragments are displayed at the same time.
In your ChildTwo use getParentFragment to get MainFragment.
MainFragment parent = (MainFragment) getParentFragment();
String edit_text_value = parent.getChildOneText();
In your MainFragment you need a reference object to your ChildOne fragment.
public String getChildOneText()
{
return mFirstFragment.getEditTextValue();
}
Finally in your ChildOne fragment create a method to return your EditText.
public String getEditTextValue()
{
return my_edit.getText().toString();
}
Hope it helps!
You may create one function in mainActivity and a variable that holds the value in there. And call that function when you want to save the data of editText, And can create a function to get the data in MainActivity as well. Call those functions like this -
((Home) getActivity()).shareData("example string");
((Home) getActivity()).receiveData("example string");
May check this answer and this one

Unable to access layout inflater as child view has not initialised

I have an Android activity that searches a web service for new content to display then either displays a NoResultFragment or a ResultFragment which represents a swipe stack for the user to swipe through the items returned. Because I need to manage the stack, retrieving more data in the background as the stack gets low etc from the Activity, all of the stack details are held at the activity level and the yes/no actions trigger methods on the activity. All good so far.
The problem is I am using the layout inflater in the ResultFragment class to generate dynamic child Views, each one of which represents an item on the stack. These then get returned to the Activity controller which manages them, sends them to the fragment to display, hides them, moves them around etc, so I need access to the child item Views from the activity to do all this. I need to generate the actual child views from within the ResultFragment though, as that is where they will be visually displayed.
I create the ResultFragment, set it to the content area and then try and generate the child views by calling into the fragment created. The error is that the onViewCreate() method has not yet been called on the ResultFragment class as it has only just been added to the content frame, so there is no layoutinflater and my method to return the child View fails. I get the feeling there is something off with my design here, can someone shed some light on how to do this? Is it as simple as just passing through the parent layoutinflater from the Activity class?
Child view creation method
public View getChildView(StorySeed seed, int seedIndex)
{
final View m_view = inflater.inflate(R.layout.fragment_item, null); // Code to populate the view
return m_view;
}
activity method
private void initialiseResults(ArrayList<StorySeed> storySeeds) {
resultsFragment = new ResultsFragment(storySeeds, getApplicationContext());
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, resultsFragment)
.commit();
// load the first results to screen
seedIndex = 1;
for (int i = 0; i < seedsToDisplay; i++) {
getNextToStack();
}
}
It is the call to getNextToStack() that is going into the Fragment class and calling the getChildView() method
I would suggest that you create the views in the activity (the controller) and pass them to the fragment as needed. The fragment is your MVC "view" and it should only tell the controller what happened. The controller decides what to do after that.
The way you can have one fragment replace itself by another is to call a method on the activity. Here's a quick example:
interface IAppController {
void onResultsNotFound();
}
class MyActivity extends Activity implements IAppController{
....
public void onResultNotFound(){
//switch fragments
}
}
class MyFragment {
....
void myMethod(){
IAppController controller = (IAppController) getActivity();
controller.onResultsNotFound();
}
}
Hope this helps

Set arguments of fragment from activity

I want to pass arguments from my activity to a fragment, embedded into the activity. Fragment is embedded statically in xml layout.
I tried to call setArgument() like this:
setContentView(R.layout.detail_activity);
DetailFragment detailFragment = (DetailFragment) getFragmentManager().findFragmentById(R.id.detailFragment);
detailFragment.setArguments(getIntent().getExtras());
but it is already too late, because setArguments has to be called immediately after fragment's creation. The only was I see it to getArguments() and the change the bundle. Any better way?
AFAIK, you can't use setArguments() like that when you embed the fragment within XML. If it's critical, you'd be better off dynamically adding the fragment instead. However if you truly want the fragment to be embedded via XML, there are different ways you can pass along that data.
Have the Activity implement the fragment's event listener. Have the fragment then request the required parameters from the Activity at creation or whenever needed. Communication with Fragment
Create custom attributes that can be embedded in xml along with the fragment. Then during fragment's inflation process, parse the custom attributes to obtain their data. Custom fragment attributes
Create public setters in the fragment and have the activity use them directly. If it's critical to set them prior to the fragment's onCreate() method, then do it from the activity's onAttachFragment() method.
You have two options here
If you just need information in the activity's intent, then placing information from the intent into the fragment arguments just adds an unneeded step. You might just a well keep things simple and from your fragment call
Bundle data = getActivity().getIntent().getExtras();
If you need to add information that is not in the activity's intent then in you fragment create a no parameter constructor like:
public DetailFragment() {
this.setArguments(new Bundle());
}
then in your activity you can add whatever arguments you need with code like:
DetailFragment frg = (DetailFragment) getFragmentManager().findFragmentById(R.id.detailFragment);
frg.getArguments().putBundle("key", data);
the point here is to use the existing bundle object rather than trying to call setArguments() after the fragment has been attached to the activity.
Another way to pass data to Fragment is as following:
//In DetailFragment (for Instance) define a public static method to get the instance of the fragment
public static final DetailFragment getInstance(Bundle data) {
DetailFragment fragment = new DetailFragment();
fragment.setArguments(data);
return fragment;
}
And when attaching DetailFragment from inside Activity
Bundle data = new Bundle();
//Add data to this bundle and pass it in getInstance() of DetailFragment
fragmentTransaction.replace(R.id.frament_layout, DetailFragment.getInstance(data));

Categories

Resources