Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return data from BottomSheetDialogFragment to Parent Fragment

I am populating a RecyclerView inside a bottomsheet and displaying the BottomSheet as a BottomSheetDialogFragment. WHen an item from the RecyclerView is clicked, i want to Auto fill a form using details from that item.

How do i pass a class(model) object containing the data from the BottomSheetDialogFragment to the Fragment where i instantiated the BottomSheetDialogFragment on. Here's my code

Fragment i want to auto populate fields

public class FormFragment extends Fragment implements onItemSelected {public class fetchSimilarContacts extends AsyncTask<Void, Void, String> {
    String result, res, search;

    fetchSimilarContacts(String sear){
        search = sear;
    }

    @Override
    protected void onPostExecute(String aVoid) {
        try {
            if (res.equals("200")){
                try {
                    // bring up bottom sheet
                    bottomSheetDialogFragment = new formBottomSheet();
                    Bundle bun = new Bundle();
                    bun.putParcelableArrayList("data", contItems);
                    bottomSheetDialogFragment.setArguments(bun);
                    bottomSheetDialogFragment.show(getActivity().getSupportFragmentManager(), bottomSheetDialogFragment.getTag());
                }
                catch (Exception ex){
                    ex.printStackTrace();
                }
            }
            else{
                Toast.makeText(getActivity().getApplicationContext(), "Could not connect to server", Toast.LENGTH_LONG).show();
            }
        }
    }

}}

I get the data and populate the RecyclerView using the asynctask function above. Here's the formBottomSheet class

public class formBottomSheet extends BottomSheetDialogFragment{

similarContactAdapter mAdapter;
RecyclerView rec;
ArrayList<hash> contItems;
View v;
onItemSelected itemSelected;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //contItems = new ArrayList<hash>();
    if(getArguments() != null){
        contItems = getArguments().getParcelableArrayList("data");
    }
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    /*return super.onCreateView(inflater, container, savedInstanceState);*/
    v = inflater.inflate(R.layout.form_bottomsheet_recyclerview, container, false);

    rec = (RecyclerView) v.findViewById(R.id.recycler);
    itemSelected = (onItemSelected) getParentFragment();
    //contItems = new ArrayList<hash>();
    mAdapter = new similarContactAdapter(contItems, getActivity().getApplicationContext(), new similarContactAdapter.onItemClickListener() {
        @Override
        public void onItemClick(hash hsh) {
            //after clicking on an item in the RecyclerView, i get the item's data here, how to i pass the data from here to the Form Fragment where i instantiated the bottom sheet fragment dialog?
            Toast.makeText(getActivity().getApplicationContext(), "",  Toast.LENGTH_LONG).show();
        }
    });
    final RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
    rec.setLayoutManager(mLayoutManager);
    rec.setItemAnimator(new DefaultItemAnimator());
    rec.setAdapter(mAdapter);
    mAdapter.notifyDataSetChanged();
    return v;
}

@Override
public void setupDialog(Dialog dialog, int style) {
    super.setupDialog(dialog, style);
}

public interface onItemSelected {
    void SendHashItem(hash hsh);
}   }

after clicking on an item in the RecyclerView, i get the item's data here, how to i pass the data from here to the Form Fragment where i instantiated the BottomSheetFragmentDialog?

Here's my activity

protected void onCreate(Bundle savedInstanceState) {
    try{
        super.onCreate(savedInstanceState);

        // Hide the status bar.
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_dashboard);

        //initialize
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        viewPager = (ViewPager) findViewById(R.id.viewp);
        setupViewPager(viewPager);
        title = findViewById(R.id.title);

        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setSelectedTabIndicatorColor(ContextCompat.getColor(getApplicationContext(), R.color.transparent));

        setupTabIcons();

        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {

                View tabView = tab.getCustomView();

                // get inflated children Views the icon and the label by their id
                TextView tab_label = (TextView) tabView.findViewById(R.id.tab);

                // change the label color, by getting the color resource value
                tab_label.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary));
                // change the image Resource
                // i defined all icons in an array ordered in order of tabs appearances
                // call tab.getPosition() to get active tab index.
                tab_label.setCompoundDrawablesWithIntrinsicBounds(0, tabIconsActive[tab.getPosition()], 0, 0);
                //"#4CAF50");
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                View tabView = tab.getCustomView();

                // get inflated children Views the icon and the label by their id
                TextView tab_label = (TextView) tabView.findViewById(R.id.tab);

                // change the label color, by getting the color resource value
                tab_label.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
                // change the image Resource
                // i defined all icons in an array ordered in order of tabs appearances
                // call tab.getPosition() to get active tab index.
                tab_label.setCompoundDrawablesWithIntrinsicBounds(0, tabIcons[tab.getPosition()], 0, 0);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

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

            }

            @Override
            public void onPageSelected(int position) {
                tabLayout.setScrollPosition(position, 0 , true);
                tabLayout.setSelected(true);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        viewPager.setCurrentItem(0);
        tabLayout.getTabAt(0).select();
        setToolbarTitle();
    }
    catch(Exception e){
        e.printStackTrace();
    }
}

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new VideoFragment(), "Video");
    adapter.addFragment(new ThreeSixtyFragment(), "360");
    adapter.addFragment(new FormFragment(), "Form");
    adapter.addFragment(new SettingsFragment(), "Settings");
    viewPager.setAdapter(adapter);
}

private void setupTabIcons() {
    TextView tabThree = (TextView) LayoutInflater.from(this).inflate(R.layout.cust_tab, null);
    tabThree.setText("Video");
    tabThree.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary));
    tabThree.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_video_red, 0, 0);
    tabLayout.getTabAt(0).setCustomView(tabThree);

    TextView tabTwo = (TextView) LayoutInflater.from(this).inflate(R.layout.cust_tab, null);
    tabTwo.setText("360");
    tabTwo.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_360_white, 0, 0);
    tabLayout.getTabAt(1).setCustomView(tabTwo);

    TextView tabOne = (TextView) LayoutInflater.from(this).inflate(R.layout.cust_tab, null);
    tabOne.setText("Form");
    tabOne.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_form_white, 0, 0);
    tabLayout.getTabAt(2).setCustomView(tabOne);

    TextView tabFive = (TextView) LayoutInflater.from(this).inflate(R.layout.cust_tab, null);
    tabFive.setText("Settings");
    tabFive.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_settings_white, 0, 0);
    tabLayout.getTabAt(3).setCustomView(tabFive);
}

@Override
public void onFragmentInteraction(Uri uri) {

}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}
like image 794
Jamie Avatar asked Jan 20 '19 17:01

Jamie


People also ask

How do I return data from Bottomsheetdialogfragment?

You can just call getActivity() and cast it to whatever your Activity's class name is: mAdapter = new similarContactAdapter(contItems, getActivity(). getApplicationContext(), new similarContactAdapter.

How to share data between fragments?

Share data between a parent and child fragment When working with child fragments, your parent fragment and its child fragments might need to share data with each other. To share data between these fragments, use the parent fragment as the ViewModel scope.


1 Answers

Both your FormFragment and your formBottomSheet are fragments that live inside the same Activity instance.

Sometimes a Fragment will have "parent" or "child" Fragments, but that is not the case here because your FormFragment uses getActivity().getSupportFragmentManager() to show the bottom sheet, rather than getChildFragmentManager(). This is totally fine, but it's something to keep in mind.

What this means is that the best way for formBottomSheet to "talk to" FormFragment is to instead talk to the Activity and then have the Activity pass that along to FormFragment.

formBottomSheet -> Activity -> FormFragment

Talking to the Activity is pretty easy. You can just call getActivity() and cast it to whatever your Activity's class name is:

mAdapter = new similarContactAdapter(contItems, getActivity().getApplicationContext(), new similarContactAdapter.onItemClickListener() {
    @Override
    public void onItemClick(hash hsh) {
        MyActivity activity = (MyActivity) getActivity();
        activity.onHashItem(hsh);
    }
});

Inside your Activity, you can use the FragmentManager to get ahold of your FormFragment and then send the message along to it. This relies on the FormFragment either having an id (if you set an android:id attribute on it in XML or if you used replace(R.id.some_id, ...) then you can use the id) or a tag (if you set an android:tag attribute on it in XML or if you used replace(..., "TAG") then you can use the tag).

public void onHashItem(hash hsh) {
    FragmentManager fm = getSupportFragmentManager();

    // use only one of the two following lines
    FormFragment fragment = (FormFragment) fm.findFragmentById(R.id.some_id); // if using id
    FormFragment fragment = (FormFragment) fm.findFragmentByTag("TAG"); // if using tag

    fragment.onHashItem(hsh);
}

Finally, you can create the onHashItem() method in your FormFragment:

public void onHashItem(hash hsh) {
    // do whatever you want
}
like image 157
Ben P. Avatar answered Oct 22 '22 06:10

Ben P.