How to pass data between fragments

后端 未结 13 2794
醉话见心
醉话见心 2020-11-22 07:03

Im trying to pass data between two fragmens in my program. Its just a simple string that is stored in the List. The List is made public in fragments A, and when the user cli

相关标签:
13条回答
  • 2020-11-22 07:27

    That depends on how the fragment is structured. If you can have some of the methods on the Fragment Class B static and also the target TextView object static, you can call the method directly on Fragment Class A. This is better than a listener as the method is performed instantaneously, and we don't need to have an additional task that performs listening throughout the activity. See example below:

    Fragment_class_B.setmyText(String yourstring);
    

    On Fragment B you can have the method defined as:

    public static void setmyText(final String string) {
    myTextView.setText(string);
    }
    

    Just don't forget to have myTextView set as static on Fragment B, and properly import the Fragment B class on Fragment A.

    Just did the procedure on my project recently and it worked. Hope that helped.

    0 讨论(0)
  • 2020-11-22 07:28

    getParentFragmentManager().setFragmentResultListener is the 2020 way of doing this. Your only limitation is to use a bundle to pass the data. Check out the docs for more info and examples.

    Some other ways

    • Call to getActivity() and cast it to the shared activity between your fragments, then use it as a bridge to pass the data. This solution is highly not recommended because of the cupelling it requires between the activity and the fragments, but it used to be the popular way of doing this back in the KitKat days...
    • Use callbacks. Any events mechanism will do. This would be a Java vanilla solution. The benefit over FragmentManager is that it's not limited to Bundles. The downside, however, is that you may run into edge cases bugs where you mess up the activity life cycle and get exceptions like IllegalStateException when the fragment manager is in the middle of saving state or the activity were destroyed. Also, it does not support cross-processing communication.
    0 讨论(0)
  • 2020-11-22 07:30

    If you use Roboguice you can use the EventManager in Roboguice to pass data around without using the Activity as an interface. This is quite clean IMO.

    If you're not using Roboguice you can use Otto too as a event bus: http://square.github.com/otto/

    Update 20150909: You can also use Green Robot Event Bus or even RxJava now too. Depends on your use case.

    0 讨论(0)
  • 2020-11-22 07:30

    So lets say you have Activity AB that controls Frag A and Fragment B. Inside Fragment A you need an interface that Activity AB can implement. In the sample android code, they have:

    private Callbacks mCallbacks = sDummyCallbacks;

    /*A callback interface that all activities containing this fragment must implement. This mechanism allows activities to be notified of item selections. */

    public interface Callbacks {
    /*Callback for when an item has been selected. */    
          public void onItemSelected(String id);
    }
    
    /*A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity. */    
    private static Callbacks sDummyCallbacks = new Callbacks() {
        @Override
        public void onItemSelected(String id) {
        }
    };
    

    The Callback interface is put inside one of your Fragments (let’s say Fragment A). I think the purpose of this Callbacks interface is like a nested class inside Frag A which any Activity can implement. So if Fragment A was a TV, the CallBacks is the TV Remote (interface) that allows Fragment A to be used by Activity AB. I may be wrong about the detail because I'm a noob but I did get my program to work perfectly on all screen sizes and this is what I used.

    So inside Fragment A, we have: (I took this from Android’s Sample programs)

    @Override
    public void onListItemClick(ListView listView, View view, int position, long id) {
    super.onListItemClick(listView, view, position, id);
    // Notify the active callbacks interface (the activity, if the
    // fragment is attached to one) that an item has been selected.
    mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
    //mCallbacks.onItemSelected( PUT YOUR SHIT HERE. int, String, etc.);
    //mCallbacks.onItemSelected (Object);
    }
    

    And inside Activity AB we override the onItemSelected method:

    public class AB extends FragmentActivity implements ItemListFragment.Callbacks {
    //...
    @Override
    //public void onItemSelected (CATCH YOUR SHIT HERE) {
    //public void onItemSelected (Object obj) {
        public void onItemSelected(String id) {
        //Pass Data to Fragment B. For example:
        Bundle arguments = new Bundle();
        arguments.putString(“FragmentB_package”, id);
        FragmentB fragment = new FragmentB();
        fragment.setArguments(arguments);
        getSupportFragmentManager().beginTransaction().replace(R.id.item_detail_container, fragment).commit();
        }
    

    So inside Activity AB, you basically throwing everything into a Bundle and passing it to B. If u are not sure how to use a Bundle, look the class up.

    I am basically going by the sample code that Android provided. The one with the DummyContent stuff. When you make a new Android Application Package, it's the one titled MasterDetailFlow.

    0 讨论(0)
  • 2020-11-22 07:30

    Fragment class A

    public class CountryListFragment extends ListFragment{
    
        /** List of countries to be displayed in the ListFragment */
    
        ListFragmentItemClickListener ifaceItemClickListener;   
    
        /** An interface for defining the callback method */
        public interface ListFragmentItemClickListener {
        /** This method will be invoked when an item in the ListFragment is clicked */
        void onListFragmentItemClick(int position);
    }   
    
    /** A callback function, executed when this fragment is attached to an activity */  
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    
        try{
            /** This statement ensures that the hosting activity implements ListFragmentItemClickListener */
            ifaceItemClickListener = (ListFragmentItemClickListener) activity;          
        }catch(Exception e){
            Toast.makeText(activity.getBaseContext(), "Exception",Toast.LENGTH_SHORT).show();
        }
    }
    

    Fragment Class B

    public class CountryDetailsFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
        /** Inflating the layout country_details_fragment_layout to the view object v */
        View v = inflater.inflate(R.layout.country_details_fragment_layout, null);
    
        /** Getting the textview object of the layout to set the details */ 
        TextView tv = (TextView) v.findViewById(R.id.country_details);      
    
        /** Getting the bundle object passed from MainActivity ( in Landscape   mode )  or from 
         *  CountryDetailsActivity ( in Portrait Mode )  
         * */
        Bundle b = getArguments();
    
        /** Getting the clicked item's position and setting corresponding  details in the textview of the detailed fragment */
        tv.setText("Details of " + Country.name[b.getInt("position")]);     
    
        return v;
        }
    
    }
    

    Main Activity class for passing data between fragments

    public class MainActivity extends Activity implements ListFragmentItemClickListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
    
    /** This method will be executed when the user clicks on an item in the listview */
    @Override
    public void onListFragmentItemClick(int position) {
    
        /** Getting the orientation ( Landscape or Portrait ) of the screen */
        int orientation = getResources().getConfiguration().orientation;
    
    
        /** Landscape Mode */
        if(orientation == Configuration.ORIENTATION_LANDSCAPE ){
            /** Getting the fragment manager for fragment related operations */
            FragmentManager fragmentManager = getFragmentManager();
    
            /** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
            /** Getting the existing detailed fragment object, if it already exists. 
             *  The fragment object is retrieved by its tag name  *
             */
    Fragment prevFrag = fragmentManager.findFragmentByTag("in.wptrafficanalyzer.country.details");
    
            /** Remove the existing detailed fragment object if it exists */
            if(prevFrag!=null)
        fragmentTransaction.remove(prevFrag);           
    
            /** Instantiating the fragment CountryDetailsFragment */
      CountryDetailsFragment fragment = new CountryDetailsFragment();
    
            /** Creating a bundle object to pass the data(the clicked item's   position) from the activity to the fragment */ 
            Bundle b = new Bundle();
    
            /** Setting the data to the bundle object */
            b.putInt("position", position);
    
            /** Setting the bundle object to the fragment */
            fragment.setArguments(b);           
    
            /** Adding the fragment to the fragment transaction */
            fragmentTransaction.add(R.id.detail_fragment_container,   fragment,"in.wptrafficanalyzer.country.details");
    
            /** Adding this transaction to backstack */
            fragmentTransaction.addToBackStack(null);
    
            /** Making this transaction in effect */
            fragmentTransaction.commit();
    
        }else{          /** Portrait Mode or Square mode */
            /** Creating an intent object to start the CountryDetailsActivity */
            Intent intent = new Intent("in.wptrafficanalyzer.CountryDetailsActivity");
    
            /** Setting data ( the clicked item's position ) to this intent */
            intent.putExtra("position", position);
    
            /** Starting the activity by passing the implicit intent */
            startActivity(intent);          
          }
        }
     }
    

    Detailde acitivity class

    public class CountryDetailsActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        /** Setting the layout for this activity */
        setContentView(R.layout.country_details_activity_layout);
    
        /** Getting the fragment manager for fragment related operations */
        FragmentManager fragmentManager = getFragmentManager();
    
        /** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */
        FragmentTransaction fragmentTransacton = fragmentManager.beginTransaction();
    
        /** Instantiating the fragment CountryDetailsFragment */
        CountryDetailsFragment detailsFragment = new CountryDetailsFragment();
    
        /** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */
        Bundle b = new Bundle();
    
        /** Setting the data to the bundle object from the Intent*/
        b.putInt("position", getIntent().getIntExtra("position", 0));
    
        /** Setting the bundle object to the fragment */
        detailsFragment.setArguments(b);
    
        /** Adding the fragment to the fragment transaction */
        fragmentTransacton.add(R.id.country_details_fragment_container, detailsFragment);       
    
        /** Making this transaction in effect */
        fragmentTransacton.commit();
    
        }
    }
    

    Array Of Contries

    public class Country {
    
    /** Array of countries used to display in CountryListFragment */
    static String name[] = new String[] {
            "India",
            "Pakistan",
            "Sri Lanka",
            "China",
            "Bangladesh",
            "Nepal",
            "Afghanistan",
            "North Korea",
            "South Korea",
            "Japan",
            "Bhutan"
    };
    }
    

    For More Details visit this link [http://wptrafficanalyzer.in/blog/itemclick-handler-for-listfragment-in-android/]. There are full example ..

    0 讨论(0)
  • 2020-11-22 07:32

    Why don't you use a Bundle. From your first fragment, here's how to set it up:

    Fragment fragment = new Fragment();
    Bundle bundle = new Bundle();
    bundle.putInt(key, value);
    fragment.setArguments(bundle);
    

    Then in your second Fragment, retrieve the data using:

    Bundle bundle = this.getArguments();
    int myInt = bundle.getInt(key, defaultValue);
    

    Bundle has put methods for lots of data types. Please see http://developer.android.com/reference/android/os/Bundle.html

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