2015-06-18 13 views
20

używam TabLayout nowej konstrukcji materialnej i mam problem, nie mogę zaktualizować zawartość zakładki z widokiem niestandardowym kiedy zostanie utworzona zakładka:TabLayout zawartości karty zmiana z widoku niestandardowego

mogę uprościć moją metodę w moim PagerAdapter z

public View setTabView(int position, boolean selected) { 
    View v = LayoutInflater.from(context).inflate(R.layout.default_tab_view, null); 
    tv = (TextView) v.findViewById(R.id.tabTextView); 
    if(selected) 
     tv.setText("SELECTED"); 
    else 
     tv.setText("UNSELECTED");  
    return v; 
} 

A aktywności mogę uprościć mój kod z:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
ViewPager pager = (ViewPager) findViewById(R.id.viewpager); 
PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager()); 
pager.setAdapter(adapter); 
tabLayout.setupWithViewPager(pager); 
for (int i = 0; i < tabLayout.getTabCount(); i++) { 
    TabLayout.Tab tab = tabLayout.getTabAt(i); 
    View v; 
    if (i == 0) { 
     v = adapter.setTabView(i, true); 
     v.setSelected(true); 
    } else 
     v = adapter.setTabView(i, false); 

    tab.setCustomView(v); 
} 

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
    @Override 
    public void onTabSelected(TabLayout.Tab tab) { 
     adapter.setTabView(tab.getPosition(), true); 
    } 

    @Override 
    public void onTabUnselected(TabLayout.Tab tab) { 
     adapter.setTabView(tab.getPosition(), false); 
    } 

    @Override 
    public void onTabReselected(TabLayout.Tab tab) { 

    } 
}); 

tytuły zakładkach są ustawione tuż po uruchomieniu aplikacji, ale gdy zmieniam kartę, treść pozostaje taka sama.

Odpowiedz

41

Ok Myślę, że to błąd w bibliotece wsparcia projektu Android v22.

Ponieważ mówisz o zmianach w treści, ale nie mogę zmienić koloru tekstu. Po utworzeniu karty i zmianie układu nie będzie ona odzwierciedlana.

I jak widziałem twój kod, dajesz niestandardowy układ przy użyciu setCustomView. i do zmiany tekstu wywołuje się ponownie metodę setTabView(). Zamiast tego powinna istnieć metoda getCustomView(), aby można było zmienić układ. Istnieje metoda w TabLayout.Tab.getCustomView, ale nie ma ona identyfikatora i zgłosiłem ten błąd.

https://code.google.com/p/android/issues/detail?id=177492

[Aktualizacja 07.08.2015]

Wreszcie bug został zaakceptowany przez android źródłowego bug traking i oznaczone jako przyszłych wersjach. Możemy więc powiedzieć, że błąd nie będzie już istnieć w przyszłej bibliotece. i możemy mieć metodę getCustomView(), abyśmy mogli łatwo uzyskać nasz niestandardowy widok.

[Aktualizacja 18-08-2015]

końcu bug został rozwiązany wydany w bibliotekami wsparcia V23. Po prostu zaktualizuj bibliotekę obsługi za pomocą menedżera SDK i uzyskaj funkcję getCustomView() jako publiczną.

wystarczy zmienić tę linię w Gradle

compile 'com.android.support:design:23.0.0' 

i upewnij się skompilować i docelowy zestaw SDK do 23.

proszę sprawdzić mój kod działa dobrze dla mnie

TabLayout.Tab tab=tabLayout.getTabAt(position);   
View view=tab.getCustomView();   
TextView txtCount= (TextView) 
view.findViewById(R.id.txtCount);   
txtCount.setText(count+""); 
+0

Idealne, zastosuję się do tego. –

+2

@Moinkhan możesz ustawić widok jako tag na tablayout. –

+0

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

7

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:

  1. Set pager adapter do TabLayout tabLayout.setTabsFromPagerAdapter(pagerAdapter);
  2. 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) { 
        } 
    }); 
    
  3. 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); 
         } 
        } 
    }); 
    
  4. 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:

  1. Ł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) { 
        } 
    }); 
    
  2. 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!

+0

Nie mam żadnego układu dla karty, właśnie korzystałem z biblioteki. więc jak mogę powiązać składnik "ostateczny ImageView ivTabIcon = (ImageView) tabview.findViewById (R.id.iv_tab_icon);", gdzie muszę dodać niestandardowy układ? – Tara

+0

@ Tara, Czy mógłbyś wyjaśnić, co próbujesz osiągnąć? –

+0

Używam biblioteki bezpośredniej, która nie definiuje żadnego niestandardowego układu dla karty. Jak zdefiniowałeś "R.layout.tab_sessioninfo". Jeśli nie używam żadnego niestandardowego układu, więc nie będę miał żadnego ImageView. Moja agenda polegała na kliknięciu na kartę, która zmieniła ikonę karty. Niektóre z nich, jak przed wybraniem karty, której ikona była szara i po wybraniu ikony zmienia się na niebieski. W jaki sposób rozwiązałem mój problem, dodając metody "addOnPageChangeListener i onPageSelected". – Tara

0

proszę sprawdzić mój kod działa dobrze dla mnie

TabLayout.Tab tab=tabLayout.getTabAt(position);   
View view=tab.getCustomView();   
TextView txtCount= (TextView) view.findViewById(R.id.txtCount);   
txtCount.setText(count+""); 
0

spojrzeć Answer trzeba ustawić układ jako oczekiwany przez was. Jeśli chcesz zmienić zawartość karty, wprowadź zmiany w Tab.setOnTabSelectedListener()

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
    @Override 
    public void onTabSelected(TabLayout.Tab tab) { 
     if(tab.getPosition()==1){ 
       tabLayout.setTabTextColors(ContextCompat.getColor(getActivity(), R.color.unselected_tab),ContextCompat.getColor(getActivity(), R.color.tab_selection)); 
      }else{ 
       tabLayout.setTabTextColors(ContextCompat.getColor(getActivity(), R.color.unselected_tab),ContextCompat.getColor(getActivity(), R.color.white)); 

      } 

// same thing goes with other tabs too 
// Just change your tab text on selected/deselected as above 

    } 

    @Override 
    public void onTabUnselected(TabLayout.Tab tab) { 
     tab.setCustomView(null); 
    } 

    @Override 
    public void onTabReselected(TabLayout.Tab tab) { 

    } 
}); 
Powiązane problemy