2015-06-25 5 views
2

Я использую PagerSlidingTabStrip с ViewPager.Пользовательский значок на вкладках

Есть ли способ, которым я могу изменять иконки вкладки динамически, в зависимости от некоторых действий. Как и при получении уведомления, я хочу изменить значок на вкладке уведомлений, чтобы показать, сколько уведомлений непрочитано.

Или любая другая библиотека, которая поддерживала бы это без большой настройки.

+0

https://github.com/astuetz/PagerSlidingTabStrip - это то, что вы ищете? – 55597

+0

Как и в вопросе, это то, что я использую. Но у библиотеки нет возможности динамически менять значки. – Housefly

ответ

15

Вы можете сделать это, реализовав интерфейс PagerSlidingTabStrip.CustomTabProvider. Я сделал example project для вашего случая, поэтому давайте изучать его шаг за шагом.

Во-первых, создайте макет для нашей вкладки, например, tab_layout. Он будет содержать 2 TextView 's для названия и значка. В моем случае это выглядит следующим образом:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<TextView 
    android:id="@+id/tab_title" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerInParent="true" 
    android:gravity="center" 
    android:textColor="@android:color/white" 
    android:textStyle="bold" 
    android:textSize="16sp" 
    android:singleLine="true" /> 

<TextView 
    android:id="@+id/badge" 
    android:layout_width="16dp" 
    android:layout_height="16dp" 
    android:layout_toRightOf="@+id/tab_title" 
    android:textSize="12sp" 
    android:gravity="center" 
    android:layout_marginLeft="8dp" 
    android:layout_centerVertical="true" 
    android:textColor="@android:color/white" 
    android:background="@drawable/badge_background" /> 

</RelativeLayout> 

Во-вторых, создать простую модель для Tab, которая будет containt вкладки название и количество уведомлений. Я назвал это ViewPagerTab:

public class ViewPagerTab { 
    public String title; 
    public int notifications; 

    public ViewPagerTab(String title, int notifications) { 
     this.title = title; 
     this.notifications = notifications; 
    } 
} 

В-третьих, реализовать PagerSlidingTabStrip.CustomTabProvider интерфейс на вашем FragmentPagerAdapter.Здесь мы будем раздувать расположение вкладок и инициализировать представления с закладками, и мы будем определять фрагменты для позиций:

public class MainAdapter extends FragmentPagerAdapter 
     implements PagerSlidingTabStrip.CustomTabProvider { 

    ArrayList<ViewPagerTab> tabs; 

    public MainAdapter(FragmentManager fm, ArrayList<ViewPagerTab> tabs) { 
     super(fm); 
     this.tabs = tabs; 
    } 

    @Override 
    public View getCustomTabView(ViewGroup viewGroup, int i) { 
     RelativeLayout tabLayout = (RelativeLayout) 
       LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.tab_layout, null); 

     TextView tabTitle = (TextView) tabLayout.findViewById(R.id.tab_title); 
     TextView badge = (TextView) tabLayout.findViewById(R.id.badge); 

     ViewPagerTab tab = tabs.get(i); 

     tabTitle.setText(tab.title.toUpperCase()); 
     if (tab.notifications > 0) { 
      badge.setVisibility(View.VISIBLE); 
      badge.setText(String.valueOf(tab.notifications)); 
     } else { 
      badge.setVisibility(View.GONE); 
     } 

     return tabLayout; 
    } 

    @Override 
    public void tabSelected(View view) { 
     //if you don't want badges disappear when you select tab comment next lines 
     RelativeLayout tabLayout = (RelativeLayout) view; 
     TextView badge = (TextView) tabLayout.findViewById(R.id.badge); 
     badge.setVisibility(View.GONE); 
    } 

    @Override 
    public void tabUnselected(View view) { 

    } 

    @Override 
    public Fragment getItem(int position) { 
     switch (position) { 
      case 0: 
       return new OneFragment(); 
      case 1: 
       return new TwoFragment(); 
      case 2: 
       return new ThreeFragment(); 
     } 
     return new OneFragment(); 
    } 

    @Override 
    public int getCount() { 
     return tabs.size(); 
    } 
} 

В-четвертых, инициализации вкладки и пейджера в MainActivity «s onCreate метода:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs); 
    pager = (ViewPager) findViewById(R.id.pager); 

    ArrayList<ViewPagerTab> tabsList = new ArrayList<>(); 
    tabsList.add(new ViewPagerTab("One", 0)); 
    tabsList.add(new ViewPagerTab("Two", 1)); 
    tabsList.add(new ViewPagerTab("Three", 2)); 

    adapter = new MainAdapter(getSupportFragmentManager(), tabsList); 

    pager.setAdapter(adapter); 
    tabs.setViewPager(pager); 

    pager.setOffscreenPageLimit(3); 
    getSupportActionBar().hide(); 
} 

You получится примерно следующее:

И наконец, чтобы получить д просмотры вкладки изменения в режиме исполнения, вы можете просто вызвать getChildAt функцию PagerSlidingTabStrip объекта в вашем Activity или Fragment, и делать то, что вы хотите:

private void notifyTabStripChanged(int position, int notificationsCount) { 
    LinearLayout tabHost = (LinearLayout) tabs.getChildAt(0); 
    RelativeLayout tabLayout = (RelativeLayout) tabHost.getChildAt(position); 
    TextView badge = (TextView) tabLayout.findViewById(R.id.badge); 
    if (notificationsCount > 0) { 
     badge.setVisibility(View.VISIBLE); 
     badge.setText(String.valueOf(notificationsCount)); 
    } else { 
     badge.setVisibility(View.GONE); 
    } 
} 

Не забывайте, что ребенок видит отсчет начинается с 0 Если вы хотите использовать изображения, просто замените ImageView на значок TextView и измените его как ресурс изображения вместо текста. Наслаждайтесь!

+0

Привет большое спасибо за ваш проект и объяснение. Помогли много. Принят, но я сделал это по-другому - я изменил функцию 'addIconTab (конечная int position, int resId)' для раздувания пользовательского представления вместо 'ImageButton'. И во фрагменте, где я использую 'PagerSlidingTabStrip', я получаю вкладку с помощью' getChildtAt() 'и устанавливаю текст или скрываю его так, как я хотел. – Housefly

+0

Добро пожаловать! Это ваш выбор, но я считаю, что «IconTabProvider» создан для вкладок только с значками, когда «CustomTabProvider» создан для полной настраиваемой вкладки. В любом случае, рад помочь вам :) – rom4ek

+0

спасибо nice exmple – Aayushi

0

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


Изменения, чтобы сделать для вашей Lib вилкой, чтобы добавить динамические изменения иконок:

In PagerSlidingTabStrip:

Изменить тип возврата (и имя) метода getPageIconResId интерфейса IconTabProvider

public interface IconTabProvider { 
    //public int getPageIconResId(int position) becomes 
    public Bitmap getPageIconBitmap(int position) 
} 

Это приводит к обновлению вызова этого метода в PagerSlidingTabStrip

-

А также изменить метод addIconTab от

private void addIconTab(final int position, int resId) { 
    ImageButton tab = new ImageButton(getContext()); 
    tab.setImageResource(resId); 
    addTab(position, tab); 
} 

в

private void addIconTab(final int position, bitmap icon) { 
    ImageButton tab = new ImageButton(getContext()); 
    tab.setImageBitmap(icon); 
    addTab(position, tab); 
} 

Затем вам нужно создать адаптер для вкладок панели, вот пример :

public class DynamicIconPagerAdapter extends PagerAdapter implements IconTabProvider { 

    public HashMap<Integer, Bitmap> mapBetweenPositionAndIcons = new HashMap(); 

    public DynamicIconPagerAdapter() { 
     super(); 
    } 

    @Override 
    public int getCount() { 
     return mapBetweenPositionAndIcons.size(); 
    } 

    @Override 
    public Bitmap getPageIconResId(int position) { 
     return mapBetweenPositionAndIcons.get(position); 
    } 

    @Override 
    public Object instantiateItem(ViewGroup container, int position) { 
     // looks a little bit messy here 
     TextView v = new TextView(getActivity()); 
     v.setBackgroundResource(R.color.background_window); 
     v.setText("PAGE " + (position + 1)); 
     final int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, getResources() 
       .getDisplayMetrics()); 
     v.setPadding(padding, padding, padding, padding); 
     v.setGravity(Gravity.CENTER); 
     container.addView(v, 0); 
     return v; 
    } 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object view) { 
     container.removeView((View) view); 
    } 

    @Override 
    public boolean isViewFromObject(View v, Object o) { 
     return v == ((View) o); 
    } 

} 

Наконец, если вы хотите обновить значок, просто измените соответствующее растровое изображение карты (mapBetweenPositionAndIcons) и вызовите notifyDataSetChanged() на свой объект PagerSlidingTabStrip.

Я не проверял свое решение из-за нехватки времени, но я буду как можно скорее! ;)

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