如何在ViewModel中保存图像以处理方向变化?



我的活动包含一个图像视图和一个按钮,当单击按钮时,图像视图内的图像会更改(工作正常(。

但是,当屏幕方向更改时,图像视图中的图像将丢失(因为重新创建了活动(。

我在某篇文章中读到,与onSaveInstanceState相比,ViewModel可以存活下来,并且可以存储大量数据(位图(。

还有许多其他选项可以检索相同的图像,但我想使用 ViewModel 来获取相同的图像,而不会受到方向更改的影响。

那么,如何使用视图模型获得相同的图像?

谢谢。

使用ViewModel 处理 TextView 和 ImageView 的简单示例,以应对方向更改

示例说明:

布局包含文本视图、图像视图和按钮。最初文本和图像是在布局内的 TextView 和 ImageView 上设置的。单击按钮时,文本(以编程方式(和图像(从可绘制对象(设置为相应的视图。

假设设备被旋转,因此单击按钮时设置的文本和图像由于活动重新创建而丢失,因此加载在xml文件中设置的文本和图像。

为了解决这个问题,我们使用 ViewModel 来处理配置更改。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/my_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android" />
<ImageView
android:id="@+id/my_image"
android:layout_width="96dp"
android:layout_height="96dp"
android:layout_margin="20dp"
android:src="@drawable/ic_android_black_24dp" />
<Button
android:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="Update text and image" />
</LinearLayout>

主活动.java

public class MainActivity extends AppCompatActivity {
TextView mText;
ImageView mImageView;
Button mButton;
MyViewModel mViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mText = findViewById(R.id.my_text);
mImageView = findViewById(R.id.my_image);
mButton = findViewById(R.id.my_button);
mViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
if (mViewModel.getText() != null) {
mText.setText(mViewModel.getText());
}
if (mViewModel.getImage() != null) {
mImageView.setImageDrawable(mViewModel.getImage());
}
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mText.setText("Happy Coding...");
mImageView.setImageDrawable(getResources().getDrawable(R.drawable.ic_face));
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mViewModel.setText(mText.getText().toString());
mViewModel.setImage(mImageView.getDrawable());
}
}

我的视图模型.java

public class MyViewModel extends ViewModel {
private String text;
private Drawable image;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Drawable getImage() {
return image;
}
public void setImage(Drawable image) {
this.image = image;
}
}

关于视图模型的一些提示:

  1. 类旨在以生命周期意识的方式保存和管理与 UI 相关的数据。这允许数据在配置更改(如屏幕旋转(中幸存下来。
  2. 视图模型将 UI 实现与应用数据分开。ViewModel 的生命周期从首次创建关联的 UI 控制器时开始,一直延伸到它被完全销毁。
  3. 切勿在视图模型中直接或间接存储 UI 控制器或上下文。这包括在视图模型中存储视图。对 UI 控制器的直接或间接引用会破坏将 UI 与数据分离的目的,并可能导致内存泄漏。
  4. ViewModel 还可以很好地与另一个架构组件(如 LiveData、Room(配合使用。使用 LiveData 的另一个好处是它是可观察的:它可以在数据更改时触发 UI 更新。使用以下链接了解更多信息。

链接: https://developer.android.com/topic/libraries/architecture/viewmodel

https://developer.android.com/topic/libraries/architecture/livedata.html

代码实验室链接: https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#0

我不是专业开发人员。上面的代码对我有用。欢迎任何更正或建议。

谢谢;)

您的 ViewModel 应该有一个更改 ViewModel 内部状态的方法changeImage。您必须以某种方式指示有关此更改的活动。为此,最好使用val imageId = MutableLiveData<Int>().

changeImage更改此值。在"活动"中,您可以订阅更改,并在 imageId 发生更改时应用新图像。

最新更新