我在我的Android应用程序中实现了SlidingTabLayout。我的疑问是我想在我的滑动标签中实现图标而不是导航文本。我在互联网上搜索任何这样的教程或样本,但没有找到。我还在stackoverflow上搜索了上一个问题:Over Here - SlidingTabLayout with Icons。它提供了一些信息,但并没有真正帮助我。
要清楚。我要求我的标签只包含 图标 。没有文字。
由于我是整个设置的新手,如果您发布正确的代码并附上解释,我们将不胜感激。感谢您的时间和精力!
PS 我也听说过Andreaz Stuetz的pagerslidingtabstrip,并想知道这是否更适合我想要的那种......
另外:这就是我希望我的滑动标签看起来像。查看此图片的顶部。
编辑:现在LOLLIPOP(带有材料设计)已经出现了。我已经看到很多应用程序使用一个新的"只有图标" SLIDING-TAB-LAYOUT
低于他们的工具栏(ANDROID 5.0 ACTION-BAR)。是他们实现这个的新方法吗?再次感谢!
答案 0 :(得分:41)
关键是从PagerAdapter的getPageTitle(位置)方法返回一个SpannableString,其中包含ImageSpan中的图标:
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创建的默认选项卡会调用TextView#setAllCaps(true)
来有效禁用所有ImageSpans,因此您必须使用自定义选项卡视图:
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
)
答案 1 :(得分:6)
我解决了同样的问题,但也改变了选定标签上的drawable。
为标签创建两个状态的drawable。 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>
创建自己的寻呼机适配器,从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中制作真正选择的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);
}
}
希望它会对某人有所帮助。
答案 2 :(得分:3)
要以您希望的方式自定义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 *,您必须在SlidingTabStrip中默认导入yourpackage.R而不是android.R。
答案 3 :(得分:1)
好的..实现此更改的方法有很多种。这是最快速和最脏的一个,只是为了这个想法..
替换方法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);
以这种方式创建每个布局LinearLayout&gt; ImageView元素,src指向图标..
答案 4 :(得分:1)
我知道这个线程相当老,但我想分享我对这个问题的解决方案,因为它可能对某些人有帮助。 它的效果非常好,即使对于不同的绘图,取决于所选的状态。
我首先在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;
现在我们更改populateTabStrip()
中的SlidingTabLayout
方法:
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);
}
要根据选择的标签更新图像,我们在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"
/>
这个解决方案远非完美,但可以满足我的需求。也许我可以帮助这个人。
答案 5 :(得分:1)
您的适配器应实现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];
}
}
请注意,只会显示图片,不会显示文字。
答案 6 :(得分:0)
我最近实现了这个名为ViewPagerAddons
的库。它包括SlidingTabLayoutColors
,这正是您所需要的。只需让您的寻呼机适配器实现SlidingTabLayouColors.ImageProvider
接口,覆盖getPageImage
方法并根据页面位置返回图像资源ID。简单。
以下是图书馆的链接(包括设置说明):https://bitbucket.org/enthusiast94/viewpageraddons/src
答案 7 :(得分:0)
我听了Jeremy的回答并且工作正常。 AFAIK没有新方法。大多数应用程序现在完全删除工具栏并添加谷歌推荐的自定义slidingtabstrip。
如果您有任何具体问题,请告诉我们。 iv让我的应用看起来很像你发布的截图。我觉得这个材料设计更新更侧重于启用自定义动画和效果。
答案 8 :(得分:0)
从null
方法返回getPageTitle()
只为我做了这件事:
@Override
public CharSequence getPageTitle(int position) {
return null;
}
答案 9 :(得分:0)
检查此解决方案链接androidhive about material design tabs /viewpager
一个关于Android解决方案的非常好的网站。希望你能找到解决方案。
答案 10 :(得分:-1)
从FragmentActivity扩展您的主要活动。还要在ActionBar.TabListener中实现这个类,因为我们正在添加Tabs
//添加标签
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setIcon(R.drawable.drawable_id)
.setTabListener(this));
}
检查here。