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 中,
放置android:layout_width="match_parent"
,以便布局占据其父级的整个宽度。
将 app:tabMode="fixed"
放入您的 TabLayout 中,这是选项卡填充所必需的。
放入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>
我遇到这种情况:
使用带有 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 中,
放置
android:layout_width="match_parent"
,以便布局占据其父级的整个宽度。将
app:tabMode="fixed"
放入您的 TabLayout 中,这是选项卡填充所必需的。放入
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>