Sanvywell Sanvywell - 1 year ago 70
Android Question

Confused about setTranslationX() when translating FloatingActionButton on ViewPager scroll

I have some tabs in a

. Each tab except the last displays the
at the bottom right corner. The last tab is supposed to display it in the bottom center, after translating it while this tab is being scrolled to. When scrolling away from this tab, the
translates back into its bottom right position. I was implementing a solution, and was surprised to find that this, more or less, was all it took:

mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// One page away from last page
if (position == mAdapter.getCount() - 2) {
mFab.setTranslationX(positionOffsetPixels / -2f);

When I scroll to the last tab, we're translating the FAB to the left of its current position, because the argument passed to
is negative. Now, here's where I'm confused. When I scroll back one page, the FAB translates back to the right as desired--but how can this be? The argument to
is still negative. I expected the FAB to translate further left.

Answer Source

When you're scrolling forward from the position mAdapter.getCount() - 2, the values of positionOffsetPixels will be increasing positive numbers and positionOffsetPixels / -2f will be increasing negative numbers, so the FAB will translate to the left, as expected.

From the documentation of position:

Position index of the first page currently being displayed.

This means when scrolling back, the offset values will be relative to the page you're scrolling to, not to the page you're scrolling from.

When you're scrolling back from mAdapter.getCount() - 1, the value of position is mAdapter.getCount() - 2 (this is the position you're scrolling to) and the values of positionOffsetPixels will be decreasing positive numbers going down to 0.

0 / -2f == 0, so eventually mFab.setTranslationX(0) will be called, returning the FAB to its original position.