Android: Best Approach to pass data between viewpager fragments

前端 未结 3 601
礼貌的吻别
礼貌的吻别 2020-12-06 19:00

I have 3 fragments in a ViewPager Activity. All 3 fragments have input fields. Here I am trying to pass first two fragments data to third fragment. I read few posts here and

相关标签:
3条回答
  • 2020-12-06 19:51

    Okay, I Had same issue to pass data(not just string) between two tabs in a ViewPager. So here is what i did. I Use interfaces to communicate between the different components.

    The data passes this way:

    Tab 1 -> Activity -> VewPageAdapter -> Tab 2
    
    1. In Tab 1

    create an interface.

    OnCartsDataListener mOncarOnCartsDataListener;
    
    
    public interface OnCartsDataListener {
    
        public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels);
    
    }
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mOncarOnCartsDataListener = (OnCartsDataListener)activity;
        }catch (ClassCastException e){
    
        }
    
    }
    // now call mOncarOnCartsDataListener.onCartsDataReceived(data) when you have the data
    
    1. In Activity

    Implement the interface and override the method

    ViewPagerAdapter adapter;
    adapter = new ViewPagerAdapter(getSupportFragmentManager(), Titles, Numboftabs);
    
    @Override
    public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels) {
        Log.d(TAG, "data received to Activity... send to view pager");
        adapter.onCartsDataReceived(cartsViewModels);
    }
    

    3.IN ViewPagerAdapter

    Also implements the interface and override the method

    @Override
    public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels) {
        Log.d(TAG, "data received to view pager... sending to tab 2");
    
        if(tab2!=null){
            tab2.onCartsDataReceived(cartsViewModels);
        }else{
            Log.d(TAG, "tab2 is null");
        }
    } 
    
    1. Finally tab 2

    Also implements the interface and override the method

    @Override
    public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels) {
        Log.d(TAG, "Finally ! received data to tab 2");
        if(cartsViewModels!=null){
            for(CartsViewModel cart : cartsViewModels){
                Log.d(TAG,"got it :"+cart.getCartName());
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-06 19:53

    Since AndroidX, you can create a ViewModel and share data between Activity and all fragments within ViewPager

    Read here how to

    0 讨论(0)
  • 2020-12-06 20:01

    Can you do something like this? First create any data structure like Arraylist in your main activity. Then send a reference of that data model to your fragments. Now update that data when, on change your text fields. By doing this all the fragment can see updated values. So fragments can update this data itself and we don't need to send that data since it is already shared. I'll explain this using your example. Try to improve this. You can maintain fragment specific data model then each fragment can access data with the knowledge of that data owner.

    TabsPagerAdapter.java

    public class TabsPagerAdapter extends FragmentPagerAdapter {
    
        public TabsPagerAdapter(FragmentManager fm,SubmitPostActivity activity){
            super(fm);
        }
    
    
        @Override
           public Fragment getItem(int index) {
    
           switch(index) {
    
              case 0 : //PostInfoFragment
                         return new PostInfoFragment(0,activity);
    
              case 1 : //LocationInfoFragment
                        return new LocationInfoFragment(1,activity);
    
              case 2 : //PersonalInfoFragment
                         return new PersonalInfoFragment(2,activity);
    
            }
            return null;
        }
    
        @Override
        public int getCount() {       
           return 3;
        }
    
    }
    

    ViewPagerActivity -- >

    package com.jbandroid;
    
    public class SubmitPostActivity extends FragmentActivity implements ActionBar.TabListener,LocationInfoFragment.setLocationInfo{
    
        private ViewPager viewpager;
        private ActionBar actionBar;
        private TabsPagerAdapter mAdapter;
         FragmentManager manager;
         PersonalInfoFragment frag;
         List<String> location;
        /*private MenuItem myActionMenuItem;
          private Button myActionButton;*/
    
    
        //Tab titles
        private String[] tabs  = {"Post Info" , "Location Info" , "Personal Info" };
        public List<String> dataModel = new ArrayList<String>();
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.action_submit_post);
    
            viewpager = (ViewPager) findViewById(R.id.pager);
            actionBar = getActionBar();
            manager = getSupportFragmentManager();
            mAdapter = new TabsPagerAdapter(getSupportFragmentManager(),this);
            //viewpager.setOffscreenPageLimit(2);
            viewpager.setAdapter(mAdapter);
    
            //actionBar.setHomeButtonEnabled(false);
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    
            for (String tab : tabs){
                actionBar.addTab(actionBar.newTab().setText(tab).setTabListener(this));
            }
    
            if(savedInstanceState != null){
                actionBar.setSelectedNavigationItem( savedInstanceState.getInt("tab",0));
            }
    
        }
    
    }
    

    1st Fragment =>

    public class PostInfoFragment extends Fragment {
    
        private MenuItem myActionMenuItem;
        private Button myActionButton;
        private ActionBar actionBar;
        private String post_title, post_desc,post_status;
    
        private EditText submit_post_title, submit_post_desc;
        private int position;
        private Resources res;
    
        SubmitPostActivity callingActivity;
        List<String> post_details;
    
        public PostInfoFragment(int position,SubmitPostActivity callingActivity )
        {
            this.callingActivity = callingActivity;
            this.position = position;
        }
    
        //RelativeLayout rel_submit_post_start_date,rel_submit_post_end_date;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_post_info,
                    container, false);
    
            /*if(!imageLoader.isInited()){*/
            initImageLoader();
            /*}*/
    
            //handler = new Handler();
    
    
            submit_post_title = (EditText) rootView
                    .findViewById(R.id.submit_post_title);
            submit_post_desc = (EditText) rootView
                    .findViewById(R.id.submit_post_description);
    
            actionBar = getActivity().getActionBar();
            setHasOptionsMenu(true);
    
            post_details = new ArrayList<String>();
            res = getResources();
    
            setListeners();
    
            Log.d("postinfo_oncreate view", "postinfo_oncreate view");
    
            //this is editText onchange listner do the same for submit_post_desc as well
            submit_post_title.addTextChangedListener( new TextWatcher()
            {
    
                @Override
                public void onTextChanged( CharSequence s, int start, int before, int count )
                {
    
                }
    
                @Override
                public void beforeTextChanged( CharSequence s, int start, int count, int after )
                {
                }
    
                @Override
                public void afterTextChanged( Editable s )
                {
                    if( callingActivity != null )
                    {
                    //use this.position in order to update relevant data 
                        List<String> post_details = callingActivity.dataModel;
                        if( post_details == null )
                        {
                            post_details = new ArrayList<String>();
                        }
                        post_details.add(s.toString());
                    }
                }
            } );
    
    
            return rootView;
    
        }
    
        //making sure if the parent activity has implemented interface
        @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 {
                callingActivity = (SubmitPostActivity) activity;
            } catch (ClassCastException e) {
    
                throw new ClassCastException(activity.toString()
                        + "must implemet setPostInfo");
            }
    
             Log.d("postinfo_onattach", "postinfo_onattach");
        }
    }
    

    Please not that this may not compile as it is. Try to get the concept.

    0 讨论(0)
提交回复
热议问题