Как управлять состоянием «Активность для результата» для элемента в списке?

Например, внутри RecyclerView есть список предметов. И я хочу изменить изображение для элемента после нажатия на соответствующий элемент списка. Как сохранить элемент position после startActivityForResult и направить изображение onActivityResult обратно к соответствующему элементу на основе position.

Для меня есть только один вариант - сохранить позицию в переменной-члене Activity и использовать ее после onActivityResult. Может быть, возможен лучший подход, чтобы избежать создания дополнительного состояния для Activity?

Пример кода:

public class MyActivity extends AppCompatActivity {
  private static final int REQ_TAKE_PICTURE = 1;

  // is it possible to avoid this variable as Activity state
  private int tempItemPosition;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    ...
    MyAdapter adapter = new MyAdapter();
    adapter.setOnItemClickListener(this::startTakePhoto);
  }

  @Override
  public void onActivityResult(int reqCode, int resCode, Intent data) {
    if (reqCode == REQ_TAKE_PICTURE) {
  updateImageItem(Uri.parse(data.getStringExtra(TakePictureActivity.RESULT_IMAGE_URI)), tempItemPosition)
    }
  }

  private void updateImageItem(Uri imageUri, int position) {
    // update item image for position
  }

  private void startTakePhoto(int position) {
    // saving state which is better to avoid
    tempItemPosition = position;
    Intent intent = new Intent(this, TakePhotoActivity.class);
    startActivityForResult(intent, REQ_TAKE_PICTURE);
  }
}

public class MyAdapter extends RecyclerView.Adapter<ViewHolder> {
  ...
  public void setOnItemClickLsitener(OnItemClickListener listener) {
    ...
  }
  ...

  public interface OnItemClickListener {
    void onItemClick(int position);
  }
}

Можно ли вызывать updateImageItem(Uri, int) после onActivityResult, но не сохранять позицию нажатого элемента как состояние Activity?

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

YouKnowWhoIAm 22.07.2019 18:36

Обновлен вопрос @YouKnowWhoIAm, добавлена ​​только важная часть кода, связанная с вопросом.

user5329216 22.07.2019 22:10
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Передайте данные в другую активность и обратно:

... your code

  @Override
  public void onActivityResult(int reqCode, int resCode, Intent data) {
    if (reqCode == REQ_TAKE_PICTURE) {
     String uriExtra = data.getStringExtra(TakePictureActivity.RESULT_IMAGE_URI);
     int positionExtra = data.getIntExtra("PhotoParentPosition")
updateImageItem(Uri.parse(uriExtra), positionExtra)
    }
  }

... your code

private void startTakePhoto(int position) {
    // saving state which is better to avoid
    tempItemPosition = position;
    Intent intent = new Intent(this, TakePhotoActivity.class);
    intent.putExtra("PhotoParentPosition", position);
    startActivityForResult(intent, REQ_TAKE_PICTURE);
  }

В другом действии (TakePhotoActivity) вы получаете дополнительное ("PhotoParentPosition") намерение создания и помещаете его в намерение результата.


Другой альтернативой может быть использование AndroidX ViewModel и использование общей ViewModel между двумя вашими действиями.

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

Идея ViewModel заключается в том, что это класс данных, который может хранить данные о вашем представлении (например, положение элемента списка выбора), эти данные могут быть сохранены между действиями и изменениями конфигурации.

Architecture Components provides ViewModel helper class for the UI controller that is responsible for preparing data for the UI. ViewModel objects are automatically retained during configuration changes so that data they hold is immediately available to the next activity or fragment instance. For example, if you need to display a list of users in your app, make sure to assign responsibility to acquire and keep the list of users to a ViewModel, instead of an activity or fragment, as illustrated by the following sample code:

Передача данных через намерение и обратно возможна при запуске действия, к которому у нас есть доступ и которое мы можем контролировать. Но Activity может принадлежать другому пакету, например системной камере. Кроме того, аналогичная ситуация может возникнуть при запросе разрешений, когда внутри onRequestPermissionsResult мы не можем получить никаких данных. Shared ViewModel выглядит как хороший вариант для предотвращения подобных сложностей.

user5329216 22.07.2019 22:30

Если вы используете системную камеру, вы все равно должны обернуть ее в свою собственную активность камеры, чтобы вы могли передавать индекс вперед и назад (и сохранять состояние в своей активности). Это гораздо более чистая практика кода

Blundell 23.07.2019 09:10

Другие вопросы по теме