Как сохранить изображение внутри ViewModel для обработки изменения ориентации? - PullRequest
0 голосов
/ 12 сентября 2018

Моя активность содержит один просмотр изображения и кнопку, при нажатии кнопки изображение внутри просмотра изображения изменяется (работает нормально).

Но при изменении ориентации экрана изображение внутри просмотра изображения теряется (поскольку действие воссоздается)).

В одном посте я читал, что ViewModel сохраняет ориентацию и может хранить большой объем данных (растровое изображение) по сравнению с onSaveInstanceState.

Существует множество других вариантов получения того же изображения,но я хочу использовать ViewModel, чтобы получить то же изображение без изменения ориентации.

Итак, как я могу получить то же изображение, используя ViewModel?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 05 июля 2019

Простой пример работы с TextView и ImageView с использованием 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>

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:

  1. Класс ViewModel предназначен для хранения и управления данными, связанными с пользовательским интерфейсом, с учетом жизненного цикла.Это позволяет данным переживать изменения конфигурации, такие как поворот экрана.
  2. ViewModels отделяет реализацию пользовательского интерфейса от данных вашего приложения.Жизненный цикл ViewModel простирается от момента первого создания соответствующего контроллера пользовательского интерфейса до его полного уничтожения.
  3. Никогда не храните контроллер или контекст UI прямо или косвенно в ViewModel.Это включает в себя сохранение View в ViewModel.Прямые или косвенные ссылки на контроллеры пользовательского интерфейса лишают цели отделения пользовательского интерфейса от данных и могут привести к утечкам памяти.
  4. ViewModel также очень хорошо работает с другим компонентом архитектуры, таким как LiveData, Room.Дополнительным преимуществом использования LiveData является то, что они наблюдаемы: они могут инициировать обновления пользовательского интерфейса при изменении данных.Используйте ссылки ниже, чтобы узнать больше.

Ссылки: 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

Яне профессиональный разработчик.Выше код работает для меня.Добро пожаловать в любые исправления или предложения.

Спасибо;)

0 голосов
/ 12 сентября 2018

Ваш ViewModel должен иметь метод changeImage, который изменяет внутреннее состояние ViewModel.Вы должны как-то указать активность по поводу этих изменений.Для этого лучше использовать val imageId = MutableLiveData<Int>().

changeImage, чтобы изменить это значение.В Activity вы можете подписаться на изменения и применять новое изображение при каждом изменении imageId.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...