上次已经了解到MVC的知识,现在是扩展实现MVP/MVVM的框架改进本身项目
MVVM 框架即 Model-View-ViewModel 框架,是一种软件架构设计模式,以下是具体介绍:
下列是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 框架。主要的变化包括:
下一章节将讲诉如何使用MVP对项目的改进。
感谢观看!!!