In CrimePagerActivity.java, I used the “setCurrentItem” method of ViewPager to find the first and last items and set the button logic to perform this. I also implemented “onPageScrolled” for mViewPager to make the respective buttons invisible if it was the first or last crime:
My main question is, was this the optimal approach?
Also, is there any difference to using “mViewPager.getAdapter().getCount()” or “mCrimes.size() - 1”. I used both here and they seemed to work equally.
There is a bug in your code. If you go to crime #98 and then swipe right to go to crime #99 the Last button will still be there. This is because mViewPager.getAdapter().getCount() returns the full count of the dataset in the adapter which will be 1 more than the last position.
To fix it just change the line: mViewPager.getAdapter().getCount() to mViewPager.getAdapter().getCount() - 1
Instead of using the ViewPager.OnPageChangeListener interface, you can create a private class which extends ViewPager.SimpleOnPageChangeListener. This way you can override any of the original interface methods, without leaving the other ones unimplemented.
Both solutions work, but showing unimplemented methods is quite ugly in my opinion Just a small thing, but maybe it helps someone cleaning up their code.
PS. You asked: “Also, is there any difference to using “mViewPager.getAdapter().getCount()” or “mCrimes.size() - 1”. I used both here and they seemed to work equally.” There’s no difference between the two, since the mViewPager count is set by the size of mCrimes.
Hey. I don’t know if this helps, but there’s also the ViewPager.SimpleOnPageChangeListener class.
it’s already implemented the interface methods and you can just overwrite the ones you need to. hth
For the layout, I used an outer LinearLayout (vertical orientation) containing the ViewPager and then a ConstraintLayout for the buttons at the bottom left and right corners of the screen:
For the logic, I did not need to implement any new methods, just wire up the buttons and add an instance variable to keep track of the last index. In CrimePagerActivity, I added
private Button mJumpToFirstButton;
private Button mJumpToLastButton;
private int lastIndex;
In OnCreate I added:
// Hook up previous and next buttons
lastIndex = mCrimes.size() - 1;
mJumpToFirstButton = findViewById(R.id.jump_to_first_button);
mJumpToLastButton = findViewById(R.id.jump_to_last_button);
mJumpToFirstButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mViewPager.setCurrentItem(0, true);
toggleButtons();
}
});
mJumpToLastButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mViewPager.setCurrentItem(lastIndex, true);
toggleButtons();
}
});
You just need the toggleButtons() call when either button is clicked, after changing out the content, and then in the adapter’s getItem() method (when swiping left or right).
The only thing that doesn’t work with my solution is that when you swipe all the way to the beginning or end, it doesn’t disable the button to jump to the beginning or end. However, when you press those buttons they do get disabled, not that it really matters.
Also you can use this code in addition, so that the button is disabled if you first click on 0 or 99 item.
for(int i = 0; i < mCrimes.size(); i++){
if(mCrimes.get(i).getId().equals(crimeId)){
mViewPager.setCurrentItem(i);
if(i == 0)
mFirstButton.setEnabled(false); //for the first occurence
else
mFirstButton.setEnabled(true);
if(i == mCrimes.size()-1)
mLastButton.setEnabled(false); //for the first occurence
else
mLastButton.setEnabled(true);
break;
}
}