【问题标题】:Hidden Floating Action Button popping up in CoordinatorLayoutCoordinatorLayout 中弹出隐藏的浮动操作按钮
【发布时间】:2015-12-03 00:26:25
【问题描述】:

我有一个Activity 和一个ViewPager,它显示三个不同的片段。一切都在CoordinatorLayout 中。 我所做的基本上和这个答案一样:FAB animation with viewpager/tabslider

我不想在第一个 Fragment 中有 FAB,所以我在布局中将 FAB 的可见性设置为 GONE 并仅在选择第二个 Fragment 时显示/隐藏它。这部分实际上工作正常。

但是,当Activity 首次创建(或屏幕旋转)时,FAB 会在第一个Fragment 上快速弹出,这真的很烦人。 当我用其他东西替换 CoordinatorLayout 时,FAB 会在应该隐藏的时候保持隐藏。

我正在使用设计支持库 23.0.1。当 FAB 设置为消失时,cheesesquare 样本也有同样的问题。

有人可以为此提出解决方法吗?我找不到CoordinatorLayout 的来源,所以我找不到发生这种情况的原因。

【问题讨论】:

    标签: android android-viewpager material-design android-support-library floating-action-button


    【解决方案1】:

    这是我想出的代码(不,事先,它并不完美,也不是最优的。但它确实有效。随意优化你认为合适的)。稍后我会回来并将其清理到更优雅的程度,但为了让您快速找到答案,请继续。

    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
            }
        });
    }
    

    几点说明:

    showFabNormally();
    

    hideFabForever();
    

    仅当您的自定义行为弄乱了 FAB 的可见性时才需要。在这种情况下,我有一个自定义的 ScrollAwareFABBehavior,它会导致 FAB 在向下滚动时消失并在向上滚动时重新出现。您可以选择直接拨打电话

    floatingActionButton.show();
    

    floatingActionButton.hide();
    

    分别。我将行为代码留在其中以演示如何处理此问题,以便一个 FAB 可用于所有选项卡,即使自定义行为会影响其可见性。

    【讨论】:

    • 感谢您的意见。你的例子和我的几乎一样,并没有直接帮助我。但是我能够找到真正的问题:我没有为 FAB 设置布局锚!将锚点设置为 viewpager,FAB 不会在第一个片段上弹出。
    • 好!我认为对我来说关键是 onResume() 代码。它处理可见性检查,以便 FAB 保持其应有的选项卡方式。
    • 这应该不是问题,但谷歌没有解决它:code.google.com/p/android/issues/detail?id=27526
    猜你喜欢
    • 2016-07-27
    • 1970-01-01
    • 2018-12-01
    • 2020-05-28
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多