MVC/MVP/MVVM框架学习总结(二)

上次已经了解到MVC的知识,现在是扩展实现MVP/MVVM的框架改进本身项目

MVVM 框架即 Model-View-ViewModel 框架,是一种软件架构设计模式,以下是具体介绍:

核心组件

  • Model(模型):代表应用程序的数据结构和业务逻辑,负责数据的存储、检索、验证和处理,定义业务规则和算法,是应用程序的数据核心。比如在一个电商应用中,商品数据、用户订单数据等的存储和相关逻辑处理都属于 Model 层。
  • View(视图):是用户界面的可见部分,负责展示数据给用户,并接受用户输入,如 HTML 页面、移动应用中的 Activity、Fragment 等。在电商应用中,商品展示页面、订单结算页面等都是 View 的具体体现。
  • ViewModel(视图模型):作为 View 和 Model 之间的桥梁,从 Model 中获取数据,并将其转换为视图所需要的格式和结构,定义与视图交互的命令和操作,响应用户输入,实现数据绑定、验证和通知等功能。比如在商品展示页面中,将后端获取的商品数据处理成适合在页面上展示的格式,就是 ViewModel 的工作。

 下列是MVVM的关系图

MVC/MVP/MVVM框架学习总结(二)_第1张图片MVVM关系图 

 现在已经说明了理论知识,之后我将结合项目来实现MVVM框架

  首先第一步添加依赖

确保你的项目中已经添加了 ViewModel 和 LiveData 的依赖,在build.gradle文件中添加以下依赖:

implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'

  之后Model层不动,创建ModelView层

ViewModel 负责处理业务逻辑和数据,与视图层进行交互。以下是一个示例StoryViewModel

package com.example.sanhaijing.viewmodel;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.example.sanhaijing.model.banner.Story;
import com.example.sanhaijing.repository.StoryRepository;

import java.util.List;

public class StoryViewModel extends ViewModel {
    private MutableLiveData> storiesLiveData = new MutableLiveData<>();
    private StoryRepository storyRepository;

    public StoryViewModel() {
        storyRepository = new StoryRepository();
    }

    public LiveData> getStories() {
        if (storiesLiveData.getValue() == null) {
            loadStories();
        }
        return storiesLiveData;
    }

    private void loadStories() {
        // 从Repository中获取数据
        List stories = storyRepository.getAllStories();
        storiesLiveData.setValue(stories);
    }
}

完成后,创建Repository

Repository 负责数据的获取和管理,它可以从本地数据库、网络等数据源获取数据。以下是一个示例StoryRepository

package com.example.sanhaijing.repository;

import com.example.sanhaijing.model.banner.Story;
import com.example.sanhaijing.database.DatabaseHelper;

import java.util.List;

public class StoryRepository {
    private DatabaseHelper databaseHelper;

    public StoryRepository() {
        databaseHelper = new DatabaseHelper();
    }

    public List getAllStories() {
        return databaseHelper.getAllStories();
    }
}

实现上述功能,即可修改View层 

在 Activity 或 Fragment 中,使用 ViewModel 来获取数据,并观察数据的变化。以下是修改后的StoryFragment示例:

package com.example.sanhaijing.view.fragment;

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

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.sanhaijing.R;
import com.example.sanhaijing.controller.home_adapter.StoryAdapter;
import com.example.sanhaijing.model.banner.Story;
import com.example.sanhaijing.viewmodel.StoryViewModel;

import java.util.List;

public class StoryFragment extends Fragment {
    private RecyclerView rvStories;
    private StoryAdapter storyAdapter;
    private StoryViewModel storyViewModel;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_story, container, false);

        initializeViews(view);
        setupViewModel();

        return view;
    }

    private void initializeViews(View view) {
        rvStories = view.findViewById(R.id.rvStories);
        rvStories.setLayoutManager(new LinearLayoutManager(getContext()));
    }

    private void setupViewModel() {
        storyViewModel = new ViewModelProvider(this).get(StoryViewModel.class);
        storyViewModel.getStories().observe(getViewLifecycleOwner(), new Observer>() {
            @Override
            public void onChanged(List stories) {
                if (stories != null) {
                    if (storyAdapter == null) {
                        storyAdapter = new StoryAdapter(stories);
                        storyAdapter.setOnStoryClickListener(story -> {
                            // 处理故事点击事件
                            Toast.makeText(getContext(), "点击了故事:" + story.getName(), Toast.LENGTH_SHORT).show();
                        });
                        rvStories.setAdapter(storyAdapter);
                    } else {
                        storyAdapter.setStories(stories);
                        storyAdapter.notifyDataSetChanged();
                    }
                }
            }
        });
    }
}

并且可以修改adapter类代码

package com.example.sanhaijing.controller.home_adapter;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.example.sanhaijing.R;
import com.example.sanhaijing.model.banner.Story;

import java.util.List;

public class StoryAdapter extends RecyclerView.Adapter {
    private List stories;
    private OnStoryClickListener listener;

    public interface OnStoryClickListener {
        void onStoryClick(Story story);
    }

    public StoryAdapter(List stories) {
        this.stories = stories;
    }

    public void setStories(List stories) {
        this.stories = stories;
    }

    public void setOnStoryClickListener(OnStoryClickListener listener) {
        this.listener = listener;
    }

    @NonNull
    @Override
    public StoryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_story, parent, false);
        return new StoryViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull StoryViewHolder holder, int position) {
        Story story = stories.get(position);
        holder.bind(story);
    }

    @Override
    public int getItemCount() {
        return stories.size();
    }

    class StoryViewHolder extends RecyclerView.ViewHolder {
        private ImageView ivStory;
        private TextView tvTitle;
        private TextView tvDescription;

        public StoryViewHolder(@NonNull View itemView) {
            super(itemView);
            ivStory = itemView.findViewById(R.id.ivStory);
            tvTitle = itemView.findViewById(R.id.tvTitle);
            tvDescription = itemView.findViewById(R.id.tvDescription);

            itemView.setOnClickListener(v -> {
                int position = getAdapterPosition();
                if (position != RecyclerView.NO_POSITION && listener != null) {
                    listener.onStoryClick(stories.get(position));
                }
            });
        }

        public void bind(Story story) {
            tvTitle.setText(story.getName());
            tvDescription.setText(story.getDescribe());

            // Load image using Glide
            Glide.with(itemView.getContext())
                    .load(story.getImage())
                    .into(ivStory);
        }
    }
}

这样我们大概可以了解到如何使用MVVM框架来改进项目了。 

总结

通过以上步骤,我们将原有的代码改写成了 MVVM 框架。主要的变化包括:

  • 创建了 ViewModel 和 Repository 类,将业务逻辑和数据处理从视图层分离出来。
  • 在 View 层(Activity 或 Fragment)中使用 ViewModel 来获取数据,并观察数据的变化。
  • 在 Adapter 中添加了更新数据的方法,以便在数据变化时更新 RecyclerView。

下一章节将讲诉如何使用MVP对项目的改进。

感谢观看!!!

你可能感兴趣的:(mvc,学习,java)