Как восстановить состояние checkBox в элементах списка Android RecyclerView при вращении устройства - PullRequest
0 голосов
/ 25 января 2019

Мое текущее приложение для Android содержит RecyclerView, в котором в каждом элементе списка присутствует флажок.

Моя проблема в том, что при повороте экрана флажок всегда возвращается в непроверенное состояние.

Я сохраняю свои обновленные элементы списка в моих действиях ViewModel и передаю этот сохраненный список обратно адаптеру в onCreate

Из моих журналов отладки я вижу, что состояние списка правильно содержит проверенное / непроверенное состояние каждого элемента списка.

Я также вышел из списка в конструкторе адаптера, который также показывает, что проверенное состояние все еще действует.

однако, когда вызывается onBindViewHolder, все элементы списка не проверяются.

вот мои фрагменты кода: -

  @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_layout);

        manageViewModel();
        recyclerView = findViewById(R.id.my_rv);

        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        adapter = new MedicationAdapter(viewModel.getList(), this);
        recyclerView.setAdapter(adapter);

   }



protected void onSaveInstanceState(Bundle state) {
    super.onSaveInstanceState(state);
    viewModel.saveList(adapter.getList());
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
}

Мой элемент списка checkBox определен следующим образом в xml: -

<android.support.v7.widget.AppCompatCheckBox
            android:id="@+id/my_checkbox_header"
            android:layout_width="wrap_content"
            android:saveEnabled="false"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:text="" />

Каков правильный подход к сохранению состояния флажка внутри элемента (ов) RecyclerView при вращении устройства?

Код моего адаптера: -

    public class MusicalAdapter extends RecyclerView.Adapter<MusicalAdapter.ViewHolder> {

        private static final String TAG = "MusicalAdapter";
        private int previousExpandedPosition = -1;
        private int mExpandedPosition = -1;

        private final List<MusicalUI> musicals = new ArrayList<>();
        private final ItemClickListener clickListener;

        MusicalAdapter(final List<MusicalUI> musicals, final ItemClickListener clickListener) {
            this.musicals.clear();
            this.musicals.addAll(musicals);
//AT THIS POINT THE CHECKED VALUES ARE AS EXPECTED

            this.clickListener = clickListener;
        }

        @NonNull
        @Override
        public MusicalAdapter.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
            final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.all_disco_item_x, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull final MusicalAdapter.ViewHolder holder, final int position) {
            final MusicalUI musical = musicals.get(position);

            Log.d(TAG, "onBindViewHolder() called with: musical = [" + musical.getChecked());

// AT THI SPOINT THE CHECKED VALUES ARE ALWAYS FALSE!!!!!!!!
            final boolean isExpanded = position == mExpandedPosition;


            for (final MusicalUI musicalx : musicals) {
                Log.d(TAG, "onBindViewHolder(): " + musicalx.getChecked());
            }

            // Header
            holder.discoDetailsHeaderLayout.setVisibility(View.VISIBLE);
            holder.musicalNameHeader.setText(musical.getDiscoName());

            holder.discoSelectedHeader.setOnCheckedChangeListener(null);
            holder.discoSelectedHeader.setChecked(musical.getChecked());
            holder.discoSelectedHeader.setOnCheckedChangeListener((buttonView, isChecked) -> musical.setChecked(isChecked));


            if (isExpanded)
                previousExpandedPosition = position;

            holder.itemView.setOnClickListener(v -> {
                mExpandedPosition = isExpanded ? -1 : position;
                notifyItemChanged(previousExpandedPosition);
                notifyItemChanged(position);
            });

        }

        @Override
        public int getItemCount() {
            return musicals.size();
        }


        MusicalUI getItem(final int position) {
            return musicals.get(position);
        }

        void updateList(final List<MusicalUI> newMusicals) {
            final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new GenericDiffUtilCallback<>(this.musicals, newMusicals));
            diffResult.dispatchUpdatesTo(this);

            this.musicals.clear();
            this.musicals.addAll(newMusicals);
        }

        List<MusicalUI> getList() {
            return musicals;
        }

        /**
         *
         */
        public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
    ...
            }


        }
    }

1 Ответ

0 голосов
/ 25 января 2019

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

Чтобы ваша деятельность не возобновлялась при смене чередования

в AndroidManifest найдите свою активность и добавьте

android:configChanges="orientation"

Android также рекомендует избегать этого в большинстве случаев

Там написано, что дескриптор android обрабатывает изменения

Осторожно: изменение конфигурации самостоятельно может сделать это очень труднее использовать альтернативные ресурсы, потому что система делает не применять их автоматически для вас. Эта техника должна быть считается последним средством, когда вы должны избегать перезапусков из-за изменение конфигурации и не рекомендуется для большинства приложений.

Чтобы объявить, что ваша деятельность обрабатывает изменение конфигурации, отредактируйте соответствующий элемент в файле манифеста, чтобы включить атрибут android: configChanges со значением, представляющим Конфигурация, которую вы хотите обработать. Возможные значения перечислены в документация для андроида: атрибут configChanges. Большинство Обычно используемые значения: «direction», «screenSize» и "KeyboardHidden". Значение «ориентация» предотвращает перезапуск, когда ориентация экрана меняется.

Подробнее

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