Android 使用 ViewPager 和 TabLayout 包装内容

Android using ViewPager and TabLayout wrap content

我遇到这种情况:

使用带有 TabLayout 的 ViewPager 的 Fragment,它占据了整个屏幕的宽度。像这样:

correctly formatted tabs

到目前为止,还不错。但在某些时候,选项卡会保留 wrap-content 并集中显示,如下所示:

wrongly formatted tabs

这不可能发生,我也不知道为什么会发生。它应该是 match_parent,如第一张图片所示。

如果有人能帮助我,我真的很感激。下面是片段的代码和xml:

public class RotativeInventorySupplyUDFragment extends AbstractNavFragment {

    private FragmentRotativeInventorySupplyBinding binder;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binder = FragmentRotativeInventorySupplyBinding.inflate(inflater, container, false);
        return binder.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        binder.viewPager.setAdapter(new RotativeInventorySupplyUDFragment.PageAdapterInternal(getChildFragmentManager()));
        binder.viewPager.setOffscreenPageLimit(2);
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);

        requireActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
            @Override
            public void handleOnBackPressed() { saveAndExit(); }
        });
    }

    public void navigateToCountFragment() {
        navigateTo(R.id.action_rotativeInventorySupplyUDFragment2_to_rotativeInventorySupplyCountFragment);
    }

    public void navigateToDetailFragment() {
        navigateTo(R.id.action_rotativeInventorySupplyUDFragment2_to_rotativeInventorySupplyDetailFragment);
    }

    private void navigateTo(int navigationId) {
        navigate(navigationId);
    }

    public void saveAndExit() {
        new LBMDialog.Builder(requireContext())
                .setTitle(translate("rotativeInventory.supply.attention"))
                .setCancelable(false)
                .setContent(translate("rotativeInventory.supply.stilUDPending") + "\n\n" + translate("rotativeInventory.supply.exitOrCount"))
                .setPrimaryFullWidthButton(new LBMDialog.LBMButtonInfo(translate("rotativeInventory.supply.continueCounting")) {
                    @Override
                    public void onClick() { }
                })
                .setSecondarySemiTransaparentButton(new LBMDialog.LBMButtonInfo(translate("rotativeInventory.supply.saveAndExit")) {
                    @Override
                    public void onClick() { navPop(); }
                })
                .setCloseIconVisibility(View.GONE)
                .swapButtons()
                .show(getChildFragmentManager());
    }

    @Override
    protected void doOnViewCreate() {}

    private class PageAdapterInternal extends FragmentStatePagerAdapter {

        public PageAdapterInternal(@NonNull FragmentManager fm) {
            super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new IrcSupplyUDFragment(IrcSupplyUDFragment.FragmentType.PENDING);
                case 1:
                    return new IrcSupplyUDFragment(IrcSupplyUDFragment.FragmentType.COMPLETED);
                default:
                    throw new IllegalStateException("Unexpected value: " + position);
            }
        }

        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 0:
                    return translate("rotativeInventory.supply.pendingDUs");
                case 1:
                    return translate("rotativeInventory.supply.completedDUs");
                default:
                    return "";
            }
        }

        @Override
        public int getCount() {
            return 2;
        }
    }
}


<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:ignore="MissingConstraints">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.constraintlayout.helper.widget.Flow
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            app:constraint_referenced_ids="viewPager"/>

        <androidx.viewpager.widget.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="0dp">

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:tabTextAppearance="@style/TabLayoutCustomTextAppearance"/>

        </androidx.viewpager.widget.ViewPager>

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

由于您没有 post 布局 xml,我假设您使用的是 MaterialTabLayout,您必须执行以下操作才能满足您的要求:

在您的 TabLayout 中,

  1. 放置android:layout_width="match_parent",以便布局占据其父级的整个宽度。

  2. app:tabMode="fixed" 放入您的 TabLayout 中,这是选项卡填充所必需的。

  3. 放入app:tabGravity="fill",这将占用每个 TabItem 的可用空间space。

     <com.google.android.material.tabs.TabLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:tabMode="fixed"
         app:tabGravity="fill">
    
         <com.google.android.material.tabs.TabItem
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="Tab 1" />
    
         <com.google.android.material.tabs.TabItem
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="Tab 2" />
    
     </com.google.android.material.tabs.TabLayout>