选项卡上的自定义图标
Custom icon on Tabs
我正在使用 PagerSlidingTabStrip 和 ViewPager。
有没有办法根据某些操作动态更改选项卡图标。就像收到通知时,我想更改通知选项卡上的图标以显示有多少通知未读。
或任何其他无需太多调整即可支持该功能的库。
您可以通过分叉此库并更改示例应用中使用的 IconTabProvider 的行为来实现您想要的 there 实施为仅使用静态资源。
更改您的 lib 分支以添加动态图标更改:
在PagerSlidingTabStrip
中:
更改return IconTabProvider 接口的getPageIconResId 方法的类型(和名称)
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) 并在您的 PagerSlidingTabStrip 对象上调用 notifyDataSetChanged()。
由于时间不够,我还没有测试我的解决方案,但我会尽快! ;)
您可以通过实现 PagerSlidingTabStrip.CustomTabProvider
接口来实现。我为你的案例制作了example project,让我们一步一步地探索它。
首先, 为我们的选项卡创建一个名为 tab_layout
的布局。它将包含 2 TextView
的标题和徽章。就我而言,它看起来像:
<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>
其次, 为选项卡创建一个简单模型,它将包含选项卡标题和通知数量。我把它命名为 ViewPagerTab
:
public class ViewPagerTab {
public String title;
public int notifications;
public ViewPagerTab(String title, int notifications) {
this.title = title;
this.notifications = notifications;
}
}
第三, 在您的 FragmentPagerAdapter
上实现 PagerSlidingTabStrip.CustomTabProvider
接口。在这里我们将膨胀选项卡布局并初始化选项卡视图,我们还将为位置定义片段:
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
的onCreate
方法中初始化tabs和pager:
@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();
}
你会得到这样的东西:
和最后,要在运行时获取和更改选项卡视图,您只需在您的 PagerSlidingTabStrip
object 中调用 getChildAt
函数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);
}
}
别忘了,child的浏览量是从0开始的。如果要使用图片,只需将ImageView
换成TextView
徽章并更改它的图像资源而不是文本。享受吧!
我正在使用 PagerSlidingTabStrip 和 ViewPager。
有没有办法根据某些操作动态更改选项卡图标。就像收到通知时,我想更改通知选项卡上的图标以显示有多少通知未读。
或任何其他无需太多调整即可支持该功能的库。
您可以通过分叉此库并更改示例应用中使用的 IconTabProvider 的行为来实现您想要的 there 实施为仅使用静态资源。
更改您的 lib 分支以添加动态图标更改:
在PagerSlidingTabStrip
中:
更改return IconTabProvider 接口的getPageIconResId 方法的类型(和名称)
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) 并在您的 PagerSlidingTabStrip 对象上调用 notifyDataSetChanged()。
由于时间不够,我还没有测试我的解决方案,但我会尽快! ;)
您可以通过实现 PagerSlidingTabStrip.CustomTabProvider
接口来实现。我为你的案例制作了example project,让我们一步一步地探索它。
首先, 为我们的选项卡创建一个名为 tab_layout
的布局。它将包含 2 TextView
的标题和徽章。就我而言,它看起来像:
<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>
其次, 为选项卡创建一个简单模型,它将包含选项卡标题和通知数量。我把它命名为 ViewPagerTab
:
public class ViewPagerTab {
public String title;
public int notifications;
public ViewPagerTab(String title, int notifications) {
this.title = title;
this.notifications = notifications;
}
}
第三, 在您的 FragmentPagerAdapter
上实现 PagerSlidingTabStrip.CustomTabProvider
接口。在这里我们将膨胀选项卡布局并初始化选项卡视图,我们还将为位置定义片段:
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
的onCreate
方法中初始化tabs和pager:
@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();
}
你会得到这样的东西:
和最后,要在运行时获取和更改选项卡视图,您只需在您的 PagerSlidingTabStrip
object 中调用 getChildAt
函数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);
}
}
别忘了,child的浏览量是从0开始的。如果要使用图片,只需将ImageView
换成TextView
徽章并更改它的图像资源而不是文本。享受吧!