Aldi Renaldi Gunawan Aldi Renaldi Gunawan - 2 months ago 7
Android Question

Nested Child Fragment with Viewpager

currently, i was trying to create a nested view pager using a fragment, how can I access top parent function to refresh the View? let say,
I have:

public class ParentFragment extends Fragment{



...{
...
viewPagerAdapter = new ViewPagerParentAdapter(getChildFragmentManager(), listOfItem);
viewPager.setAdapter(viewPagerAdapter);
}

public void refreshView(){
loadData();
}


private class ViewPagerParentAdapter extends FragmentStatePagerAdapter{
private List<String> tabTitle;
private List<Item> listOfItem;
public ViewPagerParentAdapter(FragmentManager fm, @NonNull List<Item> listOfItem) {
super(fm);

this.tabTitle = new ArrayList<>();
this.listOfItem = new ArrayList<>();

if (listOfItem.size() > 0) {
this.listOfItem = listOfItem;

for (Item item : this.listOfItem) {
tabTitle.add(Item.getCLASSIFICATION());
}
}
notifyDataSetChanged();
}

@Override
public Fragment getItem(int position) {
return DetailFragment.newInstance(getItemAtPosition(position).getDETAILS());
}

public Item getItemAtPosition(int position) {
return listOfItem != null ? listOfItem.get(position) : null;
}
}
}


and here my object

public class Item{
//POJO
private String CLASSIFICATION;
private Details details;
}


detail fragment

public class DetailFragment extends Fragment{

...{
...
Details details = getArguments().getParcelable("details");

viewPagerAdapter = new DetailViewPagerAdapter(getChildFragmentManager(), details);
viewPagerDetails.setAdapter(viewPagerAdapter);
}

public void refreshParentView(){
((ParentFragment) getParentFragment()).refreshView(); //getting Null
}

public class DetailViewPagerAdapter extends FragmentStatePagerAdapter {

String[] tabTitle = {"Components", "Materials", "Descriptions"};
Details details;


public DetailViewPagerAdapter(FragmentManager fm, @NonNull Details details) {
super(fm);
this.details = details;
notifyDataSetChanged();
}

@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return DetailsChildFragment.newInstance(details.getCOMPONENT());
case 1:
return DetailsChildFragment.newInstance(details.getMATERIAL());
case 2:
return DetailsChildFragment.newInstance(details.getDESC());
}
return null;
}

@Override
public int getCount() {
return tabTitle.length;
}
}
}


last child fragment

public class DetailsChildFragment extends Fragment implements View.OnClickListener{

...{
...
...

Button buttonRefresh = (Button)getView().findViewById(R.id.button_refresh);
buttonRefresh.setOnClickListener(this);
}

@Override
public void onClick(View view){
switch(view.getId()){
case R.id.button_refresh:
((DetailFragment)getParentFragment()).refreshParentView();
break;
}
}

}


currently i was getting Null on the detail fragment refreshParentView
any suggestion? thanks before

Answer Source

You could use an interface as a Listener for events happening in the child

public interface Listener{
  void onRefreshButtonClicked();
}

The child fragment needs to have a Listener as a field, and then you could set the Listener when getting an instance of the child fragment.

public class ChildFragment extends Fragment{

private Listener listener;

public void setListener(Listener listener)//setter
...

//now on button click you call the listener
refreshButton.setOnClickListener(new View.OnClickListener(){

    @Override onClick(){
        if(listener!=null){
            listener.onRefreshButtonClicked();
        }
    }
}




public class ParentFragment extends Fragment{
    ...


    ChildFragment child = ChildFragment.getInstance()
    child.setListener(new Listener(){
        @Override
        void onRefreshButtonClicked(){
// implement your logic
        }
    }

An advantage of doing it like this is that you don't need to cast the parent from Fragment to ParentFragment which makes your code re-usable should you ever need to