繁体   English   中英

借助 BottomNavigationBar 在片段之间滑动

[英]Swipe between fragments with help of BottomNavigationBar

我很难找到一个关于如何在bottom navigatiom bar的帮助下在fragments之间滑动的好例子。 由于不推荐使用FragmentStatePagerAdapter并且现在建议使用新的ViewPager2而不是旧的 ViewPager 我想在我的代码中使用ViewPager2FragmentStateAdapter 我在这里找到了如何结合 BottomNavigationBar 和 ViewPager 的示例,我想做类似的事情。 我的代码与示例中的代码有许多相似之处,唯一的区别是我将代码放在片段而不是活动中。 这是我的 FrontendFragment 显示效果的图片 我可以使用底部导航栏在视图之间切换,但我也希望能够在视图之间滑动。 有人可以帮助我或至少指导我正确的方式吗? 这是我的代码:

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 以便它们相应地打开/关闭视图可见性。 例如,按顺序存储视图并通过数组索引控制它们。 在我看来,你试图做的整个事情通常都不是一个好的设计模式。

为什么不加载另一个活动 onClick 而不是拥挤你的单个活动? 这将导致加载时间问题。 即使视图是不可见的,将所有这些都保存在一个地方也只是一件麻烦事。

由于我已经在我的一个应用程序中使用带有 ViewPager2 的 BottomNav,我可以提供帮助。

您的代码部分正确,这意味着您的FragmentPagerAdapter很好,但不是您的FrontEndFragment

看, FragmentPagerAdapter必须设置为ViewPager2

//this here is the FrontEndFragment 
mViewPager2.setAdapter(new FragmentPagerAdapter(this));

然后,您根本不必执行 FragmentTransaction,您只需通过BottomNavigationBarViewPager2的当前项目 position 更改为

@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()); 这不是必需的,也不需要 function loadFragment()

(可选)此外,如果您想禁用ViewPager2的 Swipe Action 并希望仅基于 Selected BottomNav 项选择 Fragments,则可以将 ViewPager2 的ViewPager2 setUserInputEnabled()属性设置为false


接下来,要根据 ViewPager2 的滑动将BottomNavigationBar的项目设置为选中ViewPager2 ,您需要做的是,

创建一个全局变量

MenuItem previousMenuItem;

然后,设置一个默认项(第一个)以在活动开始时选择 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。 这是实现目标所需的完整代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM