2015-06-18 2 views
20

Я использую TabLayout нового дизайна материала и у меня есть проблема, я не могу обновить содержимое вкладки пользовательского вида, как только вкладка создается:TabLayout вкладка обновление содержимого с пользовательской точки зрения

я могу упростить мой метод в моем PagerAdapter с

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; 
} 

И в деятельности я могу упростить мой код:

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) { 

    } 
}); 

название Вкладки установлено правильно, когда приложение запускается, но когда я меняю вкладку, содержимое остается неизменным.

ответ

41

Ok Я думаю, что это ошибка в библиотеке поддержки Android v22.

Потому что вы говорите об изменениях в содержании, но я не могу изменить цвет текста. Как только вкладка будет создана, и если вы измените макет, это не отразится.

И поскольку я видел ваш код, вы предоставляете настраиваемый макет с помощью setCustomView. и для изменения текста вы снова вызываете метод setTabView(). Вместо этого должен быть метод getCustomView(), чтобы вы могли изменить макет. Существует метод в TabLayout.Tab.getCustomView, но у него нет идентификатора, и я сообщаю об этой ошибке.

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

[Обновление 08-07-2015]

Наконец ошибка принимаются андроид источник ошибки Traking и помечена как Future Release. Таким образом, мы можем сказать, что ошибка будет больше не существовать в будущей библиотеке. , и у нас есть способ getCustomView(), чтобы мы могли легко получить наш пользовательский вид.

[Обновление 18-08-2015]

Наконец ошибка разрешена Выпущенный в поддержки v23 LIBS. Просто обновите библиотеку поддержки, используя диспетчер SDK, и у вас есть getCustomView() как публикация.

просто изменить эту строку в Gradle

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

и убедитесь, компилировать и целевой набор SDk до 23.

пожалуйста, проверьте мой код работает отлично для меня

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

Отлично, я последую за ним. –

+2

@Moinkhan вы можете установить вид как тег для tablayout. –

+0

Хорошо, я понимаю, что вы говорите, но, наконец, ошибка принимается и решается google. Теперь статус этой ошибки будет в будущем выпуске. Таким образом, нам не нужно делать какое-либо сложное решение. – Moinkhan

7

Хорошо, я, возможно, нашел очень сложное решение только потому, что у меня не было времени на w ait для следующей версии поддержки-библиотеки.Вот что я сделал:

  1. Набор пейджера адаптер к вашему TabLayout tabLayout.setTabsFromPagerAdapter(pagerAdapter);
  2. Добавить слушатель в 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. Добавить слушатель в 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. Добавить метод для повторного рисования всех вкладок

    private void invalidateTabs(int selected) { 
        for (int i = 0; i < tabLayout.getTabCount(); i++) { 
         tabLayout.getTabAt(i).setCustomView(pagerAdapter.getTabView(i, i == selected)); 
        } 
        isTabUpdating = false; 
    } 
    

Хорошо, позвольте мне объяснить немного. Прежде всего, вы можете задаться вопросом, почему я использовал setTabsFromPagerAdapter() вместо setupWithViewPager. В начале я использовал setupWithViewPager, но каким-то образом я не работал с моим пейджером, и 1-й элемент не был выбран.

Второе, что вы можете признать - каждый раз, когда я выбираю вкладку, я удаляю все из них. Ну, это была легкая проблема, вы видите, что я источник для android, когда вы вызываете Tab.setCustomView(View), он проверяет родителя представления и если он не является нулевым - он удаляет все дочерние элементы. Однако, если вы передаете вновь инстанцированы деталь вы добавите другой вид вместо того, чтобы заменить старую:

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); 
      } 
    ... 

Итак, я закончил с установкой всех слушателей самостоятельно и воссоздавая все вкладки каждый раз, когда на странице/вкладки. Это НЕ хорошее решение, но, поскольку он не может дождаться, когда Google обновит их lib - это, вероятно, единственное решение для достижения такого эффекта. (На всякий случай вам интересно, почему это так сложно - мне нужно было иметь вкладки с пользовательскими представлениями (текст + изображение), которые могли бы изменить их свойства вида (цвет шрифта, изображение), когда они выбраны/не выбраны)

BTW - Вот getTabView(...) метод с 4-го этапа:

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 Если вы знаете лучшее решение для всего этого, дайте мне знать!

UPDATE

Лучше решение можно подойти с помощью Reflection:

  1. Простая установка

    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. Tab Update

    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

Новая библиотека поддержки не имеет публичный метод для getCustomView(), так что вам не нужно отражения больше нет!

+0

У меня нет макета для вкладки, я просто использовал библиотеку. поэтому как я могу привязать компонент «final ImageView ivTabIcon = (ImageView) tabview.findViewById (R.id.iv_tab_icon)», где мне нужно добавить пользовательский макет? – Tara

+0

@ Тара, не могли бы вы объяснить, что вы пытаетесь достичь? –

+0

Я использую прямую библиотеку, не определяющую какой-либо пользовательский макет для вкладки. Как вы определили «R.layout.tab_sessioninfo». Если я не использую какой-либо пользовательский макет, поэтому у меня не будет никакого ImageView. Моя повестка дня состояла в том, чтобы щелкнуть вкладку, которую изменил значок вкладки. Некоторое, что нравится, прежде чем выбирать вкладку, ее значок был серым, а при выборе значка - синим. Как я решил свою проблему, добавив методы addOnPageChangeListener и onPageSelected. – Tara

0

пожалуйста, проверьте мой код работает отлично для меня

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

взглянуть Answer вам необходимо установить макет, как и ожидалось вами. Если вы хотите изменить содержимое вкладки, внесите изменения в 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) { 

    } 
});