我的活动包含一个imageview和一个按钮,单击该按钮时imageview内部的图像已更改(工作正常)。
但是当屏幕方向改变时,imageview内的图像丢失了(因为重新创建了活动)。
我在某篇文章中读到ViewModel可以保留方向,并且与onSaveInstanceState相比,它可以存储大量数据(位图)。
还有很多其他选项可以恢复同一张图像,但是我想使用ViewModel来获得同一张图像而不受方向变化的影响。
那么,如何使用ViewModel获得相同的图像?
谢谢。
答案 0 :(得分:1)
使用ViewModel与TextView和ImageView一起使用以承受方向变化的简单示例
示例说明:
布局包含一个TextView,ImageView和一个Button。最初,文本和图像是在布局内部的TextView和ImageView上设置的。单击按钮时,将文本(以编程方式)和图像(来自drawable)设置为适当的视图。
假设设备已旋转,因此由于活动重新创建而丢失了单击按钮时设置的文本和图像,因此会加载在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>
MainActivity.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());
}
}
MyViewModel.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;
}
}
关于ViewModel的一些技巧:
链接: https://developer.android.com/topic/libraries/architecture/viewmodel
https://developer.android.com/topic/libraries/architecture/livedata.html
CodeLab链接: https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#0
我不是专业开发人员。上面的代码对我有用。欢迎提出任何更正或建议。
谢谢;)
答案 1 :(得分:0)
您的ViewModel应该具有方法changeImage
,该方法可以更改ViewModel的内部状态。您必须以某种方式指示有关此更改的活动。为此,最好使用val imageId = MutableLiveData<Int>()
。
changeImage
更改此值。在“活动”中,您可以订阅更改并在imageId更改时应用新图像。