Fragment 版本MVVM入门





第一章 代码结构

第01节 代码结构截图

在这里插入图片描述



第02节 结构说明

1. 模块级别的 build.gradle 需要加入  mvvm 的 gradle
2. 需要创建一个 Java类, 作为 ViewModel, 这个类的要求是 需要继承 androidx.lifecycle.ViewModel
3. 修改布局文件 fragment_demo.xml 将其修改成为mvvm的结构
4. 定义 Fragment 需要初始化 ViewModel 的操作
5. 在 MainActivity 当中, 替换容器成为 Fragment





第二章 代码详解

第01步 添加gradle

代码

buildFeatures {
    viewBinding true
}

dataBinding {
    enabled true
}

说明

1、位置说明:

​ 存在于 app 模块级别的 gradle 里面,需要放在 android{ … } 当中

2、原因说明:

​ 只有引入了当前的内容,后续的 MainActivity 当中才能自动创建具体的 Binding 类型



第02步 创建ViewModel类

代码

import android.util.Log;

import androidx.lifecycle.ViewModel;

public class DemoViewModel extends ViewModel {

    private static final String TAG = DemoViewModel.class.getSimpleName();

    // 增加了一个方法, 用于 布局当中的事件处理方案
    // 在布局当中采用属性, 绑定事件  android:onClick = "@{()->viewModel.show()}"
    public void show() {
        Log.i(TAG, "Hello This is My First Fragment type MVVM");
    }
}

说明

1、注意问题:

​ 这里的 ViewModel 需要继承的是 androidx.lifecycle.ViewModel 这个类

2、方法说明:

​ 这里的 show( ) 方法是后期为了给 控件 TextView 增加的点击事件处理。



第03步 布局文件修改

代码 activity 的布局文件 activity_main.xml,后期作为容器替换成为 Fragment

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" />

代码 fragment 的布局文件fragment_demo.xml,需要改造成为 mvvm 类型

<?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">

    <!--
    说明:
        1. 在 data 标签下面包含两个子标签, 他们分别是 import 和 variable
        2. 对于 import 标签而言, 可以省略不写, 写法是 ViewModel 的类全名, 作用: 简化 type 的书写
        3. 对于 variable 标签而言, 主要有两个属性, 分别是 name 和 type
            a. 其中 name 属性, 是给 ViewModel 取的别名, 在下面的布局文件当中, 可以进行引用, 调用
            b. 其中 type 属性, 是当前 ViewModel 的类型, 如果上面写了 import 可以简化书写
    -->
    <data>

        <import type="svip.chc.DemoViewModel" />

        <variable
            name="viewModel"
            type="DemoViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->viewModel.show()}"
            android:text="HelloWorld"
            android:textColor="#FF0000"
            android:textSize="60sp"
            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>

说明

1、结构说明

​		<layout>

​				<data>

​				</data>

​				<根布局>

​				</根布局>

​		</layout>

2、事件处理

​ 对于事件处理的方式存在多种写法,这里不做一一列举。

​ 目前采用的写法格式是 android:onclick="@{()->viewModel.show()}"

​ 在事件处理当中的 viewModel 是上面 <data></data>标签当中定义的 name 属性值



第04步 Activity 的容器替换

代码

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 替换 Fragment 的操作
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.container, new DemoFragment())
                .commitNow();
    }
}



第05步 Fragment 的改造实现

代码

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import svip.chc.databinding.FragmentDemoBinding;

public class DemoFragment extends Fragment {

    // 说明: 当前的 DemoViewModel 的对象
    private DemoViewModel viewModel;
    // 说明: FragmentDemoBinding 是根据布局文件的名称自动生成的对象
    private FragmentDemoBinding binding;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 1. 初始化 ViewModel 的对象
        viewModel = new ViewModelProvider(requireActivity()).get(DemoViewModel.class);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // 2. 初始化 binding 的对象
        binding = FragmentDemoBinding.inflate(getLayoutInflater(), container, false);
        // 3. 绑定 viewModel 和 bing 之间的关系
        binding.setViewModel(viewModel);
        // 4. 设置生命周期监听, 才能进行事件的监听效果
        binding.setLifecycleOwner(getViewLifecycleOwner());
        // 5. 获取到根视图的对象, 返回结果
        return binding.getRoot();
    }
}

说明

1、布局整改

​ 将原始的设置布局的方式,需要修改成为 return binding.getRoot();

2、对于成员变量需要定义两个

​ 他们分别是 bindingviewModel

​ 两个成员变量都要完成初始化的过程,以及初始化完毕之后的,绑定过程。

3、需要注意的两件事情:

​ 第一件事情: binding 的类型是自动生成的,他是在我们 appgralde 当中添加两段代码之后,才能自动生成

​ 第二讲事情: 如果没有设置生命周期的所有者,点击事件的监听会失效





第三章 效果展示

第01节 显示效果

在这里插入图片描述



第02节 点击处理

在这里插入图片描述





Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐