如何在TabLayout中获取一个选项卡的视图?

10

我想找到TabLayout中的一个选项卡的视图,以便将它传递给另一个函数。我不知道如何找到这个视图。 myTabLayout.getTabAt(0).getCustomView()返回 null。

我该如何获取这个视图?

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);
4个回答

55

我最终使用了以下代码来实现选项卡视图。我不确定这是否是最佳实践,也不确定在所有Android版本上是否可靠:

mainTab = ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(desiredPosition);

从源代码中可以看到tabLayout.getChildAt(0)返回SlidingTabStrip,它是一个内部类,继承自LinearLayout并持有选项卡视图。然后,您可以使用.getChildAt(desiredPosition)访问选项卡视图。请注意,在使用getChildAt()时,边界未被检查,因此请确保调用正确的索引,并检查是否返回了null


好的,这很有帮助。谢谢。 - kushpf
2
虽然这对我来说可行,但在生产应用程序中使用之前,我会犹豫一下。如果谷歌改变了Tab布局功能,它可能会在未来带来一些麻烦。由于它大多是私有的,这种情况相当可能发生。 - fawaad
如何获取TextView?我需要在onCreate中更改样式。 - filthy_wizard

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():

提示:

  • 如果您使用ViewPager填充TabLayout,请首先检查视图是否已布置:)。 如果没有,请为ViewPager设置onLayoutChangedListener,然后设置页码器!

Tab源代码(如果您希望使用反射):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;
    }
}

或者您可以直接通过反射进行连接:

private final SlidingTabStrip mTabStrip;

或者你可以复制源代码,根据自己的意愿更改方法和字段。

不幸的是,这只会给我“Tab”,而不是与选项卡相关联的视图。 - NSouth
@NSouth - 标签布局 - 是指页面内容上方的内容吗?页面内容是片段 - 您想要页面内容还是标签内容?请参见编辑 - ceph3us
谢谢,这是非常有用的回答。是的,我想要选项卡的视图(而不是分页器片段内容)。这是我发现可行的方法,但我不确定它是否是最佳实践。mainTab = ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(0);。我无法使用getCustomView(),因为我从未设置自定义视图。但是,如果需要,我可以扩展我的自己的类。 - NSouth
1
getCustomView() 返回 mCustomView,除非您之前分配了它,否则它将为 null。 - GuillermoMP

1

它返回null,因为你首先没有使用任何自定义视图。只有在使用自定义视图时才会返回自定义视图。要使用自定义视图,你的代码应该像这样。

tabLayout.addTab(tabLayout.newTab().setCustomView(R.layout.custom_view).setText("Page1"));

如果您使用以上代码行并尝试调用myTabLayout.getTabAt(0).getCustomView(),它将返回您设置的视图。

1
我想到了这种情况,但我不想使用自定义视图。我想要使用默认视图。 - NSouth

0

为了日后的参考而回答。

tabLayout.getTabAt(tabIndex).view

示例- 要获取tabLayout中第一个选项卡的视图,请使用tabLayout.getTabAt(0).view


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接