1

我有一个Activity,其中ViewPager显示了三个不同的片段。一切都在CoordinatorLayout之内。 我主要做的是相同这样的回答:FAB animation with viewpager/tabslider在CoordinatorLayout中弹出的隐藏浮动动作按钮

我不希望有FAB在第一Fragment,所以我在布局和显示设置FAB的知名度GONE /隐藏它,只有当第二个Fragment被选中。这部分实际上工作正常。

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

我正在使用设计支持库23.0.1。当FAB被设置为不存在时,cheesesquare样本存在相同的问题。

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

回答

2

下面是我想出的代码(事先并不提前,它并不完美,也不是最优的,但它确实有效,随意随意地按照您认为合适的方式进行优化)。我会在稍后的日子回来清理这个问题,但为了让您快速找到答案,请点击此处。

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,即使自定义行为影响其可见性。

+0

感谢您的意见。你的例子和我的几乎一样,并没有直接帮助我。但是我能够发现真正的问题:我没有为FAB设置布局锚点!将锚点设置为viewpager时,FAB不会在第一个片段上弹出。 – MatF

+0

好!我认为我的关键是onResume()位代码。它处理可见性检查,以便FAB保持它对标签的应用。 –

+0

这应该不是问题,但谷歌并没有解决它:https://code.google.com/p/android/issues/detail?id=27526 – MatF