131

Как правильно выбрать вкладку TabLayout?Выбор вкладки TabLayout

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
tabLayout.setupWithViewPager(viewPager); 
+1

, пожалуйста, отметьте какой-то ответ как правильный. Помогает ! – eRaisedToX

ответ

247

Если вы знаете, индекс вкладки вы хотите выбрать, вы можете сделать это так:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
TabLayout.Tab tab = tabLayout.getTabAt(someIndex); 
tab.select(); 

Этот метод работает, даже если вы используете TabLayout сам по себе без ViewPager (что является нетипичной и, вероятно, плохой практикой, но я это видел).

+8

Это решение работает только в том случае, если вкладка была добавлена ​​в панель действий, что может быть не всегда так. Из документации для 'TabLayout.Tab.select()': * "Выберите эту вкладку. Действителен только в том случае, если вкладка была добавлена ​​в панель действий." * –

+3

@DanielKvist, собственно сама документация неверна. Исходный код говорит сам за себя. Этот ответ должен быть принятым ответом. –

+0

@JasonSparc Хм, я помню, что это не работало для меня, когда я в последний раз пробовал это решение, но я посмотрю, смогу ли я проверить двойную проверку, как это работает для меня. Ты пробовал? Это может работать в некоторых случаях, а не в других случаях? Это может зависеть от уровня API или чего-то подобного? –

16

Это, вероятно, не окончательное решение и требует, чтобы вы использовали TabLayout вместе с ViewPager, но это, как я ее решил:

void selectPage(int pageIndex) 
{ 
    viewPager.setCurrentItem(pageIndex); 
    tabLayout.setupWithViewPager(viewPager); 
} 

я тестировал, насколько большой производительности влияние использования этого кода заключается в том, что сначала просматривает мониторы CPU и памяти в Android Studio во время запуска метода, а затем сравнивает его с нагрузкой, которая была загружена в CPU и память, когда я самостоятельно перемещался между страницами (используя жестовые салфетки) , и разница не значительно большая, поэтому, по крайней мере, это не ужасное решение ...

Надеюсь, это поможет кому-то!

+1

Когда я сделал решение dap ('tabLayout.setScrollPosition (pageIndex, 0f, true);'), когда я нажал на вкладку справа, он не обновил страницу ViewPager (я не знаю почему). Только щелчок назад на левой вкладке и затем на правой вкладке снова, наконец, обновит страницу, чтобы страница с правой вкладкой была очень глючной. Но у этого решения не было никаких сбоев. –

54

Это, как я ее решил:

void selectPage(int pageIndex){ 
    tabLayout.setScrollPosition(pageIndex,0f,true); 
    viewPager.setCurrentItem(pageIndex); 
} 
+3

Выбранный ответ didnt работает для меня, но этот сделал. –

+0

отличное решение! работал отлично для меня, когда мне нужно было вернуться на первую страницу как viewPager, так и TabView – sashk0

+0

Работал для меня. Благодарю. –

11

Если вы не можете использовать tab.select(), и вы не хотите использовать ViewPager, вы можете программно выбрать вкладку. Если вы используете пользовательский просмотр через TabLayout.Tab setCustomView(android.view.View view), это проще. Вот как это сделать в обоих направлениях.

// if you've set a custom view 
void updateTabSelection(int position) { 
    // get the position of the currently selected tab and set selected to false 
    mTabLayout.getTabAt(mTabLayout.getSelectedTabPosition()).getCustomView().setSelected(false); 
    // set selected to true on the desired tab 
    mTabLayout.getTabAt(position).getCustomView().setSelected(true); 
    // move the selection indicator 
    mTabLayout.setScrollPosition(position, 0, true); 

    // ... your logic to swap out your fragments 
} 

Если вы не используете пользовательский вид, то вы можете сделать это, как этот

// if you are not using a custom view 
void updateTabSelection(int position) { 
    // get a reference to the tabs container view 
    LinearLayout ll = (LinearLayout) mTabLayout.getChildAt(0); 
    // get the child view at the position of the currently selected tab and set selected to false 
    ll.getChildAt(mTabLayout.getSelectedTabPosition()).setSelected(false); 
    // get the child view at the new selected position and set selected to true 
    ll.getChildAt(position).setSelected(true); 
    // move the selection indicator 
    mTabLayout.setScrollPosition(position, 0, true); 

    // ... your logic to swap out your fragments 
} 

Используйте StateListDrawable для переключения между выбранным и невыбранным или что-то вводимым коэффициентом подобного делать то, что вы хотите с цветами и/или чертежи.

1

По умолчанию, если вы выберете вкладку, она будет подсвечена. Если вы хотите выбрать «Явным образом», используйте данный комментированный код под вкладкой onTabSelected (TabLayout.Tab) с указанной вами индексной позицией табуляции. В этом коде объясняется фрагмент изменения на выбранной вкладке с помощью viewpager.

public class GalleryFragment extends Fragment implements TabLayout.OnTabSelectedListener 
{ 
private ViewPager viewPager;public ViewPagerAdapter adapter;private TabLayout tabLayout; 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
View rootView = inflater.inflate(R.layout.fragment_gallery, container, false); 
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager); 
adapter = new ViewPagerAdapter(getChildFragmentManager()); 
adapter.addFragment(new PaymentCardFragment(), "PAYMENT CARDS"); 
adapter.addFragment(new LoyaltyCardFragment(), "LOYALTY CARDS"); 
viewPager.setAdapter(adapter); 
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs); 
    tabLayout.setupWithViewPager(viewPager); 
    tabLayout.setOnTabSelectedListener(this); 
} 

@Override 
public void onTabSelected(TabLayout.Tab tab) { 
    //This will be called 2nd when you select a tab or swipe using viewpager 
    final int position = tab.getPosition(); 
    Log.i("card", "Tablayout pos: " + position); 
    //TabLayout.Tab tabdata=tabLayout.getTabAt(position); 
    //tabdata.select(); 
    tabLayout.post(new Runnable() { 
     @Override 
     public void run() { 
      if (position == 0) { 
       PaymentCardFragment paymentCardFragment = getPaymentCardFragment(); 
       if (paymentCardFragment != null) { 
        VerticalViewpager vp = paymentCardFragment.mypager; 
        if(vp!=null) 
        { 
         //vp.setCurrentItem(position,true); 
         vp.setCurrentItem(vp.getAdapter().getCount()-1,true); 
        } 
        } 
      } 
      if (position == 1) { 
       LoyaltyCardFragment loyaltyCardFragment = getLoyaltyCardFragment(); 
       if (loyaltyCardFragment != null) { 
        VerticalViewpager vp = loyaltyCardFragment.mypager; 
        if(vp!=null) 
        { 
         vp.setCurrentItem(position); 
        } 
        } 
      } 
     } 
    }); 
} 

@Override 
public void onTabUnselected(TabLayout.Tab tab) { 
//This will be called 1st when you select a tab or swipe using viewpager 
} 
@Override 
public void onTabReselected(TabLayout.Tab tab) { 
    //This will be called only when you select the already selected tab(Ex: selecting 3rd tab again and again) 
} 
private PaymentCardFragment getLoyaltyCardFragment() { 
    Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem()); 

    if(f instanceof PaymentCardFragment) 
    { 
    return (PaymentCardFragment) f; 
    } 
    return null; 
} 
private LoyaltyCardFragment getPaymentCardFragment() { 
    Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem()); 
    if(f instanceof LoyaltyCardFragment) 
    { 
    return (LoyaltyCardFragment) f; 
    } 
    return null; 
} 
    class ViewPagerAdapter extends FragmentPagerAdapter { 
    public List<Fragment> mFragmentList = new ArrayList<>(); 
    private final List<String> mFragmentTitleList = new ArrayList<>(); 
    public void addFragment(Fragment fragment, String title) { 
    mFragmentList.add(fragment); 
    mFragmentTitleList.add(title); 
    } 
} 
} 
10

использование tabs.getTabAt(2).select();

2

добавить для ViewPager:

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 

      @Override 
      public void onPageSelected(int position) { 
       array.clear(); 
       switch (position) { 
        case 1: 
         //like a example 
         setViewPagerByIndex(0); 
         break; 
       } 
      } 

      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
      } 

      @Override 
      public void onPageScrollStateChanged(int state) { 
      } 
     }); 

// на обработчик для предотвращения врезаться OutOfMemory

private void setViewPagerByIndex(final int index){ 
    Application.getInstance().getHandler().post(new Runnable() { 
     @Override 
     public void run() { 
      viewPager.setCurrentItem(index); 
     } 
    }); 
} 
+0

«предотвращение сбоя outofmemory» - зачем нам отдельный поток, чтобы выбрать текущий элемент? – AppiDevo

6

попробовать этот

new Handler().postDelayed(
      new Runnable(){ 
       @Override 
       public void run() { 
        if (i == 1){ 
         tabLayout.getTabAt(0).select(); 
        } else if (i == 2){ 
         tabLayout.getTabAt(1).select(); 
        } 
       } 
      }, 100); 
+0

Thanks.it работал для меня. Но хорошо ли использовать задержку? –

+0

Я предполагаю, что неправильно запускать поток на любом из макетов, если предположить, что вы извлекаете текст для вкладки с серверного сервера, и если b'coz по какой-либо причине задерживает сервер, этот системный поток будет unneeccarily потреблять ресурсы вашего устройства. – cammando

+0

так уродливое решение – Lester

12

Используйте это:

<android.support.design.widget.TabLayout 
    android:id="@+id/patienthomescreen_tabs" 
    android:layout_width="match_parent" 
    android:layout_height="72sp" 
    app:tabGravity="fill" 
    app:tabMode="fixed" 
    app:tabIndicatorColor="@android:color/white" 
    app:tabSelectedTextColor="@color/green"/> 

После того как в OnClickListener:

TabLayout tabLayout = (TabLayout) findViewById(R.id.patienthomescreen_tabs); 
TabLayout.Tab tab = tabLayout.getTabAt(someIndex); 
tab.select(); 
+0

лучший ответ :) –

+0

Это должно быть отмечено правильно – marchinram

1

Я утра с помощью TabLayout для переключения фрагментов. Он работает по большей части, за исключением случаев, когда я пытался выбрать вкладку программно, используя tab.select(), мой TabLayout.OnTabSelectedListener вызовет onTabSelected(TabLayout.Tab tab), что вызовет у меня много горя. Я искал способ сделать программный выбор без запуска слушателя.

Так что я адаптировал ответ @kenodoggy на мое использование. Я столкнулся с проблемой, когда некоторые из внутренних объектов возвратили значение null (потому что они еще не были созданы, потому что я отвечал onActivityResult() из моего фрагмента, который встречается до onCreate() в случае, если активность singleTask или singleInstance), поэтому я написал до подробной, если/else последовательность, которая сообщила бы об ошибке и провалилась бы без NullPointerException, которая в противном случае срабатывала. Я использую Timber для ведения журнала, если вы не используете эту замену с помощью Log.e().

void updateSelectedTabTo(int position) { 
    if (tabLayout != null){ 
     int selected = tabLayout.getSelectedTabPosition(); 
     if (selected != -1){ 
      TabLayout.Tab oldTab = tabLayout.getTabAt(0); 
      if (oldTab != null){ 
       View view = oldTab.getCustomView(); 
       if (view != null){ 
        view.setSelected(false); 
       } 
       else { 
        Timber.e("oldTab customView is null"); 
       } 
      } 
      else { 
       Timber.e("oldTab is null"); 
      } 
     } 
     else { 
      Timber.e("selected is -1"); 
     } 
     TabLayout.Tab newTab = tabLayout.getTabAt(position); 
     if (newTab != null){ 
      View view = newTab.getCustomView(); 
      if (view != null){ 
       view.setSelected(false); 
      } 
      else { 
       Timber.e("newTab customView is null"); 
      } 
     } 
     else { 
      Timber.e("newTab is null"); 
     } 
    } 
    else { 
     Timber.e("tablayout is null"); 
    } 
} 

Здесь tabLayout моя переменная памяти, связанный с TabLayout объекта в моем XML. И я не использую функцию прокрутки, поэтому я тоже ее удалил.

2

Вы можете попробовать решить ее с этим:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
tabLayout.setupWithViewPager(mViewPager); 

TabLayout.Tab tab = tabLayout.getTabAt(pos); 
if (tab != null) { 
    tab.select(); 
} 
1

Это тоже может помочь

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
    @Override 
    public void onPageScrolled(int i, float v, int i1) { 
    } 

    @Override 
    public void onPageSelected(int i) { 
     tablayout.getTabAt(i).select(); 
    } 

    @Override 
    public void onPageScrollStateChanged(int i) { 
    } 
}); 
7

Просто установите viewPager.setCurrentItem(index) и связанный с ним TabLayout будет выбрать соответствующую вкладку.

0

Вы можете установить позицию TabLayout, используя следующие функции

public void setTab(){ 
tabLayout.setScrollPosition(YOUR_SCROLL_INDEX,0,true); 
tabLayout.setSelected(true); 
} 
0

Если так случится, что вкладка по умолчанию является первым (0), и вы случайно перейти к фрагменту, то вы должны вручную заменить фрагмент в первый раз. Это связано с тем, что вкладка выбрана до регистрации слушателя.

private TabLayout mTabLayout; 

... 

@Override 
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_tablayout, container, false); 
    mTabLayout = view.findViewById(R.id.sliding_tabs); 
    mTabLayout.addOnTabSelectedListener(mOnTabSelectedListener); 

    getActivity().getSupportFragmentManager().beginTransaction() 
     .replace(R.id.tabContent, MyFirstFragment.newInstance()).commit(); 
    return view; 
} 

В качестве альтернативы, вы можете рассмотреть вызова getTabAt(0).select() и первостепенную onTabReselected так:

@Override 
public void onTabReselected(TabLayout.Tab tab) { 
    // Replace the corresponding tab fragment. 
} 

Это будет работать, потому что вы, по существу, заменяя фрагмент на каждой вкладке Reselect.

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

  • Нет связанных вопросов^_^