android:layout_height=“40dp”
app:layout_constraintLeft_toLeftOf=“parent”
app:layout_constraintRight_toRightOf=“parent”
app:layout_constraintTop_toBottomOf="@+id/progressBar"
android:layout_marginTop=“20dp”
android:text=“点击获取用户信息”
/>
</androidx.constraintlayout.widget.ConstraintLayout>
页面有个按钮用于点击获取用户信息,有个TextView展示用户信息。 在onCreate()中先 创建ViewModelProvider实例,传入的参数是ViewModelStoreOwner,Activity和Fragment都是其实现。然后通过ViewModelProvider的get方法 获取ViewModel实例,然后就是 观察ViewModel中的LiveData。
运行后,点击按钮 会弹出进度条,2s后展示用户信息。接着旋转手机,我们发现用户信息依然存在。来看下效果:
旋转手机后确实是重建了Activity的,日志打印如下:
2021-01-06 20:35:44.984 28269-28269/com.hfy.androidlearning I/UserActivity: onStop:
2021-01-06 20:35:44.986 28269-28269/com.hfy.androidlearning I/UserActivity: onDestroy:
2021-01-06 20:35:45.025 28269-28269/com.hfy.androidlearning I/UserActivity: onCreate:
总结下:
-
ViewModel的使用很简单,作用和原来的Presenter一致。只是要结合LiveData,UI层观察即可。
-
ViewModel的创建必须通过ViewModelProvider。
-
注意到ViewModel中没有持有任何UI相关的引用。
-
旋转手机重建Activity后,数据确实恢复了。
2.2 Fragment间数据共享
Activity 中的多个Fragment需要相互通信是一种很常见的情况。假设有一个ListFragment,用户从列表中选择一项,会有另一个DetailFragment显示选定项的详情内容。在之前 你可能会定义接口或者使用EventBus来实现数据的传递共享。
现在就可以使用 ViewModel 来实现。这两个 Fragment 可以使用其 Activity 范围共享 ViewModel 来处理此类通信,如以下示例代码所示:
public class ShareViewModel extends ViewModel {
public MutableLiveData selected = new MutableLiveData<>();
}
public class Share2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share2);
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
tools:context=".share.ShareActivity">
<fragment
android:id="@+id/fragment_list"
android:name=“com.gs.createmvvm210422.share2.MyList2Fragment”
android:layout_width=“100dp”
android:layout_height=“match_parent”
app:layout_constraintLeft_toLeftOf=“parent”
app:layout_constraintRight_toLeftOf="@+id/fragment_detail"
/>
<fragment
android:id="@+id/fragment_detail"
android:name=“com.gs.createmvvm210422.share2.Detail2Fragment”
android:layout_width=“200dp”
android:layout_height=“match_parent”
app:layout_constraintLeft_toRightOf="@+id/fragment_list"
app:layout_constraintRight_toRightOf=“parent”
/>
</androidx.constraintlayout.widget.ConstraintLayout>
public class MyList2Fragment extends ListFragment {