Hidden Floating Action Button popping up in CoordinatorLayout

痞子三分冷 提交于 2019-12-13 02:35:42

问题


I have an Activity with a ViewPager, which displays three different Fragments. Everything is inside a CoordinatorLayout. What I basically did is the same as in this answer: FAB animation with viewpager/tabslider

I don't want to have the FAB in the first Fragment, so I set the FAB's visibility to GONE in the layout and show/hide it only when the 2nd Fragment is selected. This part actually works fine.

However, when the Activity is first created(or the screen is rotated) the FAB pops up on the first Fragment for a quick moment, which is really annoying. When I replace the CoordinatorLayout with something else, the FAB stays hidden when it should.

I'm using the design support library 23.0.1. The cheesesquare sample is having the same issue, when the FAB is set to be gone.

Can someone suggest a workaround for this? I couldn't find the sources for the CoordinatorLayout, so I couldn't look for a reason why this happens.


回答1:


Here's the code I came up with (and no, in advance, it is not perfect, nor is it optimal. But it does work. Feel free to optimize as you see fit). I will come back and clean this up to a more elegant degree at a later date, but in interest of getting you an answer to work with quickly, here you go.

private ViewPager viewPager;
private SparseArray<View.OnClickListener> floatingActionButtonOnClickListeners;
private FloatingActionButton floatingActionButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    viewPager = (ViewPager) findViewById(R.id.viewpager);
    floatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
    setupTabs();
    setFABOnClickListeners();
}

@Override
protected void onResume() {
    super.onResume();
    setFabVisibility(viewPager.getCurrentItem());
}

private void setupTabs() {
    FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(adapter);
    tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);

    viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            setFabVisibility(viewPager.getCurrentItem());
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            switch (state) {
                case ViewPager.SCROLL_STATE_DRAGGING:
                    floatingActionButton.hide();
                    break;
            }
        }
    });
}

private void setFabVisibility(int position) {
    View.OnClickListener floatingActionButtonClickListener = floatingActionButtonClickListeners.get(position);

    floatingActionButton.setOnClickListener(floatingActionButtonClickListener);

    if (floatingActionButtonClickListener == null) {
        hideFabForever();
    } else {
        showFabNormally();
    }
}

private void hideFabForever() {
    ((CoordinatorLayout.LayoutParams) floatingActionButton.getLayoutParams()).setBehavior(new FloatingActionButton.Behavior());
    floatingActionButton.hide();
}

private void showFabNormally() {
    ((CoordinatorLayout.LayoutParams) floatingActionButton.getLayoutParams()).setBehavior(new ScrollAwareFABBehavior(this, null, new ScrollBehaviorListener() {
        @Override
        public void onAnimatedOut(View view) {
        }

        @Override
        public void onAnimatedIn(View view) {
        }
    }));

    floatingActionButton.show();
}

private void setFABOnClickListeners() {
    if (floatingActionButtonOnClickListeners == null) {
        floatingActionButtonOnClickListeners = new SparseArray<>();
    }

    // An example, but populate the SparseArray with the position of the tab
    // that should have a FAB. This will be used to indicate that the FAB 
    // should be visible on that position.
    floatingActionButtonOnClickListeners.put(0, new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO handle click
        }
    });

     floatingActionButtonOnClickListeners.put(2, new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO handle click
        }
    });

    floatingActionButtonOnClickListeners.put(4, new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO handle click
        }
    });
}

A couple of notes:

showFabNormally();

and

hideFabForever();

are ONLY necessary if you have a custom behavior that messes up the visibility of the FAB. In this case, I have a custom ScrollAwareFABBehavior that causes the FAB to disappear when scrolling down and reappear when scrolling back up. You can opt to just call

floatingActionButton.show();

and

floatingActionButton.hide();

respectively. I left the behavior code in there to demonstrate how to handle this so that one FAB can be used for all tabs, even if a custom behavior affects its visibility.



来源:https://stackoverflow.com/questions/32438819/hidden-floating-action-button-popping-up-in-coordinatorlayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!