简体   繁体   English

我可以使用针对两个活动观察到的视图模型吗?

[英]Can i use a viewmodel that is observed for two activities?

I'm working on a new project that implements MVVM. 我正在研究一个实现MVVM的新项目。 Can I use a viewmodel that is observed for two activities ? 我可以使用观察到的两个活动的视图模型吗? or should I make one viewmodel for each activity ? 还是应该为每个活动创建一个视图模型?

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();
            }
        }
    });

}

} }

Here is my ViewModel and my two activities for more details. 这是我的ViewModel和我的两个活动,以获取更多详细信息。 As I said it's a ViewModel that is observed for two activities. 正如我所说的,这是针对两个活动观察到的ViewModel。 This ViewModel calls a repository that updates, inserts and deletes user data as well as also updates e sends messages to the views. 此ViewModel调用一个存储库,该存储库可更新,插入和删除用户数据,以及更新并将消息发送到视图。

  • It's completely OK to share a viewmodel among the views, in case if you're using the same data or it's a kind of centralised datastore . 在视图之间共享视图模型是完全可以的,以防万一,如果您使用的是相同的数据,或者它是一种集中式数据存储
  • Otherwise implement separate model for each view as it increases code readability and hence efficiency. 否则, 为每个视图实现单独的模型,因为它提高了代码的可读性并因此提高了效率。
  • Happy to provide personalised solution if you could post some of your code snippets here. 如果您可以在此处发布一些代码段,很高兴提供个性化解决方案。 Happy coding 快乐编码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以在两个活动中使用相同的方法吗? - Can i use the same method in two activities? 我可以在不同的活动中为两个不同的列表视图使用相同的适配器吗? - Can I use the same adapter for two different listviews in different activities? 如何使用界面在两个活动之间建立一个简单的桥梁? - How can I use an interface to create a simple bridge between two activities? AppCompatActivity未观察到ViewModel - ViewModel not observed by AppCompatActivity 如何清除Android中除前两个活动之外的所有活动? - How can I clear all but the top two activities in Android? 我如何在两个活动之间传递类对象? - How I can pass class object between two activities? 如何在一个文件中创建两个活动? - How can i make two activities to one file? 如何创建动画类以在 android 中的其他活动中使用? - How can I create an animation class to use in other activities in android? 为什么我不能同时运行这两个活动? 这两个活动和图像显示我直接到达 MainActivity 而无需单击主页按钮 - Why I can't run the two activities together? the two activities and the image shows that I reached MainActivity directly without clicking homebutton 如何在不同的活动上使用GridView的同一适配器 - How Can I use Same Adapter of a GridView on Different activities
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM