简体   繁体   中英

Send data from one fragment to another fragment in xamarin.android

I am trying to do an application with Xamarin.android. It is "ToDoList" and I have two tabs, one of them is to create and edit the chores(it is called "undone"). The other one is for the chores that are marked as done(it is called done). I have used Fragments for the tabs and what I am trying to accomplish is when I mark one task as done I want to delete it from the list in the "undone" tab and add one to the list in "done" tab.

MainActivity.cs

public class MainActivity : Activity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
            base.OnCreate(savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);

            this.ActionBar.NavigationMode = ActionBarNavigationMode.Tabs;


            var tab1 = ActionBar.NewTab();
            tab1.SetText("Undone");
            var tabFirst = new UndoneListFragment();
            tab1.TabSelected += (sender, e) =>
            {
                var fragment = this.FragmentManager.FindFragmentById(Resource.Id.tabsContainer);

                if (fragment != null)
                    e.FragmentTransaction.Remove(fragment);

                e.FragmentTransaction.Add(Resource.Id.tabsContainer, tabFirst);
            };

            tab1.TabUnselected += (sender, e) =>
            {
                e.FragmentTransaction.Remove(tabFirst);
            };


            var tab2 = ActionBar.NewTab();
            tab2.SetText("Done");
            var tabSecond = new DoneListFragment();
            tab2.TabSelected += (sender, e) =>
            {
                var fragment = this.FragmentManager.FindFragmentById(Resource.Id.tabsContainer);

                if (fragment != null)
                    e.FragmentTransaction.Remove(fragment);

                e.FragmentTransaction.Add(Resource.Id.tabsContainer, tabSecond);
            };

            tab2.TabUnselected += (sender, e) =>
            {
                e.FragmentTransaction.Remove(tabSecond);
            };

            ActionBar.AddTab(tab1);
            ActionBar.AddTab(tab2);

      }
}  

UndoneListFragment.cs

public class UndoneListFragment : Fragment
{
    List<Task> tasks = new List<Task>();
    ListView lView;

    TasksViewAdapter adapter;
    View view;

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {

            // Use this to return your custom view for this Fragment
            // return inflater.Inflate(Resource.Layout.YourFragment, container, false);

            base.OnCreateView(inflater, container, savedInstanceState);

            view = inflater.Inflate(Resource.Layout.undoneListView, container, false);

            Button addBtn = view.FindViewById<Button>(Resource.Id.AddBtn);
            lView = view.FindViewById<ListView>(Resource.Id.TasksViewList);



            adapter = new TasksViewAdapter(view.Context, tasks);

            lView.Adapter = adapter;
            lView.ItemClick += Edit;

            addBtn.Click += AddTask;
            return view;
    }
}

public override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
      base.OnActivityResult(requestCode, resultCode, data);

      switch (requestCode)
      {

                case 10:
                    if (resultCode == Result.Ok)   //Edit an already existing task
                    {
                        var replacedTaskName = data.GetStringExtra("new_name" ?? "Name not found");
                        var position = data.GetIntExtra("listPos", 0);
                        bool done = data.GetBooleanExtra("done", false);

                        Task t = new Task(replacedTaskName);

                        if (done == true)
                        {
                            t.TaskStatus = Status.Done;

                             //here I want to implement the code to somehow  

                             //send the replacesTaskName to the second fragment

                            //Your suggestion is here
                            DoneListFragment frag = new DoneListFragment();
                            Bundle b = new Bundle();
                            b.PutString("MyKey",replacedTaskName);
                            frag.Arguments = b;

                        }

                        tasks[position] = t;
                        adapter.NotifyDataSetChanged();
                        string newName = tasks[position].TaskName;
                        break;
                    }
      }
}  

DoneListFragment.cs

public class DoneListFragment : Fragment
{
    List<Task> doneTasks = new List<Task>();
    ListView lView;
    TasksViewAdapter adapter;
    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {

            base.OnCreateView(inflater, container, savedInstanceState);
            var view = inflater.Inflate(Resource.Layout.doneListView, container, false);

            Button deleteBtn = view.FindViewById<Button>(Resource.Id.DeleteAllBtn);
            lView = view.FindViewById<ListView>(Resource.Id.doneList);


            adapter = new TasksViewAdapter(view.Context, doneTasks);
            lView.Adapter = adapter;

            if(Arguments != null)
            {
                string value= Arguments.GetString("MyKey");

            }

            //click to delete done tasks
            deleteBtn.Click += DeleteAll;

            return view;
    }
}

For Sending data from one fragment another one simple step is creating constructor while replacing the fragment or calling fragment.

For Example:

Suppose I have two fragments ,

  1. ActionFragment

  2. ActionDetailsFragment

Now I want to send data from “ActionFragment” to “ActionDetailsFragment”:

In ActionFragment :

fragmentManager = getChildFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frameLayoutActionDetails, new ActionDetailsFragment(Data x, Data y)).commitAllowingStateLoss( );

Now below code will be in “ActionDetailsFragment”

public class ActionDetailsFragment extends AppFragment {
Data x;
Data y;

    public ActionDetailsFragment(Data x, Data y) {
        super();
        this.x = x;
        this.y = y;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        —————————————
////———Here is your code———————
—————————————————

}

Now you can use “Data x, Data y” in ActionDetailsFragment… Thats it…

Note: Data x and Data y both are imaginary variables..

Activity's cannot use in TabLayout or ViewPager you must have to use Fragments . You can use “Bundle” instead,

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

Then in your Fragment, retrieve the data (eg in onCreate() method) with:

Bundle bundle = this.getArguments();
if (bundle != null) {
        int myInt = bundle.getInt(key, defaultValue);

}

Well if you are looking for Fragment to Fragment data transfer the smart way of doing it would be using fragment arguments, Something like this:

  • When you initialize the fragment object in your case:

     var frag= new DoneListFragment(); Bundle bundle= new Bundle(); bundle.PutString("YourKey", "YourValue"); frag.Arguments=bundle; 
  • Then to retrieve this data you do something like this in DoneListFragment in the OnCreateView method:

     if(Arguments!=null) { String value = Arguments.GetString("YourKey"); } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM