NavigationView 的 MVVM ViewModel 数据绑定应该是什么样子
How the MVVM ViewModel DataBinding shoud look like for NavigationView
我没有找到任何示例来说明这一点。我刚开始接触 MVVM DataBinding 和 ViewModel。
我想在单击 DrawerLayout 中 NavigationView 中的元素后执行一个操作。如果没有任何设计模式,我会以非常简单的方式做到这一点,但这个 MVVM 是非常困难的模式。
我在考虑 ViewModelMain 中的 MutableLiveData,然后在 ActivityMain 中观察它,但我不知道在这个例子中要观察什么。
这是我的代码:
ActivityMain.java
(...)
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if(id == R.id.nav_account) {
Toast.makeText(this, "abc", Toast.LENGTH_SHORT).show();
drawerLayout.close();
}
return false;
}
ViewModelMain.java
public class ViewModelMain extends ViewModel {
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/my_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="?attr/colorBottomNavigationViewBg"
app:itemHorizontalTranslationEnabled="true"
app:itemTextColor="?attr/colorBottomNavigationViewItem"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/menu_bottom_navigation" />
</RelativeLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/menu_navigation_drawer"
app:itemIconTint="?colorDayNight" />
</androidx.drawerlayout.widget.DrawerLayout>
首先我想指出DataBinding 和ViewBinding 之间的区别。 DataBinding 允许您将布局中的 UI 组件(在 XML 中)绑定到应用程序中的数据源。我对 DataBinding 有点偏见。我不喜欢也不用。
ViewBinding 是一种在您的应用程序代码中绑定视图元素并消除不断编写 findViewById
的需要的方法。它为每个 XML 布局生成一个绑定 class,您可以在 activities/fragments(views) 中使用它。
在您的情况下,您只需使用视图绑定就可以了。
这是 android 文档:https://developer.android.com/topic/libraries/view-binding
接下来取决于您要执行的操作。假设您想显示元素被点击的次数。
您的 ViewModel 将负责处理该逻辑,而您的视图将负责观察和显示更改。
(我会尝试在java中写这个,但我已经很久没有使用Java,你也应该考虑切换到Kotlin)
public class ViewModelMain extends ViewModel {
private MutableLiveData<Integer> _timesClicked = new MutableLiveData<>();
public void increaseClickCounter() {
int currentTimesClicked = _timesClicked.getValue();
_timesClicked.setValue(++currentTimesClicked);
}
public LiveData<Integer> getTimesClicked() {
if (_timesClicked == null) {
_timesClicked = new MutableLiveData<>();
_timesClicked.setValue(0);
}
return _timesClicked;
}
}
要阅读 activity 中的视图绑定,您可以访问此处:https://developer.android.com/topic/libraries/view-binding#activities
您现在需要将 viewBinding 和 viewModle 添加到您的 activity。这将成为您 activity 代码的一部分:
private ActivityMainBinding binding; //notice the "Binding" suffix at the end
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(ViewModelMain.class);
binding = ActivityMainBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
initClickListeners();
startObservingData();
}
private void initClickListeners() {
///replace "yourButton" with an element from your XML.
binding.yourButton.setOnClickListener(new View.OnClickListener() {
viewModel.increaseClickCounter();
});
}
private void startObservingData() {
viewModel.getTimesClicked().observe(this, timesClicked -> {
Toast.makeText(this, timesClicked.intValue(), Toast.LENGTH_SHORT).show();
});
}
我没有找到任何示例来说明这一点。我刚开始接触 MVVM DataBinding 和 ViewModel。
我想在单击 DrawerLayout 中 NavigationView 中的元素后执行一个操作。如果没有任何设计模式,我会以非常简单的方式做到这一点,但这个 MVVM 是非常困难的模式。
我在考虑 ViewModelMain 中的 MutableLiveData,然后在 ActivityMain 中观察它,但我不知道在这个例子中要观察什么。
这是我的代码:
ActivityMain.java
(...)
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if(id == R.id.nav_account) {
Toast.makeText(this, "abc", Toast.LENGTH_SHORT).show();
drawerLayout.close();
}
return false;
}
ViewModelMain.java
public class ViewModelMain extends ViewModel {
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/my_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="?attr/colorBottomNavigationViewBg"
app:itemHorizontalTranslationEnabled="true"
app:itemTextColor="?attr/colorBottomNavigationViewItem"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/menu_bottom_navigation" />
</RelativeLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/menu_navigation_drawer"
app:itemIconTint="?colorDayNight" />
</androidx.drawerlayout.widget.DrawerLayout>
首先我想指出DataBinding 和ViewBinding 之间的区别。 DataBinding 允许您将布局中的 UI 组件(在 XML 中)绑定到应用程序中的数据源。我对 DataBinding 有点偏见。我不喜欢也不用。
ViewBinding 是一种在您的应用程序代码中绑定视图元素并消除不断编写 findViewById
的需要的方法。它为每个 XML 布局生成一个绑定 class,您可以在 activities/fragments(views) 中使用它。
在您的情况下,您只需使用视图绑定就可以了。 这是 android 文档:https://developer.android.com/topic/libraries/view-binding
接下来取决于您要执行的操作。假设您想显示元素被点击的次数。
您的 ViewModel 将负责处理该逻辑,而您的视图将负责观察和显示更改。 (我会尝试在java中写这个,但我已经很久没有使用Java,你也应该考虑切换到Kotlin)
public class ViewModelMain extends ViewModel {
private MutableLiveData<Integer> _timesClicked = new MutableLiveData<>();
public void increaseClickCounter() {
int currentTimesClicked = _timesClicked.getValue();
_timesClicked.setValue(++currentTimesClicked);
}
public LiveData<Integer> getTimesClicked() {
if (_timesClicked == null) {
_timesClicked = new MutableLiveData<>();
_timesClicked.setValue(0);
}
return _timesClicked;
}
}
要阅读 activity 中的视图绑定,您可以访问此处:https://developer.android.com/topic/libraries/view-binding#activities
您现在需要将 viewBinding 和 viewModle 添加到您的 activity。这将成为您 activity 代码的一部分:
private ActivityMainBinding binding; //notice the "Binding" suffix at the end
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(ViewModelMain.class);
binding = ActivityMainBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
initClickListeners();
startObservingData();
}
private void initClickListeners() {
///replace "yourButton" with an element from your XML.
binding.yourButton.setOnClickListener(new View.OnClickListener() {
viewModel.increaseClickCounter();
});
}
private void startObservingData() {
viewModel.getTimesClicked().observe(this, timesClicked -> {
Toast.makeText(this, timesClicked.intValue(), Toast.LENGTH_SHORT).show();
});
}