1

У меня есть Activity с ViewPager, в котором отображаются три разных фрагмента. Все находится внутри CoordinatorLayout. То, что я в основном делали то же самое, что и в этом ответе: FAB animation with viewpager/tabsliderСкрытая плавающая кнопка действия появляется в координатореLayout

Я не хочу иметь FAB в первом Fragment, поэтому я видимость ФАБ к GONE в макете и показать/скрыть их только тогда, когда выбирается второй Fragment. Эта часть работает отлично.

Однако, когда сначала создается Activity (или экран повернут), FAB появляется на первом Fragment на мгновение, что очень раздражает. Когда я заменяю CoordinatorLayout чем-то другим, FAB остается скрытым, когда он должен.

Я использую библиотеку поддержки дизайна 23.0.1. Образец cheesesquare имеет ту же проблему, когда FAB настроен на исчезновение.

Может кто-нибудь предложить обходное решение для этого? Я не мог найти источники для 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(); 

ТОЛЬКО необходимо, если у вас есть пользовательское поведение, которое портит видимость ФАБ. В этом случае у меня есть обычное ScrollAwareFABBehavior, которое заставляет FAB исчезать при прокрутке вниз и снова появляться при прокрутке назад. Вы можете выбрать, чтобы просто позвонить

floatingActionButton.show(); 

и

floatingActionButton.hide(); 

соответственно. Я оставил код поведения там, чтобы продемонстрировать, как справиться с этим, чтобы один FAB мог использоваться для всех вкладок, даже если пользовательское поведение влияет на его видимость.

+0

Благодарим вас за ввод. Ваш пример почти такой же, как мой, и мне прямо не помог. Однако мне удалось найти реальную проблему: я не установил якорь для FAB! Когда привязка установлена ​​к viewpager, FAB не появляется на первом фрагменте. – MatF

+0

Хорошо! Я считаю, что ключом для меня был бит кода onResume(). Он обрабатывает проверку видимости, чтобы FAB оставался так, как нужно для вкладки. –

+0

Это даже не проблема, но Google не исправляет ее: https://code.google.com/p/android/issues/detail?id=27526 – MatF

Смежные вопросы