I have this kind of structure
MainPage Activity1 has view pager holding 3 fragments
I am using tabapdater
The first of the fragments have method to move to another Activity2
I want to fire some method in the first fragment when button is clicked in Activity2
Can i do that? can you guys give me any example code for it??
Thanks guys
There are some solutions.
The first one I think is startActivityForResult. If you start your second activity by calling startActivityForResult instead of startActivity you can expect the result in first activity by overriding the onActivityResult method and then change the first fragment content from there.
Another good and easy solution is using Buses like EventBus and otto.
They are well documented.
In your Fragment class:
public void foo(Object objectToPassFromActivity) {
// do what you want
}
In Your activity:
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentByTag(getFragmentTag(R.id.yourViewPagerId, fragmentPosition);
fragment.foo(objectToPassFromActivity)
Add method:
private String getFragmentTag(int viewPagerId, int fragmentPosition) {
return "android:switcher:" + viewPagerId + ":" + fragmentPosition;
}
You can see the link that i added in comments to get more details.
Related
I write a ViewPager with some Fragments. In the Fragment, there are VideoView. At the beginning, the first VideoView will auto play, when the first VideoView finishes, I want change the page of VideoView, so I want call setCurrentItem in Fragment. Is this possible?
you can use eventbus notice viewpager to next page.
implement toNextPage func
void toNextPage() {
if (viewPager.getAdapter().getCount() >= viewPager.getCurrentItem() + 1) {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
} else {
Toast.makeText(this, "is end", Toast.LENGTH_SHORT).show();
}
}
As you've not mentioned the language you're using, I'm gonna answer it for both Java and Kotlin.
Java:
Create a function in your ViewPager's Activity as
public void changeViewPagerPostition(int position) {
viewPager.setCurrentItem(position);
}
And call this function it from Fragment with passing the postition parameter as
((YourActivity) getActivity()).changeViewPagerPostition(yourPostition);
//Remember first item is at 0th postition and so on.
You can also declare the ViewPager as public static in your Activity and can access the ViewPager directly in Fragment but this is not the preferred way.
Kotlin:
In kotlin, it's a bit easy I believe, although you can use exact same way mentioned for Java but I use this way as I also use ViewPager for more things:
Declare the ViewPager as global variable in your Activity as
lateinit var viewPager : ViewPager
Initialize in it onCreate() of the Activity as
viewPager = findViewById(R.id.viewPager)
And use it in fragment and pass your current postition as
(activity as YourActivity?)!!.setCurrentItem(yourPosition)
Now, the moment your video finishes, you can call any of these ways in your Fragment to change the currentItem of the ViewPager.
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
So i have a working solution, it seems not to be ideal but just need to confirm - so i have an activity with 3 fragments showing one at a time - i need to block the default back operation for two of those fragments so that when the back button is pressed nothing happens(for now, still developing).
So what i did was that i used an interface
//top of activity snippet
public class StudyKitActivity extends AppCompatActivity implements OnStudyKitBackListener{
private int fragment_id;
.
.
.
.
//interface method
#Override
public void onBackChanged(int fragment_id) {
this.fragment_id = fragment_id;
}
to set a variable on the activity
when i am changing the current fragment in the activity e.g set 1 for fragment A, 2 for fragment B and 3 for fragment C, so this is code snippet within fragment 2 when moving to fragment 3 -
onStudyKitBackListener.onBackChanged(3);
StudyKitResultFragment studyKitResultFragment = StudyKitResultFragment.getInstance(examResult);
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.frame_container, studyKitResultFragment).addToBackStack("exam_result").commit();
and i did an overwrite in my activity's onBackpressed to check the value of that variable and either execute the default OnBackPressed or do nothing like so -
#Override
public void onBackPressed() {
if(this.fragment_id==2||this.fragment_id==3){
}
else{
super.onBackPressed();
}
}
i came up with this cos other solutions like setting a tag and trying to get the fragment's tag or by checking current fragments id did not work for me, this is working like i expected but i have not seen it anywhere just want to know if there is an alternate solution.
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
Activity1 placed with fragment and starting activity2 by action item after closing activity2 i need to get a fragment instance of current fragment placed in activity1? thanks in advance
Your question does not give enough details, but I will assume you have an activity with multiple fragments. Also let us assume you are using tabs for navigation.
To get an instance of a fragment you can make use of tags assigned to each fragment. Here is the function that returns the tag associated with a fragment:
private static String makeFragmentName(int viewId, int position)
{
return "android:switcher:" + viewId + ":" + position;
}
And you would get the fragment like this:
MyFragment fragment = ((MyFragment) fm.findFragmentByTag(makeFragmentName(R.id.pager,position)))
Where R.id.pager is the pager view containing the fragments (with tabs), and position is the position of the fragment in a tab layout.
Let me know how this works out for you.