Based on the answer of Chris I give my own answer. I think the tutorial is not best practice for the simple reason, that an object should not expose it's internal implementation. Base on the argumentation of Chris I was looking for an option to get encapsulation without losing the named features. The result is the method observerUsers()
which delegates to a LiveData
object internally.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivityViewModel model = ViewModelProviders.of(this).get(MainActivityViewModel.class);
model.observeUsers(this,
new Observer<List<User>>() {
@Override
public void onChanged(@Nullable List<User> users) {
updateUI();
}
}
);
}
void updateUI() {
}
static class MainActivityViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public void observeUsers(@NonNull LifecycleOwner owner,
@NonNull Observer<List<User>> observer) {
getUsers().observe(owner, observer);
}
private LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
static class User {
}
}
Still List<User>
exposes internal implementation. It could be improved to a class Users
.
I put everything into one file and use inner static class. This is not meant as best practice. It was just to be able to quickly edit everything within one file. Especially the model User
belongs into it's very own file, while I often put the ViewModel
into the View
class it belongs to like this.
My second point of critic matches the case that the ViewModel
itself observes an underlying model. In this case the observer method onChange()
is very general and requires a very general update method like updateUI()
. You may want to observe more specific events of the model to do specific updates.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…