BottomNavigation+ViewPager实现App底部切换页面

本文介绍了一种在Android应用中自定义ViewPager与BottomNavigationView组件的方法,通过禁用ViewPager的水平滑动并实现Fragment与底部导航栏之间的联动。文章详细解释了如何创建NoScrollViewPager类来替代标准的ViewPager行为,以及如何通过BaseFragmentAdapter适配器管理和切换不同Fragment。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<com.geniusphone.xdd.weight.NoScrollViewPager
        android:id="@+id/vp_home_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>


    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:elevation="15dp"
        android:background="#fff"
        app:itemIconSize="21dp"
        app:itemTextColor="@color/home_tab_text_color"
        app:menu="@menu/home_bottom_tab" />
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/item_home"
        android:icon="@drawable/radio_rb_home_selector"
        android:title="首页" />
    <item
        android:id="@+id/item_find"
        android:icon="@drawable/radio_rb_find_selector"
        android:title="发现" />
    <item
        android:id="@+id/item_mine"
        android:icon="@drawable/radio_rb_mine_selector"
        android:title="我的" />
</menu>
 		homeNavView = findViewById(R.id.bottomNavigationView);
        mViewPager = findViewById(R.id.vp_home_pager);
        homeNavView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
        homeNavView.setItemHorizontalTranslationEnabled(false);
        homeNavView.setItemIconTintList(null);
        homeNavView.setSelectedItemId(R.id.item_home);
  // 设置默认进来是tab 显示的页面
    private void setDefaultFragment() {
        mPagerAdapter = new BaseFragmentAdapter<>(this);
        mPagerAdapter.addFragment(HomeFragment.newInstance());
        mPagerAdapter.addFragment(FindFragment.newInstance());
        mPagerAdapter.addFragment(MineFragment.newInstance());
        mViewPager.setAdapter(mPagerAdapter);
        // 限制页面数量
        mViewPager.setOffscreenPageLimit(mPagerAdapter.getCount());
    }
homeNavView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.item_home:
                        mPagerAdapter.setCurrentItem(HomeFragment.class);
                        return true;
                    case R.id.item_find:
                        mPagerAdapter.setCurrentItem(FindFragment.class);
                        return true;
                    case R.id.item_mine:
                        mPagerAdapter.setCurrentItem(MineFragment.class);
                        return true;
                    default:
                        break;
                }
                return false;
            }
        });
 @Override
    public void onSoftKeyboardOpened(int keyboardHeight) {
        homeNavView.setVisibility(View.GONE);
    }
    @Override
    public void onSoftKeyboardClosed() {
        homeNavView.setVisibility(View.VISIBLE);
    }
    @Override
    protected void onDestroy() {
        mViewPager.setAdapter(null);
        homeNavView.setOnNavigationItemSelectedListener(null);
        super.onDestroy();
    }
//FragmentPagerAdapter 基类
public class BaseFragmentAdapter<F extends Fragment> extends FragmentPagerAdapter {

    /** Fragment集合 */
    private final List<F> mFragmentSet = new ArrayList<>();

    /** 当前显示的Fragment */
    private F mCurrentFragment;

    /** 当前 ViewPager */
    private ViewPager mViewPager;

    public BaseFragmentAdapter(FragmentActivity activity) {
        this(activity.getSupportFragmentManager());
    }

    public BaseFragmentAdapter(Fragment fragment) {
        this(fragment.getChildFragmentManager());
    }

    public BaseFragmentAdapter(FragmentManager manager) {
        this(manager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
    }

    public BaseFragmentAdapter(FragmentManager manager, int behavior) {
        super(manager, behavior);
    }

    @NonNull
    @Override
    public F getItem(int position) {
        return mFragmentSet.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentSet.size();
    }

    @SuppressWarnings("unchecked")
    @Override
    public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        if (getCurrentFragment() != object) {
            // 记录当前的Fragment对象
            mCurrentFragment = (F) object;
        }
        super.setPrimaryItem(container, position, object);
    }

    public void addFragment(F fragment) {
        mFragmentSet.add(fragment);
    }

    /**
     * 获取Fragment集合
     */
    public List<F> getAllFragment() {
        return mFragmentSet;
    }

    /**
     * 获取当前的Fragment
     */
    public F getCurrentFragment() {
        return mCurrentFragment;
    }

    @Override
    public void startUpdate(@NonNull ViewGroup container) {
        super.startUpdate(container);
        if (container instanceof ViewPager) {
            // 记录绑定 ViewPager
            mViewPager = (ViewPager) container;
        }
    }

    /**
     * 设置当前条目
     *
     * @param clazz             欲切换的 Fragment
     */
    public void setCurrentItem(Class<? extends F> clazz) {
        for (int i = 0; i < mFragmentSet.size(); i++) {
            if (mFragmentSet.get(i).getClass() == clazz) {
                setCurrentItem(i);
                break;
            }
        }
    }

    public void setCurrentItem(int position) {
        if (mViewPager != null) {
            mViewPager.setCurrentItem(position);
        }
    }

    public void setCurrentItem(int position, boolean smoothScroll) {
        if (mViewPager != null) {
            mViewPager.setCurrentItem(position, smoothScroll);
        }
    }
}
//禁用水平滑动的ViewPager(一般用于 APP 主页的 ViewPager + Fragment)
public final class NoScrollViewPager extends ViewPager {

    public NoScrollViewPager(Context context) {
        super(context);
    }

    public NoScrollViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // 不拦截这个事件
        return false;
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // 不处理这个事件
        return false;
    }

    @Override
    public boolean executeKeyEvent(@NonNull KeyEvent event) {
        // 不响应按键事件
        return false;
    }

    @Override
    public void setCurrentItem(int item) {
        boolean smoothScroll;
        int currentItem = getCurrentItem();
        if (currentItem == 0) {
            // 如果当前是第一页,只有第二页才会有动画
            smoothScroll = item == currentItem + 1;
        } else if (currentItem == getCount() - 1) {
            // 如果当前是最后一页,只有最后第二页才会有动画
            smoothScroll = item == currentItem - 1;
        } else {
            // 如果当前是中间页,只有相邻页才会有动画
            smoothScroll = Math.abs(currentItem - item) == 1;
        }
        super.setCurrentItem(item, smoothScroll);
    }

    public int getCount() {
        PagerAdapter adapter = getAdapter();
        return adapter != null ? adapter.getCount() : 0;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值