Akeshwar Jha
Akeshwar Jha

Reputation: 4576

Go to next page in ViewPager

I have a ViewPager in my MainActivity. Every page in it is a Fragment. So, everytime I swipe right or left, a new instance of the fragment is created and the fragment view is updated accordingly.

I also have two buttons: LEFT and RIGHT for navigation. These buttons are inside the Fragment, not in the Activity. A user can either swipe or alternatively press the relevant button to navigate between the pages.

Here's the problem: Since I'm changing the views through my MainActivity, how do I detect the onClick events of those buttons in the Activity in order to update the fragment?

Here's the PagerAdapter class (Removed all the irrelevant code from everywhere):

public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {

        // logic part for the views.

        return PlaceholderFragment.newInstance(sectionNumber, questionStatus, questionOrder, showNext, showPrevious);
    }

And here's the PlaceHolderFragment class:

public class PlaceholderFragment extends Fragment{

    //some global variables

    public static PlaceholderFragment newInstance(int sectionNumber, int questionStatus, String questionOrder, boolean showNext, boolean showPrevious) {
        PlaceholderFragment fragment = new PlaceholderFragment();

        //setting up the arguments
        fragment.setArguments(args);
        return fragment;
    }

    public PlaceholderFragment() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.explanation_fragment, container, false);

        //code for filling up all the views

        RightButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //can I do something here?
            }
        });

        return rootView;
    }
}

MORE INFO: I have to keep the navigation buttons in the fragment itself and not in the activity.

Upvotes: 9

Views: 24288

Answers (7)

amir_a14
amir_a14

Reputation: 2060

Use kotlin extension functions:

fun ViewPager2.nextPage(smoothScroll: Boolean = true): Boolean {
    if ((currentItem + 1) < adapter?.itemCount ?: 0) {
        setCurrentItem(currentItem + 1, smoothScroll)
        return true
    }
    //can't move to next page, maybe current page is last or adapter not set.
    return false
}

fun ViewPager2.previousPage(smoothScroll: Boolean = true): Boolean {
    if ((currentItem - 1) >= 0) {
        setCurrentItem(currentItem - 1, smoothScroll)
        return true
    }
    //can't move to previous page, maybe current page is first or adapter not set.
    return false
}

Upvotes: 6

Kishan Solanki
Kishan Solanki

Reputation: 14618

For Kotlin and ViewPager2

previous page:

val currPos: Int = xyzViewPager.currentItem
if (currPos != 0) {
   xyzViewPager.currentItem = currPos - 1
}

next page:

val currPos: Int = xyzViewPager.currentItem
if ((currPos + 1) != xyzViewPager.adapter?.count) {
    xyzViewPager.currentItem = currPos + 1
}

Upvotes: 6

Farmaker
Farmaker

Reputation: 2790

You can send a broadcast upon button click inside the fragment like below:

Intent intent = new Intent();
        intent.setAction(NUMBER_OF_RECEIVER_NEXT);
        getActivity().sendBroadcast(intent);

Then in your main activity you catch the Intent and you set the current position of the pager to the desired number

private class broadcastReceived extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String actionGet = intent.getAction();
            if(actionGet.equals(NUMBER_OF_RECEIVER_NEXT)){

                mPager.setCurrentItem(1);
                Log.e("IntentNextPage","Received");
            }
        }
    }

Do not forget to set a

private static final String NUMBER_OF_RECEIVER_NEXT = "nextPage";

in both main activity and fragment and of course to register,unregister receiver to onResume and onPause methods.

Also add an intent filter to the receiver in onCreate methd with the action specified as NUMBER_OF_RECEIVER_NEXT

Upvotes: 0

Ram Prakash Bhat
Ram Prakash Bhat

Reputation: 1308

In your fragment write one interface like:

public class PlaceholderFragment extends Fragment{
        private OnButtonClickListener mOnButtonClickListener;

        interface OnButtonClickListener{
        void onButtonClicked(View view);
        }

        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            try {
                mOnButtonClickListener = (OnButtonClickListener) context;
            } catch (ClassCastException e) {
                throw new ClassCastException(((Activity) context).getLocalClassName()
                            + " must implement OnButtonClickListener");
            }
        }

        yourButtons.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mOnButtonClickListener.onButtonClicked(v);
            }
        });
     }   

And in your mainactivity:

class MainActivity extends AppCompatActivity implements   OnButtonClickListener{

    @Override
    void onButtonClicked(View view){
        int currPos=yourPager.getCurrentItem();

        switch(view.getId()){

            case R.id.leftNavigation:
            //handle currPos is zero
            yourPager.setCurrentItem(currPos-1);
            break;

            case R.id.rightNavigation:
            //handle currPos is reached last item
            yourPager.setCurrentItem(currPos+1);
            break;
        }
    }
}

Upvotes: 21

Shivam Satija
Shivam Satija

Reputation: 37

Make a public method in your activity

public void swipeRight(int x){
    if(x < totalNumberOfFragment){
        viewPager.setCurrentItem(x + 1);
    }
}

public void swipeLeft(int x){
    if(x > 0){
        viewPager.setCurrentItem(x - 1);
    }
}

You can call these method from your fragment button's click action

RightButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Yes 
            ((YourActivityClassName)getActivity()).swipeRight(position);
        }
    });

And do same for LeftButton

YourActivityClassName - Activity which is holding this viewPager fragment.

position - position of your current fragment.

Upvotes: 3

Oleksandr Berdnikov
Oleksandr Berdnikov

Reputation: 679

You can create special method in your parent Activity like following:

public class PagerActiviy extends Activity {
    ...
    public void onFragmentNavigationButtonClick(View button) {
        // Do your stuff here
    }
    ...
}

Then in your fragments you can get your parent Activity with getActivity() method, cast it to the actual type and call the method:

public class PlaceholderFragment extends Fragment{

...
...

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.explanation_fragment, container, false);

        //code for filling up all the views

        RightButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((PagerActvity) getActivity()).onFragmentNavigationButtonClick(v);
            }
        });

        return rootView;
    }
}

As a side note I should add that from your example it's not clear why do you need to keep your navigation buttons in the fragments and can't move them to the Activity and manage them there.

Upvotes: 0

Nikhil
Nikhil

Reputation: 3711

You can add button in your activities xml as follows

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" >

        <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        </android.support.v4.view.ViewPager>
    </LinearLayout>

    <ImageView
        android:id="@+id/leftNavigation"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:padding="10dp"
        android:src="@drawable/ic_chevron_left_black_24dp"
        android:visibility="gone" />

    <ImageView
        android:id="@+id/rightNavigation"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:layout_weight="0"
        android:gravity="center"
        android:padding="10dp"
        android:src="@drawable/ic_chevron_right_black_24dp" />
  </FrameLayout>

Upvotes: 0

Related Questions