No dobrze, mogłem znaleźć bardzo trudne rozwiązanie tylko dlatego, że nie miałem czasu, aby ait dla następnej wersji biblioteki wsparcia.Oto co zrobiłem:
- Set pager adapter do TabLayout
tabLayout.setTabsFromPagerAdapter(pagerAdapter);
Dodaj słuchacza do ViewPager
customViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
tabLayout.getTabAt(position).select();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
Dodaj słuchacza do TabLayout
tabLayout.setOnTabSelectedListener(new
TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if (!isTabUpdating) {
isTabUpdating = true;
final int pos = tab.getPosition();
customViewPager.setCurrentItem(pos);
// Clears and populates all tabs
tabLayout.setTabsFromPagerAdapter(pagerAdapter);
invalidateTabs(pos);
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
if (!isTabUpdating) {
isTabUpdating = true;
final int pos = tab.getPosition();
customViewPager.setCurrentItem(pos);
// Clears and populates all tabs
tabLayout.setTabsFromPagerAdapter(pagerAdapter);
invalidateTabs(pos);
}
}
});
metody Add do ponownego rysowania wszystkich zakładek
private void invalidateTabs(int selected) {
for (int i = 0; i < tabLayout.getTabCount(); i++) {
tabLayout.getTabAt(i).setCustomView(pagerAdapter.getTabView(i, i == selected));
}
isTabUpdating = false;
}
Dobrze, więc pozwól mi wyjaśnić trochę. Przede wszystkim możesz się zastanawiać, dlaczego użyłem setTabsFromPagerAdapter()
zamiast setupWithViewPager
. Na początku użyłem setupWithViewPager
, ale jakoś nie działało to poprawnie z moim pageriem, a pierwszego elementu nie można było wybrać.
Druga rzecz, którą możesz przyznać - za każdym razem, gdy wybieram kartę, usuwam wszystkie. No cóż, to był łatwy problem, widzisz źródła z Androidem, gdy dzwonisz pod numer Tab.setCustomView(View)
, który sprawdza rodzica widoku, a jeśli nie ma wartości null - usuwa wszystkie odsłonięcia. Jednak jeśli przejdą nowo wystąpienia elementu dodasz inny widok zamiast zastępując starą:
View custom = tab.getCustomView();
if(custom != null) {
ViewParent icon = custom.getParent();
if(icon != this) {
if(icon != null) {
// You wont get here
((ViewGroup)icon).removeView(custom);
}
this.addView(custom);
}
...
Więc skończyło się ustawienie wszystkich słuchaczy przez siebie i ponownego tworzenia wszystkie karty za każdym razem na stronie/zmiany w kartach. To NIE jest dobre rozwiązanie, ale o ile nie możemy czekać, aż Google zaktualizuje swoją bibliotekę - to chyba jedyne rozwiązanie, które pozwoli osiągnąć taki efekt. (Tylko w przypadku, gdy zastanawiacie się, dlaczego jest to tak skomplikowane - musiałem mieć Tabulatory z niestandardowymi widokami (tekst + obraz), które mogą zmienić ich właściwości widoku (kolor czcionki, obraz), gdy zostaną wybrane/odznaczone)
BTW - Oto metoda z 4. etapu getTabView(...)
:
public View getTabView(int pos, boolean isSeleted) {
View tabview = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout
.tab_sessioninfo,
null, false);
final ImageView ivTabIcon = (ImageView) tabview.findViewById(R.id.iv_tab_icon);
final TextView tvTabTittle = (TextView) tabview.findViewById(R.id.tv_tab_title);
if (isSeleted) {
tvTabTittle.setTextColor(context.getResources().getColor(R.color.tab_indicator));
}
switch (pos) {
case 0:
tvTabTittle.setText("1st Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon1_selected : R.drawable.ic_icon1);
break;
case 1:
tvTabTittle.setText("2nd Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon2_selected : R.drawable.ic_icon2);
break;
case 2:
tvTabTittle.setText("3rd Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon3_selected : R.drawable.ic_icon3);
break;
}
return tabview;
}
PS Jeśli znasz lepsze rozwiązanie dla tych wszystkich rzeczy, daj mi znać!
UPDATE
lepszym rozwiązaniem mogłoby być podchodzić za pomocą refleksji:
Łatwa konfiguracja
tabLayout.setupWithViewPager(customViewPager);
customViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
for (int i = 0; i <tabLayout.getTabCount(); i++){
updateTab(tabLayout.getTabAt(i), position == i);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
Aktualizacja Tab
private void updateTab(TabLayout.Tab tab, boolean isSelected){
Method method = null;
try {
method = TabLayout.Tab.class.getDeclaredMethod("getCustomView", null);
method.setAccessible(true);
View tabview = (View) method.invoke(tab, null);
final ImageView ivTabIcon = (ImageView) tabview.findViewById(R.id.iv_tab_icon);
final TextView tvTabTittle = (TextView) tabview.findViewById(R.id.tv_tab_title);
if (isSeleted) {
tvTabTittle.setTextColor(context.getResources().getColor(R.color.tab_indicator));
}
switch (pos) {
case 0:
tvTabTittle.setText("1st Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon1_selected : R.drawable.ic_icon1);
break;
case 1:
tvTabTittle.setText("2nd Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon2_selected : R.drawable.ic_icon2);
break;
case 2:
tvTabTittle.setText("3rd Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon3_selected : R.drawable.ic_icon3);
break;
}
tab.setCustomView(tabview);
} catch (Exception e) {
e.printStackTrace();
}
}
UPDATE
Nowa biblioteka posiada wsparcie publiczne dla getCustomView()
metody, więc nie trzeba odbicie nie więcej!
Idealne, zastosuję się do tego. –
@Moinkhan możesz ustawić widok jako tag na tablayout. –
Ok, rozumiem, co mówisz, ale w końcu błąd jest akceptowany i rozwiązywany przez google. Teraz status tego błędu jest w przyszłej wersji. Więc nie musimy robić żadnych trudnych rozwiązań .. – Moinkhan