ListView in a Fragment when ItemClick for detail what must be scenario

wonderWomanwonderWoman USMember
edited May 2014 in Xamarin.Android

Project have got 4 tabs in actionbar and i call fragments in my container programmatically. Second tab open Product fragment with a listview. i want to learn what must i do, when click a product list item what must be my way. in example item click and go for product detail a Activity or a Fragment.

if it must go Fragment how can i send product ID in new fragment and how can i replace my fragment container ?

thank you.

Best Answer

  • CheesebaronCheesebaron DK mod
    edited May 2014 Accepted Answer

    I would implement a EventHandler in the Fragment with your ListView, which fires when you press an item in the ListView. Then you can subscribe to it in your FragmentActivity and react accordingly when you get an Id or whatever you pass in the EventArgs in the EventHandler.

    So something in the lines of:

    public delegate EventHandler<MyEventArgs> MyEventHandler(object sender, MyEventArgs args);
    
    public class MyEventArgs : EventArgs
    {
        public int Id { get; set; }
    }
    
    public class MyFragment : Fragment
    {
        public event MyEventHandler OnListViewClick;
        private List<ListItem> _items;
    
        public MyFragment(List<ListItem> items) { _items = items; }
    
        public override View OnCreateView(LayoutInflater inf, ViewGroup cont, Bundle bundle)
        {
            var view = inf.Inflate(Resource.Layout.myListViewLayout, cont, false);
    
            var adapter = new MyListAdapter(Activity, _items);
            var listView = view.FindViewById<listView>(Resource.Id.listView);
            listView.Adapter = adapter;
            listView.ItemClick += (s, e) => {
                if (OnListViewClick != null)
                    OnListViewClick(this, new MyEventArgs { 
                        Id = _items[e.Position].Id 
                    });
            };
    
            return view;
        }
    }
    

    Then somewhere in your Activity or where you instantiate the Fragment you just subscibe to the OnListViewClick event like:

    frag.OnListViewClick += (s, e) => {
        // change Activity or Fragment here, get Id with: e.Id
    };
    

    where frag is an instance of your Fragment.

    Haven't tested this code, just wrote it from memory but it should work without major corrections.

Answers

  • CheesebaronCheesebaron DKInsider, University mod
    edited May 2014 Accepted Answer

    I would implement a EventHandler in the Fragment with your ListView, which fires when you press an item in the ListView. Then you can subscribe to it in your FragmentActivity and react accordingly when you get an Id or whatever you pass in the EventArgs in the EventHandler.

    So something in the lines of:

    public delegate EventHandler<MyEventArgs> MyEventHandler(object sender, MyEventArgs args);
    
    public class MyEventArgs : EventArgs
    {
        public int Id { get; set; }
    }
    
    public class MyFragment : Fragment
    {
        public event MyEventHandler OnListViewClick;
        private List<ListItem> _items;
    
        public MyFragment(List<ListItem> items) { _items = items; }
    
        public override View OnCreateView(LayoutInflater inf, ViewGroup cont, Bundle bundle)
        {
            var view = inf.Inflate(Resource.Layout.myListViewLayout, cont, false);
    
            var adapter = new MyListAdapter(Activity, _items);
            var listView = view.FindViewById<listView>(Resource.Id.listView);
            listView.Adapter = adapter;
            listView.ItemClick += (s, e) => {
                if (OnListViewClick != null)
                    OnListViewClick(this, new MyEventArgs { 
                        Id = _items[e.Position].Id 
                    });
            };
    
            return view;
        }
    }
    

    Then somewhere in your Activity or where you instantiate the Fragment you just subscibe to the OnListViewClick event like:

    frag.OnListViewClick += (s, e) => {
        // change Activity or Fragment here, get Id with: e.Id
    };
    

    where frag is an instance of your Fragment.

    Haven't tested this code, just wrote it from memory but it should work without major corrections.

  • wonderWomanwonderWoman USMember

    Thank you Cheesebaron you give me a good idea for that. i write something like that and it is working good but not perfect ))

    i write in Pruduct fragment this code

    this.ListView.ItemClick += (s, e) =>
                {
                    var _programDetailFragment = new ProgramDetail() { Arguments = new Bundle() };
                    _programDetailFragment.Arguments.PutString("PID", _data[e.Position].id);
                    FragmentTransaction ft = this.Activity.FragmentManager.BeginTransaction();
                    ft.Replace(Resource.Id.fragmentContainer, _programDetailFragment);
                    ft.Commit();
                };
    

    and i get my program id in ProgramDetail fragment like that

    public string myPID
            {
                get { return Arguments.GetString("PID", "0"); }
            }
    

    and i use it for get my data from json. but when item click and replace Product Fragment to ProductDetail Fragment actionbar tab not change. it stay always selected. i want to click again product tab but Product Fragment not load in container. what can i do for that ?

  • CheesebaronCheesebaron DKInsider, University mod

    What should change in the ActionBar? Also I would personally prefer not to do any transactions inside the Fragment itself making it less coupled and reusable.

  • wonderWomanwonderWoman USMember

    ok i see. i do it with TabReselected function. thank you again.

  • aurangzebaurangzeb USMember

    HI .

    I want to open new fragment on ltemclick but i am not be able to get a new fragment.
    any one help me

    Thanks in advance

    public override Android.Views.View OnCreateView (Android.Views.LayoutInflater inflater, Android.Views.ViewGroup container, Bundle savedInstanceState)
            {
            var root = inflater.Inflate(Resource.Layout.fragment_card, container, false);
    
            var _listview =  root.FindViewById<ListView> (Resource.Id.listView1);
    
            _medicineadapter = new MedicineAdapter (MainActivity.context ,list());
                _listview.Adapter = _medicineadapter;   
    
    
    
    
            _listview.ItemClick += (s,args) => selectitem(args.Position);
    
    
            return root;
        }
        public void selectitem(int position)
        {
            var fragment = new FragmentSub();
            FragmentTransaction fm = this.FragmentManager.BeginTransaction ();
            var fb = new FragmentSub ();
            fm.Replace (Resource.Id.content_frame2, fragment);
            fm.Commit;
        }
    
Sign In or Register to comment.