Добавить иконки в SlidingTabLayout вместо текста
Я использую SlidingTabLayout в приложении для Android. Какой мой запрос заключается в том, что я хотел бы реализовать значки в своих скользящих вкладках вместо текстов для навигации. Я много искал в Интернете для любого такого учебника или образца, но не нашел его. Я также искал предыдущий вопрос о stackoverflow: Over Here - SlidingTabLayout с иконками. Это было немного информативно, но на самом деле не помогло мне.
Быть ясным. Мне нужно, чтобы мои вкладки состояли только из значков . Нет текста.
Поскольку я новичок в этой всей установке, я был бы признателен, если бы вы опубликовали правильный код с объяснением. Спасибо за ваше время и усилия!
P.S. Я также слышал о том, что Andreas Stuetz использовал pagerslidingtabstrip и задавался вопросом, будет ли это более подходящим для того типа, в котором я собираюсь...
Также: Вот что мне хотелось бы, чтобы мои скользящие вкладки выглядели. Проверьте верхнюю часть этого изображения.
ИЗМЕНИТЬ: ТЕПЕРЬ, ЧТО LOLLIPOP (С МАТЕРИАЛЬНЫМ ДИЗАЙНОМ) ПРИХОДИТ. Я УВИДЕТЬ БОЛЬШОЕ ПРИЛОЖЕНИЕ, ИСПОЛЬЗУЯ НОВУЮ ТОЛЬКО ИКОНУ SLIDING-TAB-LAYOUT
НИЖЕ ИХ ИНСТРУМЕНТА (ANDROID 5.0 ACTION-BAR). ИХ ЛЮБОЙ НОВЫЙ СПОСОБ РЕАЛИЗАЦИИ ЭТОГО? СПАСИБО СНОВА СНОВА!
![See the Sliding Tabs on the top?]()
Ответы
Ответ 1
Ключом к этому является возврат SpannableString, содержащий ваш значок в ImageSpan, из вашего метода getPageTitle (позиция) PagerAdapter:
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, поэтому вместо этого вам нужно будет использовать собственное представление табуляции:
Рез/макет/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
)
Ответ 2
Я решил такую же проблему, но также и с возможностью изменения на выбранной вкладке.
Создайте свои чертежи для вкладок с двумя состояниями.
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);
}
}
И сделайте действительно выбранный заголовок TextView также в SlidingTabLayout в InternalViewPagerListener:
@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);
}
}
Надеюсь, что это будет полезно для кого-то.
Ответ 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 * вам необходимо импортировать файл yourpackage.R вместо android.R, поскольку он по умолчанию находится в SlidingTabStrip.
Ответ 4
Хорошо. Есть много способов реализации этого изменения. Это самый быстрый и грязный, просто для идеи.
Замените метод 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, указывающие на значок.
Ответ 5
Я знаю, что этот поток, если довольно старый, но я хотел бы поделиться своим решением этой проблемы, тем не менее, потому что это может быть полезно для некоторых.
Он работает довольно хорошо даже для разных чертежей в зависимости от выбранного состояния.
Сначала я определил два массива внутри класса 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;
Наконец, нам нужно добавить пользовательский Tab View:
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"
/>
Это решение далека от совершенства, но работает для моих нужд. Может быть, я могу помочь кому-то с этим.
Ответ 6
Ваш адаптер должен реализовывать 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];
}
}
Имейте в виду, что будет показано только изображение, текст не будет.
Ответ 7
Недавно я реализовал эту библиотеку под названием ViewPagerAddons
. Он включает SlidingTabLayoutColors
, что именно то, что вам нужно. Просто позвольте адаптеру пейджера реализовать интерфейс SlidingTabLayouColors.ImageProvider
, переопределить метод getPageImage
и вернуть идентификаторы ресурса изображения в соответствии с позициями страницы. Просто.
Здесь ссылка на библиотеку (включая инструкции по настройке): https://bitbucket.org/enthusiast94/viewpageraddons/src
Ответ 8
Я последовал за ответом Джереми и его работой. AFAIK нет нового способа сделать это. Большинство приложений теперь полностью удаляют панель инструментов и добавляют пользовательскую скользящую панель, рекомендованную google.
Если у вас есть какие-то конкретные вопросы, дайте мне знать. iv получил мое приложение, похожее на скриншот, который вы опубликовали. Я чувствую, что это обновление материального дизайна больше фокусировалось на включении пользовательских анимаций и эффектов.
Ответ 9
Просто возврат null
из метода getPageTitle()
сделал это для меня:
@Override
public CharSequence getPageTitle(int position) {
return null;
}
Ответ 10
Отметьте эту ссылку для решения androidhive о вкладках дизайна материалов /viewpager
Очень хороший сайт о решениях для Android. Надеюсь, вы найдете решение.
Ответ 11
Расширьте основное действие из FragmentActivity. Также реализуйте этот класс из ActionBar.TabListener, поскольку мы добавляем вкладки
//Для добавления вкладок
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setIcon(R.drawable.drawable_id)
.setTabListener(this));
}
Отметьте здесь.