在 BottomNavigationBar 的帮助下在片段之间滑动
Swipe between fragments with help of BottomNavigationBar
我很难找到一个很好的例子来说明如何在 bottom navigatiom bar
的帮助下在 fragments
之间滑动。自 FragmentStatePagerAdapter is deprecated and a new ViewPager2 is now recommended instead of the old ViewPager I want to use ViewPager2 and FragmentStateAdapter in my code instead. I have found an example of how to combine BottomNavigationBar and ViewPager and I want to do something similar. My code have many similarities to the one in the example with the only difference that I have my code in a fragment instead of an activity. Here is a picture of how my FrontendFragment display look like。我可以使用 bottomnavigationbar 在视图之间切换,但我也希望能够在视图之间滑动。有人可以帮助我或至少以正确的方式指导我吗?这是我的代码:
FragmentPagerAdapter Class:
public class FragmentPagerAdapter extends FragmentStateAdapter {
private static final int mFragmentCount = 5;
public FragmentPagerAdapter(@NonNull Fragment fragment) {
super(fragment);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position){
case 0:
return new HomeFragment();
case 1:
return new SearchFragment();
case 2:
return new AddFragment();
case 3:
return new MessageFragment();
case 4:
return new ProfileFragment();
}
return null;
}
@Override
public int getItemCount() {
return mFragmentCount;
}
}
前端片段Class:
public class FrontendFragment extends Fragment implements BottomNavigationView.OnNavigationItemSelectedListener{
private BottomNavigationView mBottomNavigationView;
private ViewPager2 mViewPager2;
private FragmentPagerAdapter mFragmentPagerAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_frontend, container, false);
loadFragment(new HomeFragment());
mBottomNavigationView = v.findViewById(R.id.bottomNavigationBar);
mBottomNavigationView.setOnNavigationItemSelectedListener(this);
return v;
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.home_icon:
selectedFragment = new HomeFragment();
break;
case R.id.search_icon:
selectedFragment = new SearchFragment();
break;
case R.id.add_icon:
selectedFragment = new AddFragment();
break;
case R.id.message_icon:
selectedFragment = new MessageFragment();
break;
case R.id.profile_icon:
selectedFragment = new ProfileFragment();
break;
}
return loadFragment(selectedFragment);
}
private boolean loadFragment(Fragment selectedFragment) {
if(selectedFragment != null){
MainActivity.sFm.beginTransaction().replace(R.id.relLayoutMiddle, selectedFragment).commit();
return true;
}
return false;
}
}
提前致谢!
如果您想在视图之间滑动,一个简单的解决方案是将所有视图存储在您的父视图中,但将除初始视图之外的所有视图布局设置为 android:visibility="gone"
。不过请确保将初始视图布局设置为 android:visibility="visible"
。现在在您单击按钮时,您将必须实现 onClick 以便它们相应地打开/关闭视图可见性。例如,按顺序存储视图并通过数组索引控制它们。但是你试图做的整个事情通常不是一个好的设计模式 在我看来。
你为什么不加载另一个 Activity onClick 而不是挤满你的单曲 activity?这将导致加载时间问题。即使视图是不可见的,将所有这些维护在一个地方也只是一个整体的麻烦。
因为我已经在我的一个应用程序中使用 BottomNav 和 ViewPager2,所以我可以提供帮助。
您的代码部分正确,这意味着您的 FragmentPagerAdapter
没问题,但您的 FrontEndFragment
.
不正确
看,FragmentPagerAdapter
必须设置为 ViewPager2
as
//this here is the FrontEndFragment
mViewPager2.setAdapter(new FragmentPagerAdapter(this));
那么,你根本不用做FragmentTransaction,你只需要通过BottomNavigationBar
改变ViewPager2
的当前项目位置为
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.home_icon:
mViewPager2.setCurrentItem(0);
break;
case R.id.search_icon:
mViewPager2.setCurrentItem(1);
break;
case R.id.add_icon:
mViewPager2.setCurrentItem(2);
break;
case R.id.message_icon:
mViewPager2.setCurrentItem(3);
break;
case R.id.profile_icon:
mViewPager2.setCurrentItem(4);
break;
}
return false;
}
仅此而已,除了FragmentPagerAdapter
,您根本不需要处理Fragments
。另外,不要忘记删除不需要的 loadFragment(new HomeFragment());
,也不需要函数 loadFragment()
。
(可选),此外,如果您想禁用 ViewPager2
的滑动操作,并希望仅根据 Selected BottomNav 项目选择片段,则可以设置 setUserInputEnabled()
ViewPager2
的 属性 作为 false
。
接下来,要根据 ViewPager2
的滑动将 BottomNavigationBar
的项目设置为选中,您需要做的是,
创建全局变量
MenuItem previousMenuItem;
然后,在activity start as
上设置要选择的BottomNav 的默认项(第一个)
mBottomNavigationView.getMenu().getItem(0).setChecked(true);
最后,在 ViewPager2
上设置 OnPageSelected()
回调以将所选菜单项更新为:
mViewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
if (previousMenuItem != null) {
previousMenuItem.setChecked(false);
}
else {
mBottomNavigationView.getMenu().getItem(0).setChecked(false);
}
mBottomNavigationView.getMenu().getItem(position).setChecked(true);
previousMenuItem = mBottomNavigationView.getMenu().getItem(position);
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
你在这里做的是将默认项目设置为 previousMenuItem
然后滑动到另一个页面,取消选择 previousMenuItem
并选择新的,这意味着更新基于 ViewPager 当前项目的 BottomNav。这是实现 objective.
所需的完整代码
我很难找到一个很好的例子来说明如何在 bottom navigatiom bar
的帮助下在 fragments
之间滑动。自 FragmentStatePagerAdapter is deprecated and a new ViewPager2 is now recommended instead of the old ViewPager I want to use ViewPager2 and FragmentStateAdapter in my code instead. I have found an example of how to combine BottomNavigationBar and ViewPager
FragmentPagerAdapter Class:
public class FragmentPagerAdapter extends FragmentStateAdapter {
private static final int mFragmentCount = 5;
public FragmentPagerAdapter(@NonNull Fragment fragment) {
super(fragment);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position){
case 0:
return new HomeFragment();
case 1:
return new SearchFragment();
case 2:
return new AddFragment();
case 3:
return new MessageFragment();
case 4:
return new ProfileFragment();
}
return null;
}
@Override
public int getItemCount() {
return mFragmentCount;
}
}
前端片段Class:
public class FrontendFragment extends Fragment implements BottomNavigationView.OnNavigationItemSelectedListener{
private BottomNavigationView mBottomNavigationView;
private ViewPager2 mViewPager2;
private FragmentPagerAdapter mFragmentPagerAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_frontend, container, false);
loadFragment(new HomeFragment());
mBottomNavigationView = v.findViewById(R.id.bottomNavigationBar);
mBottomNavigationView.setOnNavigationItemSelectedListener(this);
return v;
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.home_icon:
selectedFragment = new HomeFragment();
break;
case R.id.search_icon:
selectedFragment = new SearchFragment();
break;
case R.id.add_icon:
selectedFragment = new AddFragment();
break;
case R.id.message_icon:
selectedFragment = new MessageFragment();
break;
case R.id.profile_icon:
selectedFragment = new ProfileFragment();
break;
}
return loadFragment(selectedFragment);
}
private boolean loadFragment(Fragment selectedFragment) {
if(selectedFragment != null){
MainActivity.sFm.beginTransaction().replace(R.id.relLayoutMiddle, selectedFragment).commit();
return true;
}
return false;
}
}
提前致谢!
如果您想在视图之间滑动,一个简单的解决方案是将所有视图存储在您的父视图中,但将除初始视图之外的所有视图布局设置为 android:visibility="gone"
。不过请确保将初始视图布局设置为 android:visibility="visible"
。现在在您单击按钮时,您将必须实现 onClick 以便它们相应地打开/关闭视图可见性。例如,按顺序存储视图并通过数组索引控制它们。但是你试图做的整个事情通常不是一个好的设计模式 在我看来。
你为什么不加载另一个 Activity onClick 而不是挤满你的单曲 activity?这将导致加载时间问题。即使视图是不可见的,将所有这些维护在一个地方也只是一个整体的麻烦。
因为我已经在我的一个应用程序中使用 BottomNav 和 ViewPager2,所以我可以提供帮助。
您的代码部分正确,这意味着您的 FragmentPagerAdapter
没问题,但您的 FrontEndFragment
.
看,FragmentPagerAdapter
必须设置为 ViewPager2
as
//this here is the FrontEndFragment
mViewPager2.setAdapter(new FragmentPagerAdapter(this));
那么,你根本不用做FragmentTransaction,你只需要通过BottomNavigationBar
改变ViewPager2
的当前项目位置为
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.home_icon:
mViewPager2.setCurrentItem(0);
break;
case R.id.search_icon:
mViewPager2.setCurrentItem(1);
break;
case R.id.add_icon:
mViewPager2.setCurrentItem(2);
break;
case R.id.message_icon:
mViewPager2.setCurrentItem(3);
break;
case R.id.profile_icon:
mViewPager2.setCurrentItem(4);
break;
}
return false;
}
仅此而已,除了FragmentPagerAdapter
,您根本不需要处理Fragments
。另外,不要忘记删除不需要的 loadFragment(new HomeFragment());
,也不需要函数 loadFragment()
。
(可选),此外,如果您想禁用 ViewPager2
的滑动操作,并希望仅根据 Selected BottomNav 项目选择片段,则可以设置 setUserInputEnabled()
ViewPager2
的 属性 作为 false
。
接下来,要根据 ViewPager2
的滑动将 BottomNavigationBar
的项目设置为选中,您需要做的是,
创建全局变量
MenuItem previousMenuItem;
然后,在activity start as
上设置要选择的BottomNav 的默认项(第一个)mBottomNavigationView.getMenu().getItem(0).setChecked(true);
最后,在 ViewPager2
上设置 OnPageSelected()
回调以将所选菜单项更新为:
mViewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
if (previousMenuItem != null) {
previousMenuItem.setChecked(false);
}
else {
mBottomNavigationView.getMenu().getItem(0).setChecked(false);
}
mBottomNavigationView.getMenu().getItem(position).setChecked(true);
previousMenuItem = mBottomNavigationView.getMenu().getItem(position);
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
你在这里做的是将默认项目设置为 previousMenuItem
然后滑动到另一个页面,取消选择 previousMenuItem
并选择新的,这意味着更新基于 ViewPager 当前项目的 BottomNav。这是实现 objective.