How do I get the view of a Tab in a TabLayout?
Solution 1
I ended up using the following to get tab views. I'm just not sure if it's best practice or if it's reliable across all Android versions:
mainTab = ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(desiredPosition);
Looking at source we can see that tabLayout.getChildAt(0)
returns the SlidingTabStrip
which is an internal class extending LinearLayout
that holds the tab views. Then, you can access the tab view with .getChildAt(desiredPosition)
. Note that when using getChildAt()
boundaries are not being checked, so make sure you are calling correct indexes and also check for null
returns.
Solution 2
TabLayout tabLayout = .... (findview or code creation )
/** get selected tab index */
int selectedTabPosition = tabLayout.getSelectedTabPosition();
/** get tab for selected index or if u want any other tab set desired index */
TabLayout.Tab tabAt = tabLayout.getTabAt(selectedTabPosition);
/** get view - but first u need set custom view on tabl via Tab.setCustomView(View) */
View tabView = tabAt.getCustomView():
hint:
- if you populate
TabLayout
withViewPager
check first if view is laid out :). If not setonLayoutChangedListener
forViewPager
then setup with pager!
Tab
Source if you wish to use reflections :D
/**
* A tab in this layout. Instances can be created via {@link #newTab()}.
*/
public static final class Tab {
/**
* An invalid position for a tab.
*
* @see #getPosition()
*/
public static final int INVALID_POSITION = -1;
private Object mTag;
private Drawable mIcon;
private CharSequence mText;
private CharSequence mContentDesc;
private int mPosition = INVALID_POSITION;
private View mCustomView;
private final TabLayout mParent;
Tab(TabLayout parent) {
mParent = parent;
}
/**
* @return This Tab's tag object.
*/
@Nullable
public Object getTag() {
return mTag;
}
/**
* Give this Tab an arbitrary object to hold for later use.
*
* @param tag Object to store
* @return The current instance for call chaining
*/
@NonNull
public Tab setTag(@Nullable Object tag) {
mTag = tag;
return this;
}
/**
* Returns the custom view used for this tab.
*
* @see #setCustomView(View)
* @see #setCustomView(int)
*/
@Nullable
public View getCustomView() {
return mCustomView;
}
/**
* Set a custom view to be used for this tab.
* <p>
* If the provided view contains a {@link TextView} with an ID of
* {@link android.R.id#text1} then that will be updated with the value given
* to {@link #setText(CharSequence)}. Similarly, if this layout contains an
* {@link ImageView} with ID {@link android.R.id#icon} then it will be updated with
* the value given to {@link #setIcon(Drawable)}.
* </p>
*
* @param view Custom view to be used as a tab.
* @return The current instance for call chaining
*/
@NonNull
public Tab setCustomView(@Nullable View view) {
mCustomView = view;
if (mPosition >= 0) {
mParent.updateTab(mPosition);
}
return this;
}
/**
* Set a custom view to be used for this tab.
* <p>
* If the inflated layout contains a {@link TextView} with an ID of
* {@link android.R.id#text1} then that will be updated with the value given
* to {@link #setText(CharSequence)}. Similarly, if this layout contains an
* {@link ImageView} with ID {@link android.R.id#icon} then it will be updated with
* the value given to {@link #setIcon(Drawable)}.
* </p>
*
* @param layoutResId A layout resource to inflate and use as a custom tab view
* @return The current instance for call chaining
*/
@NonNull
public Tab setCustomView(@LayoutRes int layoutResId) {
return setCustomView(
LayoutInflater.from(mParent.getContext()).inflate(layoutResId, null));
}
/**
* Return the icon associated with this tab.
*
* @return The tab's icon
*/
@Nullable
public Drawable getIcon() {
return mIcon;
}
/**
* Return the current position of this tab in the action bar.
*
* @return Current position, or {@link #INVALID_POSITION} if this tab is not currently in
* the action bar.
*/
public int getPosition() {
return mPosition;
}
void setPosition(int position) {
mPosition = position;
}
/**
* Return the text of this tab.
*
* @return The tab's text
*/
@Nullable
public CharSequence getText() {
return mText;
}
/**
* Set the icon displayed on this tab.
*
* @param icon The drawable to use as an icon
* @return The current instance for call chaining
*/
@NonNull
public Tab setIcon(@Nullable Drawable icon) {
mIcon = icon;
if (mPosition >= 0) {
mParent.updateTab(mPosition);
}
return this;
}
/**
* Set the icon displayed on this tab.
*
* @param resId A resource ID referring to the icon that should be displayed
* @return The current instance for call chaining
*/
@NonNull
public Tab setIcon(@DrawableRes int resId) {
return setIcon(TintManager.getDrawable(mParent.getContext(), resId));
}
/**
* Set the text displayed on this tab. Text may be truncated if there is not room to display
* the entire string.
*
* @param text The text to display
* @return The current instance for call chaining
*/
@NonNull
public Tab setText(@Nullable CharSequence text) {
mText = text;
if (mPosition >= 0) {
mParent.updateTab(mPosition);
}
return this;
}
/**
* Set the text displayed on this tab. Text may be truncated if there is not room to display
* the entire string.
*
* @param resId A resource ID referring to the text that should be displayed
* @return The current instance for call chaining
*/
@NonNull
public Tab setText(@StringRes int resId) {
return setText(mParent.getResources().getText(resId));
}
/**
* Select this tab. Only valid if the tab has been added to the action bar.
*/
public void select() {
mParent.selectTab(this);
}
/**
* Returns true if this tab is currently selected.
*/
public boolean isSelected() {
return mParent.getSelectedTabPosition() == mPosition;
}
/**
* Set a description of this tab's content for use in accessibility support. If no content
* description is provided the title will be used.
*
* @param resId A resource ID referring to the description text
* @return The current instance for call chaining
* @see #setContentDescription(CharSequence)
* @see #getContentDescription()
*/
@NonNull
public Tab setContentDescription(@StringRes int resId) {
return setContentDescription(mParent.getResources().getText(resId));
}
/**
* Set a description of this tab's content for use in accessibility support. If no content
* description is provided the title will be used.
*
* @param contentDesc Description of this tab's content
* @return The current instance for call chaining
* @see #setContentDescription(int)
* @see #getContentDescription()
*/
@NonNull
public Tab setContentDescription(@Nullable CharSequence contentDesc) {
mContentDesc = contentDesc;
if (mPosition >= 0) {
mParent.updateTab(mPosition);
}
return this;
}
/**
* Gets a brief description of this tab's content for use in accessibility support.
*
* @return Description of this tab's content
* @see #setContentDescription(CharSequence)
* @see #setContentDescription(int)
*/
@Nullable
public CharSequence getContentDescription() {
return mContentDesc;
}
}
or you can hook directly into (via reflection):
private final SlidingTabStrip mTabStrip;
or you can copy source code and change methods and fields at your discretion.
NSouth
Updated on October 21, 2021Comments
-
NSouth over 2 years
I'd like to find the view of a Tab in a TabLayout so that I can pass it to another function. I'm not sure how to go about finding the view.
myTabLayout.getTabAt(0).getCustomView()
returns null.How do I get the view?
TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tab_layout_main); tabLayout.addTab(tabLayout.newTab().setText("Page1")); tabLayout.addTab(tabLayout.newTab().setText("Page2")); viewPager = (ViewPager) rootView.findViewById(R.id.pager_main); pagerAdapter = new MyPagerAdapter(getActivity(), getChildFragmentManager(), tabLayout.getTabCount()); viewPager.setAdapter(pagerAdapter);
-
NSouth over 8 yearsI figured that was the case, but I do not want to use a custom view. I'd like to get the default view used.
-
NSouth over 8 yearsUnfortunately, that gets me the
Tab
, not the view associated with the tab. -
ceph3us over 8 years@NSouth - tab layout - is that what is above pager content - pager content is fragment - u want pager content or tab content ? see edit
-
NSouth over 8 yearsThanks, this is a very informative answer. Yes, I want the tab's view (not the pager fragment content). This is the method I found to work, though I'm not sure that it's best practice.
mainTab = ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(0);
. I can't usegetCustomView()
because I never set a custom view. However, I could extend my own class if I need to. -
kushpf over 8 yearsWell, that helps. Thanks
-
GuillermoMP over 8 yearsgetCustomView() returns mCustomView which is null unless you assigned it before
-
fawaad about 8 yearsWhile this worked for me, I would hesitate before using this in a production app. It might cause some headaches down the road if Google ever changes the
Tab
layout functionality. Since it's mostly private, it's fairly likely. -
filthy_wizard about 7 yearshow to get the textview out? i need to chage the style in onCreate?