将图标添加到SlidingTabLayout而不是文本

我在我的Android应用程序中实现SlidingTabLayout。 我的查询是,我想在我的滑动选项卡中实现图标,而不是导航文本。 我在网上search了很多这样的教程或样本,但没有find。 我也search了一个以前的问题上的stackoverflow: 在这里 – SlidingTabLayout与图标 。 这是有点信息,但没有真正帮助我。

要清楚。 我需要我的标签只包含图标 。 没有文字。

由于我是这个整体设置的新手,我很感激,如果你将正确的代码与解释。 感谢您的时间和精力!

PS 我也听说过安德烈亚斯·斯图茨(Andreaz Stuetz)的翻页贴,想知道这是否会更适合我要去的东西的types…

另外:这是我想我的滑动标签看起来像。 看看这个图像的顶部。

编辑:现在,LOLLIPOP(与材料devise)已经出来。 我在使用工具栏(ANDROID 5.0 ACTION-BAR)之后,使用了一个新的“唯一图标” SLIDING-TAB-LAYOUT看到了许多应用程序。 是否有任何新的方式来执行这个? 再次感谢!

看顶部的滑动标签?

Solutions Collecting From Web of "将图标添加到SlidingTabLayout而不是文本"

这个关键是从你的PagerAdapter的getPageTitle(position)方法返回一个在ImageSpan中包含你的图标的SpannableString:

 private int[] imageResId = { R.drawable.ic_tab_notifications, R.drawable.ic_tab_weather, R.drawable.ic_tab_calendar }; @Override public CharSequence getPageTitle(int position) { Drawable image = getResources().getDrawable(imageResId[position]); image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight()); SpannableString sb = new SpannableString(" "); ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM); sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return sb; } 

通常情况下,这样就足够了,但SlidingTabLayout创build的默认选项卡会调用TextView#setAllCaps(true) ,这将有效地禁用所有ImageSpan,因此您必须使用自定义选项卡视图:

RES /布局/ custom_tab.xml

 <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12sp" android:textStyle="bold" android:background="?android:selectableItemBackground" android:padding="16dp" /> 

以及你在哪里设置/绑定到你的ViewPager:

 SlidingTabLayout slidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs); slidingTabLayout.setCustomTabView(R.layout.custom_tab, 0); slidingTabLayout.setViewPager(viewPager); 

(确保在setCustomTabView之前调用setViewPager

我解决了同样的问题,而且在选定的选项卡上更改drawable。

用两种状态创build制表符的绘图。 first_tab_drawable.xml,second_tab_drawable.xml,third_tab_drawable.xml:

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_selected" android:state_selected="true"/> <item android:drawable="@drawable/ic_normal"/> </selector> 

创build您自己的寻呼机适配器,从PagerAdapter扩展:

 public class MyPagerAdapter extends PagerAdapter { private int[] drawablesIds = { R.drawable.first_tab_drawable, R.drawable.second_tab_drawable, R.drawable.third_tab_drawable }; //Constructor and other standard funcs... public int getDrawableId(int position){ //Here is only example for getting tab drawables return drawablesIds[position]; } //... } 

更改SlidingTabLayout的代码:

 private void populateTabStrip() { //Here is no more standard PagerAdapter! final MyPagerAdapter adapter = (MyPagerAdapter) mViewPager.getAdapter(); final View.OnClickListener tabClickListener = new TabClickListener(); for (int i = 0; i < adapter.getCount(); i++) { View tabView = null; TextView tabTitleView = null; if (mTabViewLayoutId != 0) { // If there is a custom tab view layout id set, try and inflate it tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, false); tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId); } if (tabView == null) { tabView = createDefaultTabView(getContext()); } if (tabTitleView == null && TextView.class.isInstance(tabView)) { tabTitleView = (TextView) tabView; } //Set icon, that can be changeable instead setting text. //I think the text also can setting here from getPageTitle func. //But we interesting only in icon tabTitleView.setCompoundDrawablesWithIntrinsicBounds(adapter.getDrawableId(i), 0, 0, 0); //Select tab if it is current if (mViewPager.getCurrentItem() == i){ tabView.setSelected(true); } tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); } } 

并且在InternalViewPagerListener中的SlidingTabLayout中也真正地select了TextView标题:

  @Override public void onPageSelected(int position) { //Clear old selection and make new for(int i = 0; i < mTabStrip.getChildCount(); i ++){ mTabStrip.getChildAt(i).setSelected(false); } mTabStrip.getChildAt(position).setSelected(true); if (mScrollState == ViewPager.SCROLL_STATE_IDLE) { mTabStrip.onViewPagerPageChanged(position, 0f); scrollToTab(position, 0); } if (mViewPagerPageChangeListener != null) { mViewPagerPageChangeListener.onPageSelected(position); } } 

希望对别人有帮助。

要以您想要的方式自定义SlidingTabLayout,您只需要修改populateTabStrip()方法:

 public void populateTabStrip() { final PagerAdapter adapter = mViewPager.getAdapter(); final View.OnClickListener tabClickListener = new TabClickListener(); for (int i = 0; i < adapter.getCount(); i++) { View tabView = null; tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_layout, mTabStrip, false); ImageView iconImageView = (ImageView) tabView.findViewById(R.id.tab_layout_icon); iconImageView.setImageDrawable(getContext().getResources().getDrawable(getIconResourceArray()[i])); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); } } 

你的布局可能是这样的:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="75dp" android:paddingTop="15dp" android:layout_height="50dp" android:orientation="vertical"> <ImageView android:id="@+id/tab_layout_icon" android:layout_width="20dp" android:layout_height="20dp" android:layout_gravity="center" /> </LinearLayout> 

你实现getResourceArray()方法的方式取决于你。 这是我做的:

 public class IconSlidingTabLayout extends HorizontalScrollView { private Integer[] mIconResourceArray; ... public Integer[] getIconResourceArray() { return mIconResourceArray; } public void setIconResourceArray(Integer[] mIconResourceArray) { this.mIconResourceArray = mIconResourceArray; } } 

在活动中:

 mSlidingTabLayout = (IconSlidingTabLayout) findViewById(R.id.icon_sliding_tab_layout); Integer[] iconResourceArray = { R.drawable.news_tab_icon, R.drawable.challenges_tab_icon, R.drawable.trophies_tab_icon, R.drawable.leaderboard_tab_icon }; mSlidingTabLayout.setIconResourceArray(iconResourceArray); 

请注意,为了有权访问R.layout.tab_layout *,您必须导入yourpackage.R而不是android.R,因为它在默认情况下在SlidingTabStrip中。

好吧..有很多方法来实现这个变化。 这是最快和最肮脏的一个,只是想法..

替代方法SlidingTabLayout.populateTabStrip()为此..

  private void populateTabStrip() { final OnClickListener tabClickListener = new TabClickListener(); View tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_notif_icon_only, mTabStrip, false); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_weather_icon_only, mTabStrip, false); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_calendar_icon_only, mTabStrip, false); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); 

以这种方式创build每个布局LinearLayout> ImageView元素,src指向图标..

您的适配器应该实现PagerSlidingTabStrip.IconTabProvider

然后在getPageIconResId你可以返回图像资源的id:

 public class ViewPagerAdapter extends FragmentPagerAdapter implements PagerSlidingTabStrip.IconTabProvider { private static final int[] icons = {R.drawable.image1, R.drawable.image2, R.drawable.image3}; @Override public int getPageIconResId(int i) { return icons[i]; } } 

请记住,只有图像会显示,文字不会。

我知道这个线程如果相当老,但我想分享我的解决scheme,但这个问题,因为它可能会有所帮助。 它工作的很好,即使对于不同的可绘制的取决于所select的状态。

我首先在SlidingTabLayout类中定义了两个数组(这可以很容易地外包给另一个类):

 private int[] imageResId = { R.drawable.multi_random, R.drawable.single_random, R.drawable.known_person, }; private int[] imageResSelected = { R.drawable.multi_random_selected, R.drawable.single_random_selected, R.drawable.known_person_selected }; private int mOldPosition = 0; 

现在我们改变SlidingTabLayoutpopulateTabStrip()方法:

  for (int i = 0; i < adapter.getCount(); i++) { View tabView = null; ImageView tabImageView = null; if (mTabViewLayoutId != 0) { // HAS TO BE SET FOR THE MOMENT! // If there is a custom tab view layout id set, try and inflate it tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, false); tabImageView = (ImageView) tabView.findViewById(mTabViewTextViewId); } if (tabView == null) { tabView = createDefaultTabView(getContext()); } if (tabImageView == null && ImageView.class.isInstance(tabView)) { tabImageView = (ImageView) tabView; } int resourceId; if (i == mViewPager.getCurrentItem()) { resourceId = imageResSelected[i]; mOldPosition = i; } else { resourceId = imageResId[i]; } tabImageView.setImageResource(resourceId); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); } 

要根据select哪个选项卡来更新图像,我们在onPageSelected方法中添加一些行

 // This Method is called once the transition is finished // Change the drawable of the old one.. ImageView view = (ImageView) mTabStrip.getChildAt(mOldPosition); view.setImageResource(imageResId[mOldPosition]); // And now change it of the current one view = (ImageView) mTabStrip.getChildAt(position); view.setImageResource(imageResSelected[position]); mOldPosition = position; 

最后,我们需要添加一个自定义选项卡视图:

 mSlidingTabLayout.setCustomTabView(R.layout.custom_tab, 0); 

像这个

 <?xml version="1.0" encoding="utf-8"?> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="0dp" android:layout_height="wrap_content" android:padding="16dp" android:layout_weight="1" android:src="@drawable/multi_random" /> 

这个解决scheme远非完美,而是满足我的需求。 也许我可以帮助这个人。

我最近实现了这个名为ViewPagerAddons库。 它包括SlidingTabLayoutColors ,这正是你所需要的。 只要让你的寻呼机适配器实现SlidingTabLayouColors.ImageProvider接口,重写getPageImage方法并根据页面位置返回图像资源id。 简单。

这里是链接到图书馆(包括设置说明): https : //bitbucket.org/enthusiast94/viewpageraddons/src

我跟着杰里米的回答,工作正常。 AFAIK没有这样做的新方法。 大多数应用程序现在完全删除工具栏,并添加一个由google推荐的自定义滑动条。

如果您有任何具体问题,请告诉我。 四我的应用程序看起来很像你张贴的截图。 我觉得这个材料devise更新更侧重于启用自定义animation和效果。

getPageTitle()方法返回null对我来说是这样的:

 @Override public CharSequence getPageTitle(int position) { return null; } 

检查此解决scheme链接androidhive关于材料devise选项卡/ viewpager

一个非常好的网站关于android解决scheme。 希望你会find一个解决scheme。

从FragmentActivity扩展您的主要活动。 在我们添加Tabs的时候也从ActionBar.TabListener实现这个类

//用于添加选项卡

 for (String tab_name : tabs) { actionBar.addTab(actionBar.newTab().setIcon(R.drawable.drawable_id) .setTabListener(this)); } 

在这里检查。