Android 底部导航栏实现

news/2024/8/22 21:11:33 标签: 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 实现


http://www.niftyadmin.cn/n/5556640.html

相关文章

【C++】——类和对象(中)

文章目录 类的默认成员函数构造函数析构函数拷贝构造函数赋值运算符重载运算符重载 const成员函数 类的默认成员函数 在C中&#xff0c;类&#xff08;class&#xff09;可以拥有多种成员函数&#xff0c;其中一些成员函数在类定义中没有显式声明时&#xff0c;编译器会隐式地…

java设计模式(二二)备忘录模式(Memeton Pattern)

1、模式介绍&#xff1a; 备忘录模式是一种行为设计模式&#xff0c;它允许在不破坏封装的前提下捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。 2、应用场景&#xff1a; 需要保存和恢复对象的历史状态&…

HC05主从一体蓝牙模块的裸机使用——单片机<-->蓝牙模块

HC-05是一种常用的蓝牙模块&#xff0c;具有低功耗、低成本、易于使用的特点。它可以实现与其他蓝牙设备&#xff08;如手机、电脑等&#xff09;进行无线通信。HC-05蓝牙模块具有串口通信接口&#xff0c;可以通过串口与主控制器&#xff08;如Arduino、Raspberry Pi等&#x…

【Linux】多线程_7

文章目录 九、多线程8. POSIX信号量根据信号量环形队列的生产者消费者模型代码结果演示 未完待续 九、多线程 8. POSIX信号量 POSIX信号量和SystemV信号量作用相同&#xff0c;都是用于同步操作&#xff0c;达到无冲突的访问共享资源目的。 但POSIX可以用于线程间同步。 创建…

jmeter-beanshell学习10-字符串补齐位数

每天都遇到新问题&#xff0c;今天又一个场景&#xff0c;一个字符串&#xff0c;如果不足11位&#xff0c;则左边补0&#xff0c;补够11位。 先要获取字符串长度&#xff0c;然后计算差多少位&#xff0c;补齐。今天又发现一个Object类型&#xff0c;这个类型有点厉害&#x…

设计模式-创建型模式之工厂方法模式

和简单工厂模式中工厂负责生产所有产品相比&#xff0c;工厂方法模式将生成具体产品的任务分发给具体的产品工厂&#xff0c;定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪个产品类对象。 工厂方法模式的主要角色: 抽象工厂(AbstractFactory):提供了创建产品的接…

【Pytorch实战教程】对抗样本生成中是如何添加噪声的?

文章目录 对抗样本中添加随机生成的对抗噪声代码解析应用场景示例代码对抗样本中添加随机生成的对抗噪声 通常在对抗训练或者生成对抗样本时使用,目的是为了稍微扰动模型的输入数据,从而测试或增强模型在面对输入数据轻微变化时的鲁棒性。 x = x + torch.zeros_like(x).uni…

Hadoop-29 ZooKeeper集群 Watcher机制 工作原理 与 ZK基本命令 测试集群效果 3台公网云服务器

章节内容 上节我们完成了&#xff1a; ZNode的基本介绍ZNode节点类型的介绍事务ID的介绍ZNode实机测试效果 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&#xff…