Search code examples
androidandroid-viewpagerswipe-gestureandroid-pageradapter

Get Values from views inflated in a PagerAdapter


I have an Activity with a ViewPager and a custom adapter that implements the PagerAdaper. I am inflating a view inside the PagerAdapter and adding sub views to the parent view. These sub views are RadioGroup, Checkboxes, EditText etc. depending upon a certain parameter of the object of whose list I pass to the adapter.

I want to get the values from these sub views once the page is changed. But since my inflation code is in the adapter, I need to know how can I detect the page change from my adapter itself.

Here is my code for the adapter :-

 public override Java.Lang.Object InstantiateItem(ViewGroup container, int position)
        {
            var view = voteFormActivity.LayoutInflater.Inflate(Resource.Layout.active_votes_layout, container, false);
            txtvoteTitle = view.FindViewById<TextView>(Resource.Id.txtTitle);
            //radioGroup = view.FindViewById<RadioGroup>(Resource.Id.radioGroupChoice);
            btnSubmit = view.FindViewById<Button>(Resource.Id.btnSubmit);
            layoutForcomponents = view.FindViewById<LinearLayout>(Resource.Id.layoutForComponents);


            radioGroup = new RadioGroup(voteFormActivity);

            var data = selectedVotes.ElementAt(position);



            if (data != null)
            {
                if (!string.IsNullOrEmpty(data.Title))
                {
                    txtvoteTitle.Text = data.Title;
                }


                var choiceList = data.Choices;

                if (choiceList != null && choiceList.Count > 0)
                {
                    if (checkParam == "RadioChoice")
                    {
                        foreach (var choice in choiceList)
                        {
                            RadioButton rButton = new RadioButton(voteFormActivity);
                            rButton.Text = choice;
                            radioGroup.AddView(rButton);
                            layoutForcomponents.RemoveAllViews();
                            layoutForcomponents.AddView(radioGroup);
                        }
                    }
                    else if (checkParam == "CheckBoxChoice")
                    {
                        foreach (var choice in choiceList)
                        {
                            CheckBox cButton = new CheckBox(voteFormActivity);
                            cButton.Text = choice;
                            radioGroup.AddView(cButton);
                            layoutForcomponents.RemoveAllViews();

                            layoutForcomponents.AddView(radioGroup);

                        }
                    }

                }
                //if (checkParam == "MultiLineText")
                else{
                    EditText etMultilineText = new EditText(voteFormActivity);
                    etMultilineText.Hint = "Enter feedback";
                    etMultilineText.SetLines(6);
                    layoutForcomponents.RemoveAllViews();

                    layoutForcomponents.AddView(etMultilineText);
                }
            }
            container.AddView(view);
            return view;
        }

I pass the adapter to my ViewPager as follows:-

mViewPager.Adapter = new PollViewPagerAdapter(this, this.FragmentManager, AppHelper.SelectedVotes);

How can I detect the page change and get the values from the RadioGroup, Checkbox and EditText ? Any help is appreciated.


Solution

  • You don't need to know when a page is scrolled inside the adapter. You can assign a page scrolled listener to the pager like this:

    viewPager.setOnPageChangeListener(object : OnPageChangeListener {
            override fun onPageScrollStateChanged(state: Int) {}
            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
            override fun onPageSelected(position: Int) {}
        })
    

    I'd keep the logic outside the adapter. You can make even an interface between your Activity/Fragment and your Adapter to listen to events like radiogroup state changes and stuff like that.

    Edit

    Let me try to elaborate further. There's no correct answer to your question. You can implement this sort of behavior in many ways. Let's suppose you've got a radiogroup in your adapter with a checked change listener. Inside the checked change method you can call some interface method you defined inside the adapter for example.

    interface RadioChangedListener{
        fun radioChanged(radioId: Int)
    }
    

    Define this interface inside the adapter and make your fragment/activity implement it. Then declare the adapter passing it the activity/fragment in the constructor as a radioChangedListener object:

    class YourAdapter(var listItems: MutableList<YourItem>, val yourListener: RadioChangedListener)
    : RecyclerView.Adapter<YourAdapter.YourHolder>() {
    
    //...adapter code
    
    }
    

    Finally, in your radiogroup listener you can call your interface method like so (giving you the Java code for this cause I'm lazy):

    RadioGroup radioGroup = (RadioGroup) findViewById(R.id.yourRadioGroup);        
    radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() 
    {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            yourListener.radioChanged(checkedId)
        }
    });
    

    This will trigger your radioChanged method inside the activity, in which you can store your value.