Access Viewpager Fragment Method from Activity

Call Tabbed Fragment method from Activity

What you should do is : create only once each fragment and then give it for all calls to the getItem method.

For instance :

public class AppSectionsPagerAdapter extends FragmentPagerAdapter {

Fragment one, two, three;

public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}

@Override
public Fragment getItem(int i) {
switch (i) {
case 0:
if(one == null)
one = new NPListFragment();
return one;
case 1:
if(two == null)
two= new PListFragment();
return two;
case 2:
if(three == null)
three= new FavouritesFragment();
return three;
}
return null;
}

@Override
public int getCount() {
return 3;
}

}

Now, even you in your activity you can call getItem

You'll just need to cast it to the real fragment class if you want to call a specific method.

int pos = viewpager.getCurrentItem();    
Fragment activeFragment = adapter.getItem(pos);
if(pos == 0)
((NPListFragment)activeFragment).refreshT();
...

Access ViewPager Fragment method from Activity

Using the ViewPager.OnPageChangeListener is the correct way to go, but you will need to refactor your adapter a bit in order to keep a reference to each Fragment contained in the FragmentPagerAdapter.

You do that using the instantiateItem() method override in the adapter, here is a simplified example:

 class PagerAdapter extends FragmentPagerAdapter {
String tabTitles[] = new String[] { "One", "Two", "Three", "Four"};
Context context;

//This will contain your Fragment references:
public Fragment[] fragments = new Fragment[tabTitles.length];

public PagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
@Override
public int getCount() {
return tabTitles.length;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
case 2:
return new FragmentThree();
case 3:
return new FragmentFour();
}
return null;
}

//This populates your Fragment reference array:
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
fragments[position] = createdFragment;
return createdFragment;
}

@Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
}

Then, instead of creating a new Fragment, use the one contained in the adapter:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }

@Override
public void onPageSelected(int position) {

// do this instead, assuming your adapter reference
// is named mAdapter:
Fragment frag = mAdapter.fragments[position];
if (frag != null && frag instanceof FragmentTwo) {
((FragmentTwo)frag).sendGetRequest();
}
}

@Override
public void onPageScrollStateChanged(int state) { }
});

Note that if you're using different Fragment classes in your adapter, you can implement an interface that defines sendGetRequest(), and in each of your Fragment classes implement the sendGetRequest() method.

If you don't go with the interface approach, you will need to cast the Fragment to your own Fragment type as shown in the example above, i.e.:

if (frag instanceof FragmentTwo) {
((FragmentTwo)frag).sendGetRequest();
}

UPDATE

For using ViewPager2 and Kotlin, here is how it would look:

    viewPager.registerOnPageChangeCallback(
object: ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
val frag: Fragment = mAdapter.fragments[position]
if (frag != null && frag is FragmentTwo) {
(frag as FragmentTwo).sendGetRequest()
}
}
}
)

call a method on a fragment in a ViewPager

The pagerAdapter.getItem(int) method usually creates a new instance of the fragment, however, so what you can do is use a HashMap to store a reference to the already existing fragments.

// ViewPagerAdapter
private HashMap<Integer, Fragment> fragmentHashMap = new HashMap<>();

@Override
public Fragment getItem(int position) {
if (fragmentHashMap.get(position) != null) {
return fragmentHashMap.get(position);
}
TabFragment tabFragment = new TabFragment();
fragmentHashMap.put(position, tabFragment);
return tabFragment;
}

Then you can find your fragment to call its methods:

FragmentAdapter fa = (FragmentAdapter)viewPager.getAdapter();
TabFragment theFragment = (TabFragment)fa.getItem(index);
theFragment.customMethod(Object obj);

You will have to keep track of which fragment goes with which index because you cast them to their specific class in order to access their methods.

Calling Fragment Method From Main Activity with FragmentPagerAdapter

At the top of your activity add ViewPagerAdapter pagerAdapter;

Then use this to create your ViewPager adapter

pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

Then use this to access the first page of the ViewPager

Fragment fragment = pagerAdapter.getItem(0);

First make sure that the above statement returns not null and that the fragment is HomeFragment. Now cast the fragment to your HomeFragment and call the method

((HomeFragment) fragment).yourMethod();

How to call method on Fragment from ViewPager?

Use an instantiateItem() override in the FragmentPagerAdapter in order to keep a reference for the fragments in the ViewPager that have already been instantiated.

Since you have a variable amount of fragments in the ViewPager, use a Map to map the index to each fragment:

public class QuestionsAdapter extends FragmentPagerAdapter {
private ArrayList<SurveyElement> mSurveyElements;
private int mAdapterSize = 0;

//Fragment container:
Map<Integer, Fragment> mFragmentMap = new HashMap<>();

public QuestionsAdapter(FragmentManager fm) {
super(fm);
}

public void updateFragmentAdapter(ArrayList<SurveyElement> fragmentList) {
mSurveyElements = fragmentList;
mAdapterSize = fragmentList.size();
this.notifyDataSetChanged();

}

//This populates your Fragment reference map:
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
mFragmentMap.put(position, createdFragment);
return createdFragment;
}

@Override
public Fragment getItem(int position) {
SurveyElement surveyElement = mSurveyElements.get(position);
switch (surveyElement.getElementType()) {
case SurveyElement.OPEN_TEXT:
return OpenTextFragment.newInstance(surveyElement, position + 1);
case SurveyElement.SINGLE_RADIOBUTTON:
return SingleRadioButtonFragment.newInstance(surveyElement, position + 1);
case SurveyElement.DROPDOWN_SELECT:
return DropdownSelectFragment.newInstance(surveyElement, position + 1);
case SurveyElement.MULTIPLE_CHECKBOXES:
return MultipleCheckboxesFragment.newInstance(surveyElement, position + 1);
default:
return OpenTextFragment.newInstance(surveyElement, position + 1);

}
}

@Override
public int getCount() {
return mAdapterSize;
}
}

Then, you can use the code below in the activity to call into the appropriate method for each type of fragment. The key is to reference the actual fragment that is instantiated and shown in the ViewPager:

private boolean canIGoToNextQuestion(int position){ // mMyViewPager.getCurrentItem()

Fragment fragment = mQuestionsAdapter.mFragmentMap.get(position);
if (fragment != null && fragment instanceof OpenTextFragment){
return ((OpenTextFragment)fragment).attemptAnswerQuestion();
}

return false;
}

Access a ViewPager Fragment's public method from the main Activity

You can extend FragmentStatePagerAdapter much like having your own ArrayAdapter.

Hold a List<Fragment> in that (passed through the constructor), then just use adapter.getItem(position).getFoo()

Very minimal example.

public MyFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments;

public MyFragmentStatePagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}

public int getCount() { return fragments.size(); }
public Fragment getItem(int position) { return fragments.get(position); }
}

call activity method from inner viewpager fragments

Yes, it is possible. Follow these steps.

  1. Make an interface and declare a method.
  2. Let the activity implement that interface
  3. Now override the method from interface and write the definition for the function.
  4. Make the object of the interface in the fragment.
  5. Using the object call that method whenever needed.

Example using code : -

Inteface Code :-

//use any name
public interface onInputChangeListener {

/*To change something in activty*/
public void changeSomething(//parameters that will hold the new information);


}

Activity Code:-

public class MyActivity extends AppCompatActivity implements onInputChangeListener {

onCreate();

@override
public void changeSomething(/*Arguments with new information*/){

//do whatever this function need to change in activity
// i.e give your defination to the function
}
}

Fragment Code:-

public class MyFragment extends Fragment {

onInputChangeListener inputChangeCallback;

/*This method onAttach is optional*/
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);

// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
inputChangeCallback = (onInputChangeListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement onFragmentChangeListener");
}
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View v = inflater.inflate(R.layout.fragment_my,container,false);
inputChangeCallback.changeSomething(//pass the new information);
return v;
}

}

This would doo.. Cheers!

If you want a quick Fix :-

In your Fragment:-

public class MyFragment extends Fragment {

MyActivity myActivity;

onCreateView(){
...

myActivity = (MyActivity)getActivity;

myActivity.callAnyFunctionYouWant();

...
}
}

How can Call a Fragment Method from a Parent Activity in Android

The simplest way is to store locally in your activity reference to your fragment and call getToast on it:

SampleFragment myFragment; // declared in your activity class

// This is small change in your setupViewPager
myFragment = new SampleFragment ();
adapter.addFrag(myFragment, context.getResources().getString(R.string.info));

//later on when you want to call getToast:
myFragment.getToast();

You may also skip storing SampleFragment as a data member of your activity and retrievie its reference directly from FragmentManager when its needed.



Related Topics



Leave a reply



Submit