19

我在我的android应用程序中实现SlidingTabLayout。我的查询是,我想要在我的滑动选项卡中实现图标,而不是用于导航的文本。我在互联网上大量搜索任何这样的教程或样本,但没有发现。我也搜索了上一个问题在计算器上:Over Here - SlidingTabLayout with Icons。它有点内容丰富,但并没有真正帮助我。将图标添加到SlidingTabLayout而不是文本

要清楚。我需要我的标签由图标组成。没有文字。

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

附:我还听说有关Andreaz Stuetz的pagerslidingtabstrip并想知道如果这将是更适合的东西我要为...

同样类型:这里是什么,我想我的滑动标签看起来像。看看这张图片的顶部。

编辑:现在,LOLLIPOP(与材料设计)已经出来。我使用一个新的“唯一的图标”SLIDING-TAB-LAYOUT下面看到他们的工具栏(ANDROID 5.0 ACTION-BAR),看到了很多应用程序。他们有什么新的方式来实现这个?再次感谢!

See the Sliding Tabs on the top?

+0

检查此http://www.mkyong.com/android/android-tablayout-example/ –

+0

http://stackoverflow.com/questions/28125794/slidingtablayout-with-icons-only/28134763#28134763 – Daniel

+0

我需要它,所以我改变了SlidingTabLayout代码的一点点,使它易于使用图标的标签https://github.com/kimkevin/SlidingIconTabLayout – kimkevin

回答

-1

从FragmentActivity扩展您的主要活动。还实现了从ActionBar.TabListener这个类,因为我们添加标签

//添加标签

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

检查here

41

这里的关键是要返回SpannableString,含在ImageSpan你的图标,从PagerAdapter的getPageTitle(位置)方法:

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

(确保setViewPager之前调用setCustomTabView

+0

我们可以使'SlidingTabLayout'应该填充它的宽度选项卡,并使他们平等的部分? 。 –

+0

@jeremy如何为选定的选项卡设置不同的图像? – Divya

+1

@VikalpPatel使用重量为自定义选项卡的宽度应该做的伎俩:用'android:layout_width =“0dp”'和'android:layout_weight =“1”'替换'android:layout_width =“wrap_content”'' –

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> ImageView的元素,SRC指向图标..

+0

嗨。你能告诉我mtabstrip是什么以及适配器和onclicklistener的用途是什么? – SynerFlow

+0

SlidingTabLayout的原始实现的一部分..监听器用于向选项卡添加onclick功能,并且不需要适配器,因为您不想在选项卡中设置页面标题 – Tom

0

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

这里的链接库(设置指令包括):https://bitbucket.org/enthusiast94/viewpageraddons/src

1

我知道这个线程,如果比较老了,但我想还是分享我解决这个问题,因为它可能是一些有用的。 它工作得非常好,即使对于不同的drawables,取决于所选状态。

我首先做了定义两个数组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); 
     } 

要根据选择哪个标签更新图像,我们在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" 
     /> 

该解决方案是远远不够完善,但适合我的需要。也许我可以帮助这个人。

+0

如何在垂直顺序中添加两个文本视图 – Erum

6

我解决了同样的问题,但也改变了在选定的选项卡上绘制。

为两个状态的选项卡创建绘图。 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); 
     } 
    } 

希望对某人有帮助。

+0

如果选项卡的宽度占用SlidingTabLayout宽度的50%,您将如何居中该图标。我是否需要创建自定义视图? – Daniel

+0

我没有居中。在我的情况下,标签从左开始,如果它需要50%,它不会填满所有宽度。 – v1k

+0

@Daniel尝试添加android:layout_weight =“1”到您的自定义选项卡布局。 – v1k

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 *,你要代替进口的android yourpackage.R .R,因为它在SlidingTabStrip中是默认的。

1

您的适配器应执行PagerSlidingTabStrip.IconTabProvider

然后在getPageIconResId你可以返回图像资源编号:

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

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

0

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

如果您有任何具体问题,请告诉我。 iv让我的应用看起来很像您发布的屏幕截图。我觉得这个材料设计更新更侧重于启用自定义动画和效果。

0

刚从getPageTitle()方法返回null为我做:

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