我正在开发一个实现MVVM的新项目。我可以使用针对两个活动观察到的视图模型吗?还是应该为每个活动创建一个视图模型?
public class FormViewModel extends AndroidViewModel {
/*
This is my only ViewModel in the project
*/
private UserRepository userRepository;
//linked fields in xml for lib Data Binding
public String name, lastName, address, age;
//variables observed in the views
public MutableLiveData<String> responseMessageInsertUpdate = new MutableLiveData<>();
public MutableLiveData<String> responseStartUserFormActivity = new MutableLiveData<>();
public MutableLiveData<String> responseMessageDelete = new MutableLiveData<>();
public FormViewModel(Application application) {
super(application);
userRepository = new UserRepository(application);
}
//get all users from database that implements RoomDataBase, it´s observed em MainActivity
//and update recyclerview when database receive any change
public LiveData<List<User>> getAllUsers() {
return userRepository.selectAllUsers();
}
/*
action of submit button defined (linked for lib Data Binding) in xml
makes change or user registration
*/
public void submitClick(User user) {
int idade = 0;
if (this.age != null) {
if (!this.age.isEmpty()) {
idade = Integer.parseInt(this.age);
}
}
if (user != null) {
user.setName(name);
user.setLastName(lastName);
user.setAddress(address);
user.setAge(idade);
} else {
user = new User(name, lastName, address, idade);
}
//validation logic
if (user.isFormValid()) {
if (user.getId() > 0) {
//update the user in the database
userRepository.updateUser(user);
//there is an observable of this MutableLiveData variable in UserFormActivity that shows this
//message in a toast for the User when received a value
responseMessageInsertUpdate.setValue("User data uploaded successfully.");
} else {
//insert the user on data base
userRepository.insertUser(user);
responseMessageInsertUpdate.setValue("User " + user.getName() + " stored successfully.");
}
} else {
responseMessageInsertUpdate.setValue("Please, correctly fill in all the fields of the form to confirm the registration.");
}
}
//action of btnNewForm linked for lib Data Binding in xml
public void newFormClick() {
/*
this MutableLiveData is observed for MainActivity and start a new UserFormActivity when receive
value when the btnNewForm is pressed
*/
responseStartUserFormActivity.setValue("startActivity");
}
//delete User from database
public void deleteUser(User user) {
if (user != null) {
userRepository.deleteUser(user);
/*
there is an observable of this MutableLiveData variable in MainActivity that shows this
message in a toast for the user when received a value (when an user is deleted from database)
*/
responseMessageDelete.setValue(user.getName() + " removed from list successfully.");
}
}
//this method is called on UserFormActivity to show more details of an existing user in activity fields
public void showDataUserInActivity(User user) {
//linked fields in xml for lib Data Binding that receive values from the object user
name = user.getName();
lastName = user.getLastName();
address = user.getAddress();
age = String.valueOf(user.getAge());
}
}
public class MainActivity extends AppCompatActivity {
/*
this activity shows all users in recyclerview
*/
private Context contexto = this;
private ActivityMainBinding binding;
private UserAdapter userAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
FormViewModel formViewModel = ViewModelProviders.of(this).get(FormViewModel.class);
binding.setViewModel(formViewModel);
createRecyclerView();
methodsViewModel();
}
//methods from ViewModel
private void methodsViewModel() {
//observer that update recyclerview when database receive any change
binding.getViewModel().getAllUsers().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(@Nullable List<User> pessoas) {
userAdapter.addUserToList(pessoas);
}
});
//observer that starts a new UserFormActivity when btnNewForm is pressed
//receive value in the method newFormClick from ViewModel
binding.getViewModel().responseStartUserFormActivity.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
startUserFormActivity();
}
});
//observer that shows a message in a toast when the user is deleted from database
//receive value in the method deleteUser from ViewModel
binding.getViewModel().responseMessageDelete.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String message) {
Toast.makeText(contexto, message, Toast.LENGTH_SHORT).show();
}
});
}
private void createRecyclerView() {
RecyclerView rvUser = binding.rvPessoas;
rvUser.setLayoutManager(new LinearLayoutManager(contexto));
userAdapter = new UserAdapter(contexto, itemClick());
rvUser.setAdapter(userAdapter);
}
private void startUserFormActivity() {
Intent intent = new Intent(contexto, UserFormActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
contexto.startActivity(intent);
}
private void startUserFormActivity(User user) {
Intent intent = new Intent(contexto, UserFormActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("user", user);
contexto.startActivity(intent);
}
private UserAdapter.ItemClick itemClick() {
return new UserAdapter.ItemClick() {
@Override
public void simpleClick(View view, final int position) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(contexto);
String[] options = {"Update", "Delete"};
alertDialog.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (i == 0) {
//start a new UserFormActivity to change user attributes
startUserFormActivity(userAdapter.getUserFromList().get(position));
} else if (i == 1) {
//call the method deleteUser from ViewModel
binding.getViewModel().deleteUser(userAdapter.getUserFromList().get(position));
}
}
});
alertDialog.show();
}
};
}
}
public class UserFormActivity extends AppCompatActivity {
private Context context = this;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FormViewModel formViewModel = ViewModelProviders.of(this).get(FormViewModel.class);
final ActivityFormUserBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_form_user);
binding.setViewModel(formViewModel);
if (getIntent().getSerializableExtra("user") != null) {
User user = (User) getIntent().getSerializableExtra("user");
formViewModel.showDataUserInActivity(user);
//put user data in activity when action "update" is called in MainActivity
binding.setUser(user);
}
/*
Method from ViewModel
Observer that shows a message in a toast and close the activity when the user is storage or updated from database
receive value in the method submitClick from ViewModel
*/
formViewModel.responseMessageInsertUpdate.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
Toast.makeText(context, s, Toast.LENGTH_LONG).show();
if (s.contains("successfully")) {
finish();
}
}
});
}
}
以下是我的ViewModel和我的两个活动,以了解更多详细信息。正如我所说的,这是一个针对两个活动观察到的ViewModel。此ViewModel调用一个存储库,该存储库用于更新、插入和删除用户数据以及更新和向视图发送消息。
- 在视图之间共享视图模型是完全可以的,以防您使用相同的数据或它是一种集中式数据存储
- 否则,在每个视图增加时为其实现单独的模型代码可读性,从而提高效率
- 如果您可以发布一些您的此处的代码片段。快乐编码