Android 底部导航栏实现

依赖库

    implementation "androidx.viewpager2:viewpager2:1.0.0"

fragment基类

/**
 * Fragment的基类
 *
 * @param <DB> data binding
 * @param <VM> view model
 * @author shizhiyin
 */
public abstract class BaseFragment<DB extends ViewDataBinding, VM extends BaseViewModel>
        extends Fragment {

    protected DB mDataBinding;

    protected VM mViewModel;

    private FragmentBaseBinding mFragmentBaseBinding;

    private ViewLoadingBinding mViewLoadingBinding;

    private ViewLoadErrorBinding mViewLoadErrorBinding;

    private ViewNoNetworkBinding mViewNoNetworkBinding;

    private ViewNoDataBinding mViewNoDataBinding;


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        if (args != null) {
            handleArguments(args);
        }

        initViewModel();

        // ViewModel订阅生命周期事件
        if (mViewModel != null) {
            getLifecycle().addObserver(mViewModel);
        }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mFragmentBaseBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_base, container, false);
        mDataBinding = DataBindingUtil.inflate(inflater, getLayoutResId(),
                mFragmentBaseBinding.flContentContainer, true);
        bindViewModel();
        mDataBinding.setLifecycleOwner(this);
        initLoadState();

        initCollectState();

        init();

        return mFragmentBaseBinding.getRoot();
    }

    private void initLoadState() {
        if (mViewModel != null && isSupportLoad()) {
            mViewModel.loadState.observe(getViewLifecycleOwner(), new Observer<LoadState>() {
                @Override
                public void onChanged(LoadState loadState) {
                    switchLoadView(loadState);
                }
            });

        }
    }


    /**
     * 根据加载状态 , 切换不同的View
     *
     * @param loadState
     */
    private void switchLoadView(LoadState loadState) {
        removeLoadView();

        switch (loadState) {
            case LOADING:
                if (mViewLoadingBinding == null) {
                    mViewLoadingBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_loading,
                            mFragmentBaseBinding.flContentContainer, false);
                }
                mFragmentBaseBinding.flContentContainer.addView(mViewLoadingBinding.getRoot());
                break;

            case NO_NETWORK:
                if (mViewNoNetworkBinding == null) {
                    mViewNoNetworkBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_no_network,
                            mFragmentBaseBinding.flContentContainer, false);
                    mViewNoNetworkBinding.setViewModel(mViewModel);
                }
                mFragmentBaseBinding.flContentContainer.addView(mViewNoNetworkBinding.getRoot());
                break;

            case NO_DATA:
                if (mViewNoDataBinding == null) {
                    mViewNoDataBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_no_data,
                            mFragmentBaseBinding.flContentContainer, false);
                }
                mFragmentBaseBinding.flContentContainer.addView(mViewNoDataBinding.getRoot());
                break;

            case ERROR:
                if (mViewLoadErrorBinding == null) {
                    mViewLoadErrorBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_load_error,
                            mFragmentBaseBinding.flContentContainer, false);
                    mViewLoadErrorBinding.setViewModel(mViewModel);
                }
                mFragmentBaseBinding.flContentContainer.addView(mViewLoadErrorBinding.getRoot());
                break;

            default:
                break;
        }
    }


    private void removeLoadView() {
        int childCount = mFragmentBaseBinding.flContentContainer.getChildCount();
        if (childCount > 1) {
            mFragmentBaseBinding.flContentContainer.removeViews(1, childCount - 1);
        }
    }

    @SuppressLint("FragmentLiveDataObserve")
    private void initCollectState() {
        if (mViewModel == null) {
            return;
        }
        mViewModel.getCollectStatus().observe(this, new Observer<Object>() {
            @Override
            public void onChanged(Object collect) {
                if (collect == null) {
                
                    //跳转到登录界面
                    LoginActivity.start(getActivity());
                }
            }
        });
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        // ViewModel订阅生命周期事件
        if (mViewModel != null) {
            getLifecycle().removeObserver(mViewModel);
        }
        removeLoadView();
    }


    /**
     * 处理参数
     *
     * @param args 参数容器
     */
    protected void handleArguments(Bundle args) {

    }


    /**
     * 是否支持页面加载。默认不支持
     *
     * @return true表示支持,false表示不支持
     */
    protected boolean isSupportLoad() {
        return false;
    }

    /**
     * 获取当前页面的布局资源ID
     *
     * @return 布局资源ID
     */
    protected abstract int getLayoutResId();

    /**
     * 初始化ViewModel
     */
    protected abstract void initViewModel();

    /**
     * 绑定ViewModel
     */
    protected abstract void bindViewModel();

    /**
     * 初始化
     */
    protected abstract void init();
}

baseActivity

/**
 * Activity的基类
 *
 * @param <DB> data binding
 * @param <VM> view model
 * @author shizhiyin
 */
public abstract class BaseActivity<DB extends ViewDataBinding, VM extends BaseViewModel>
        extends AppCompatActivity {

    public DB mDataBinding;

    protected VM mViewModel;

    private ActivityBaseBinding mActivityBaseBinding;

    private ViewLoadingBinding mViewLoadingBinding;

    private ViewLoadErrorBinding mViewLoadErrorBinding;

    private ViewNoNetworkBinding mViewNoNetworkBinding;

    private ViewNoDataBinding mViewNoDataBinding;

    private BatteryReceiver receiver;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        handleIntent(getIntent());

        if (isNoActionBar()) {
            setNoActionBar();
        }

        mActivityBaseBinding = DataBindingUtil.setContentView(this, R.layout.activity_base);
        mDataBinding = DataBindingUtil.inflate(getLayoutInflater(), getLayoutResId(),
                mActivityBaseBinding.flContentContainer, true);

        initViewModel();
        bindViewModel();

        mDataBinding.setLifecycleOwner(this);

        initLoadState();
        init();

        //注册设备电池监听广播

        receiver = new BatteryReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                super.onReceive(context, intent);

                BatteryManager batteryManager = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
                int batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
//                int battery = batteryManager.getIntProperty(BatteryManager.BATTERY_STATUS_CHARGING);
                int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);

                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                    boolean isCharging = false;

                    if (status == 2) {
                        isCharging = true;
                    }

                    handtBatteryData(batteryLevel, isCharging);
                }

                //wifi监测
                Boolean isWifiConnected = isNetworkAvailable(context);

                if (!isWifiConnected) {//没连网络
                    handtWifiData(false, 1);

                } else {//已连网络
                    handtWifiData(true, 2);
                }

            }
        };
        IntentFilter filter2 = new IntentFilter();
        filter2.addAction(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(receiver, filter2);

        // ViewModel订阅生命周期事件
        if (mViewModel != null) {
            getLifecycle().addObserver(mViewModel);
        }
    }

    /**
     * 设置沉浸式状态栏
     */
    private void setNoActionBar() {
        Window window = getWindow();
        View decorView = window.getDecorView();
        int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        }
    }


    private void initLoadState() {
        if (mViewModel != null && isSupportLoad()) {
            mViewModel.loadState.observe(this, new Observer<LoadState>() {
                @Override
                public void onChanged(LoadState loadState) {
                    switchLoadView(loadState);
                }
            });
        }
    }

    private void removeLoadView() {
        int childCount = mActivityBaseBinding.flContentContainer.getChildCount();
        if (childCount > 1) {
            mActivityBaseBinding.flContentContainer.removeViews(1, childCount - 1);
        }
    }

    private void switchLoadView(LoadState loadState) {
        removeLoadView();

        switch (loadState) {
            case LOADING:
                if (mViewLoadingBinding == null) {
                    mViewLoadingBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_loading,
                            mActivityBaseBinding.flContentContainer, false);
                }
                mActivityBaseBinding.flContentContainer.addView(mViewLoadingBinding.getRoot());
                break;

            case NO_NETWORK:
                if (mViewNoNetworkBinding == null) {
                    mViewNoNetworkBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_no_network,
                            mActivityBaseBinding.flContentContainer, false);
                    mViewNoNetworkBinding.setViewModel(mViewModel);
                }
                mActivityBaseBinding.flContentContainer.addView(mViewNoNetworkBinding.getRoot());
                break;

            case NO_DATA:
                if (mViewNoDataBinding == null) {
                    mViewNoDataBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_no_data,
                            mActivityBaseBinding.flContentContainer, false);
                }
                mActivityBaseBinding.flContentContainer.addView(mViewNoDataBinding.getRoot());
                break;

            case ERROR:
                if (mViewLoadErrorBinding == null) {
                    mViewLoadErrorBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_load_error,
                            mActivityBaseBinding.flContentContainer, false);
                }
                mActivityBaseBinding.flContentContainer.addView(mViewLoadErrorBinding.getRoot());
                break;

            default:
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

    /**
     * 电池
     * 连接状态
     */
    protected void handtBatteryData(int batteryLevel, boolean isCharging) {

    }

    /**
     * wifi
     * 连接状态
     */
    protected void handtWifiData(boolean isConnected, int level) {

    }

    /**
     * 处理参数
     *
     * @param intent 参数容器
     */
    protected void handleIntent(Intent intent) {

    }

    /**
     * 是否为沉浸模式
     *
     * @return true表示支持,false表示不支持
     */
    protected boolean isNoActionBar() {
        return false;
    }


    /**
     * 是否支持页面加载。默认不支持
     *
     * @return true表示支持,false表示不支持
     */
    protected boolean isSupportLoad() {
        return false;
    }

    /**
     * 获取当前页面的布局资源ID
     *
     * @return 布局资源ID
     */
    protected abstract int getLayoutResId();

    /**
     * 初始化ViewModel
     */
    protected abstract void initViewModel();

    /**
     * 绑定ViewModel
     */
    protected abstract void bindViewModel();

    /**
     * 初始化
     */
    protected abstract void init();

}

一、Fragment + TextView 实现

1、主界面

/**
 * 主界面
 */
public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> {

    public static void start(Context context, Boolean isLogin) {
        Intent intent = new Intent(context, MainActivity.class);
        intent.putExtra(Constants.ParamCode.PARAM1, isLogin);
        context.startActivity(intent);
    }

    @Override
    protected void handleIntent(Intent intent) {

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


    }

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_main;
    }

    @Override
    protected void initViewModel() {
        mViewModel = new ViewModelProvider(this).get(MainViewModel.class);
    }

    @Override
    protected void bindViewModel() {

    }

    private List<Fragment> fragmentList;
    private ContentPagerAdapter contentPagerAdapter;

    @Override
    protected void init() {
        initView();

        fragmentList = new ArrayList<>();

        fragmentList.add(new HomeFragment());
        fragmentList.add(new ShoppingFragment());
        fragmentList.add(new LifeServicesFragment());
        fragmentList.add(new EduStewarFragment());
        fragmentList.add(new PersonCenterFragment());

        contentPagerAdapter = new ContentPagerAdapter(this, fragmentList);
        mDataBinding.viewPager.setAdapter(contentPagerAdapter);

        mDataBinding.textViewHome.setOnClickListener(v -> mDataBinding.viewPager.setCurrentItem(0, false));
        mDataBinding.textViewShopping.setOnClickListener(v -> mDataBinding.viewPager.setCurrentItem(1, false));
        mDataBinding.textViewLifeServices.setOnClickListener(v -> mDataBinding.viewPager.setCurrentItem(2, false));
        mDataBinding.textviewEduStewar.setOnClickListener(v -> mDataBinding.viewPager.setCurrentItem(3, false));
        mDataBinding.textviewPersonCenter.setOnClickListener(v -> mDataBinding.viewPager.setCurrentItem(4, false));

        mDataBinding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // 当页面滑动时调用
                super.onPageScrolled(position, positionOffset, positionOffsetPixels);

                changeState(position);
            }

            @Override
            public void onPageSelected(int position) {
                // 当页面被选中时调用
                super.onPageSelected(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                // 当页面滑动状态改变时调用
                super.onPageScrollStateChanged(state);
            }
        });
    }


    /**
     * 改变
     * 导航栏样式
     */
    private void changeState(int position) {

        mDataBinding.textViewHome.setTextColor(Color.parseColor("#93A5EE"));
        mDataBinding.textViewShopping.setTextColor(Color.parseColor("#93A5EE"));
        mDataBinding.textViewLifeServices.setTextColor(Color.parseColor("#93A5EE"));
        mDataBinding.textviewEduStewar.setTextColor(Color.parseColor("#93A5EE"));
        mDataBinding.textviewPersonCenter.setTextColor(Color.parseColor("#93A5EE"));

        switch (position) {
            case 0:
                mDataBinding.textViewHome.setTextColor(Color.parseColor("#52FDFF"));
                break;
            case 1:
                mDataBinding.textViewShopping.setTextColor(Color.parseColor("#52FDFF"));
                break;
            case 2:
                mDataBinding.textViewLifeServices.setTextColor(Color.parseColor("#52FDFF"));
                break;
            case 3:
                mDataBinding.textviewEduStewar.setTextColor(Color.parseColor("#52FDFF"));
                break;
            case 4:
                mDataBinding.textviewPersonCenter.setTextColor(Color.parseColor("#52FDFF"));
                break;
            default:
                mDataBinding.textViewHome.setTextColor(Color.parseColor("#52FDFF"));
                break;
        }

    }

    @Override
    protected void onResume() {
        super.onResume();

    }


    /**
     * 初始view
     */
    private void initView() {

    }


    @Override
    public void onBackPressed() {
//        super.onBackPressed();
    }
}

2、xml布局

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="@dimen/dp_640"
        android:layout_height="@dimen/dp_400">

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewPager"
            android:layout_width="@dimen/dp_640"
            android:layout_height="350dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <LinearLayout
            android:id="@+id/bottom_navigation"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:background="#00064F"
            android:orientation="horizontal"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent">

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center">

                <TextView
                    android:id="@+id/textViewHome"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:clickable="true"
                    android:focusable="true"
                    android:gravity="center"
                    android:text="首页"
                    android:textColor="#52FDFF"
                    android:textSize="@dimen/sp_10" />
            </LinearLayout>

            <TextView
                android:id="@+id/textViewShopping"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:clickable="true"
                android:focusable="true"
                android:gravity="center"
                android:text="商城"
                android:textColor="#52FDFF"
                android:textSize="@dimen/sp_10" />

            <TextView
                android:id="@+id/textViewLifeServices"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:clickable="true"
                android:focusable="true"
                android:gravity="center"
                android:text="服务"
                android:textColor="#52FDFF"
                android:textSize="@dimen/sp_10" />

            <TextView
                android:id="@+id/textviewEduStewar"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:clickable="true"
                android:focusable="true"
                android:gravity="center"
                android:text="管家"
                android:textColor="#52FDFF"
                android:textSize="@dimen/sp_10" />

            <TextView
                android:id="@+id/textviewPersonCenter"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:clickable="true"
                android:focusable="true"
                android:gravity="center"
                android:text="个人"
                android:textColor="#52FDFF"
                android:textSize="@dimen/sp_10" />

        </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

3、首页

3.1 fragment代码

public class HomeFragment extends BaseFragment<HomeFragmentLayoutBinding,HomeFragmentViewmodel> {

    @Override
    protected int getLayoutResId() {
        return R.layout.home_fragment_layout;
    }

    @Override
    protected void initViewModel() {

    }

    @Override
    protected void bindViewModel() {

    }

    @Override
    protected void init() {

    }
}

3.2 布局代码

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

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="@dimen/dp_640"
        android:layout_height="@dimen/dp_400"
        android:background="@color/color_red">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="首页"
            android:textColor="@color/white"
            android:textSize="@dimen/sp_16"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

4、商场页面

4.1fragment代码

public class ShoppingFragment extends BaseFragment<ShoppingFragmentLayoutBinding, ShoppingFragmentViewModel> {

    @Override
    protected int getLayoutResId() {
        return R.layout.shopping_fragment_layout;
    }

    @Override
    protected void initViewModel() {

    }

    @Override
    protected void bindViewModel() {

    }

    @Override
    protected void init() {

    }

}

4.2布局代码

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

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="@dimen/dp_640"
        android:layout_height="@dimen/dp_400"
        android:background="@color/green">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="小雅购物"
            android:textColor="@color/white"
            android:textSize="@dimen/sp_16"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

5、服务页面

5.1服务fragment

public class LifeServicesFragment extends BaseFragment<LifeServicesFragmentLayoutBinding, LifeServicesFragmentViewmodel> {

    @Override
    protected int getLayoutResId() {
        return R.layout.life_services_fragment_layout;
    }

    @Override
    protected void initViewModel() {

    }

    @Override
    protected void bindViewModel() {

    }

    @Override
    protected void init() {

    }

}

5.2服务布局页面

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

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="@dimen/dp_640"
        android:layout_height="@dimen/dp_400"
        android:background="@color/color_red">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="生活服务"
            android:textColor="@color/white"
            android:textSize="@dimen/sp_16"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

6、教育页面

6.1教育fragment代码

/**
 * 教育管家
 */
public class EduStewarFragment extends BaseFragment<EduStewarFragmentLayoutBinding, EduStewarFragmentViewmodel> {

    @Override
    protected int getLayoutResId() {
        return R.layout.edu_stewar_fragment_layout;
    }

    @Override
    protected void initViewModel() {

    }

    @Override
    protected void bindViewModel() {

    }

    @Override
    protected void init() {

    }

}

6.2教育布局代码

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

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="@dimen/dp_640"
        android:layout_height="@dimen/dp_400"
        android:background="@color/color_red">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="教育管家"
            android:textColor="@color/white"
            android:textSize="@dimen/sp_16"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

7、个人中心

7.1个人中心fragment

public class PersonCenterFragment extends BaseFragment<PersonCenterBinding,PersonCenterVieMOdel> {

    @Override
    protected int getLayoutResId() {
        return R.layout.person_center;
    }

    @Override
    protected void initViewModel() {

    }

    @Override
    protected void bindViewModel() {

    }

    @Override
    protected void init() {

    }
}

7.2个人中心布局页面

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

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="@dimen/dp_640"
        android:layout_height="@dimen/dp_400">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="个人中心"
            android:textColor="@color/black"
            android:textSize="@dimen/sp_16"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"  />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

二、RadioGroup + ViewPager 实现

三、BottomNavigationView+ViewPager+fragment 实现

四、TabLayout+fragment+viewPager 实现

相关推荐
数据猎手小k4 分钟前
AndroidLab:一个系统化的Android代理框架,包含操作环境和可复现的基准测试,支持大型语言模型和多模态模型。
android·人工智能·机器学习·语言模型
你的小1039 分钟前
JavaWeb项目-----博客系统
android
风和先行1 小时前
adb 命令查看设备存储占用情况
android·adb
AaVictory.2 小时前
Android 开发 Java中 list实现 按照时间格式 yyyy-MM-dd HH:mm 顺序
android·java·list
似霰3 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder
大风起兮云飞扬丶3 小时前
Android——网络请求
android
干一行,爱一行3 小时前
android camera data -> surface 显示
android
断墨先生3 小时前
uniapp—android原生插件开发(3Android真机调试)
android·uni-app
无极程序员5 小时前
PHP常量
android·ide·android studio
萌面小侠Plus6 小时前
Android笔记(三十三):封装设备性能级别判断工具——低端机还是高端机
android·性能优化·kotlin·工具类·低端机