From fc6c31c3db77dcb04473378f27e24283131b6052 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 7 Aug 2021 19:40:45 +0200 Subject: [PATCH] Android: Update cheat list when a cheat is edited The way I'm implementing events using LiveData feels rather unorthodox, but I'm not aware of anything in the Android framework that would let me do it in a better way... One option I did consider was wrapping the cheat lists in LiveData and observing those, but then CheatsAdapter wouldn't know which cheat had changed, only that there was some kind of change to the list, necessitating the use of the not recommended notifyDataSetChanged. --- .../cheats/model/CheatsViewModel.java | 31 ++++++++++++++++++- .../cheats/ui/CheatDetailsFragment.java | 1 + .../features/cheats/ui/CheatListFragment.java | 2 +- .../features/cheats/ui/CheatViewHolder.java | 7 +++-- .../features/cheats/ui/CheatsAdapter.java | 11 +++++-- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/CheatsViewModel.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/CheatsViewModel.java index e4e5298104..cdd68221c6 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/CheatsViewModel.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/CheatsViewModel.java @@ -10,9 +10,11 @@ public class CheatsViewModel extends ViewModel { private boolean mLoaded = false; + private int mSelectedCheatPosition = -1; private final MutableLiveData mSelectedCheat = new MutableLiveData<>(null); private final MutableLiveData mIsEditing = new MutableLiveData<>(false); + private final MutableLiveData mCheatChangedEvent = new MutableLiveData<>(null); private final MutableLiveData mOpenDetailsViewEvent = new MutableLiveData<>(false); private PatchCheat[] mPatchCheats; @@ -74,12 +76,13 @@ public class CheatsViewModel extends ViewModel return mSelectedCheat; } - public void setSelectedCheat(Cheat cheat) + public void setSelectedCheat(Cheat cheat, int position) { if (mIsEditing.getValue()) setIsEditing(false); mSelectedCheat.setValue(cheat); + mSelectedCheatPosition = position; } public LiveData getIsEditing() @@ -92,6 +95,32 @@ public class CheatsViewModel extends ViewModel mIsEditing.setValue(isEditing); } + /** + * When a cheat is edited, the integer stored in the returned LiveData + * changes to the position of that cheat, then changes back to null. + */ + public LiveData getCheatChangedEvent() + { + return mCheatChangedEvent; + } + + /** + * Notifies that an edit has been made to the contents of the currently selected cheat. + */ + public void notifySelectedCheatChanged() + { + notifyCheatChanged(mSelectedCheatPosition); + } + + /** + * Notifies that an edit has been made to the contents of the cheat at the given position. + */ + public void notifyCheatChanged(int position) + { + mCheatChangedEvent.setValue(position); + mCheatChangedEvent.setValue(null); + } + public LiveData getOpenDetailsViewEvent() { return mOpenDetailsViewEvent; diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java index 0b7ce49785..3a61b2e4b7 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java @@ -76,6 +76,7 @@ public class CheatDetailsFragment extends Fragment switch (result) { case Cheat.TRY_SET_SUCCESS: + mViewModel.notifySelectedCheatChanged(); mViewModel.setIsEditing(false); break; case Cheat.TRY_SET_FAIL_NO_NAME: diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatListFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatListFragment.java index 82c5b549bb..03f87f0c0c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatListFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatListFragment.java @@ -36,7 +36,7 @@ public class CheatListFragment extends Fragment CheatsActivity activity = (CheatsActivity) requireActivity(); CheatsViewModel viewModel = new ViewModelProvider(activity).get(CheatsViewModel.class); - recyclerView.setAdapter(new CheatsAdapter(viewModel)); + recyclerView.setAdapter(new CheatsAdapter(getViewLifecycleOwner(), viewModel)); recyclerView.setLayoutManager(new LinearLayoutManager(activity)); recyclerView.addItemDecoration(new DividerItemDecoration(activity, null)); } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatViewHolder.java index c48c7c27be..1ffcafafd5 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatViewHolder.java @@ -23,6 +23,7 @@ public class CheatViewHolder extends ViewHolder private CheatsViewModel mViewModel; private Cheat mCheat; + private int mPosition; public CheatViewHolder(@NonNull View itemView) { @@ -33,7 +34,7 @@ public class CheatViewHolder extends ViewHolder mCheckbox = itemView.findViewById(R.id.checkbox); } - public void bind(CheatsViewModel viewModel, Cheat item) + public void bind(CheatsViewModel viewModel, Cheat item, int position) { mCheckbox.setOnCheckedChangeListener(null); @@ -42,6 +43,7 @@ public class CheatViewHolder extends ViewHolder mViewModel = viewModel; mCheat = item; + mPosition = position; mRoot.setOnClickListener(this); mCheckbox.setOnCheckedChangeListener(this); @@ -49,12 +51,13 @@ public class CheatViewHolder extends ViewHolder public void onClick(View root) { - mViewModel.setSelectedCheat(mCheat); + mViewModel.setSelectedCheat(mCheat, mPosition); mViewModel.openDetailsView(); } public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mCheat.setEnabled(isChecked); + mViewModel.notifyCheatChanged(mPosition); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java index 3638ab383f..623f89c507 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java @@ -7,6 +7,7 @@ import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; +import androidx.lifecycle.LifecycleOwner; import androidx.recyclerview.widget.RecyclerView; import org.dolphinemu.dolphinemu.R; @@ -17,9 +18,15 @@ public class CheatsAdapter extends RecyclerView.Adapter { private final CheatsViewModel mViewModel; - public CheatsAdapter(CheatsViewModel viewModel) + public CheatsAdapter(LifecycleOwner owner, CheatsViewModel viewModel) { mViewModel = viewModel; + + mViewModel.getCheatChangedEvent().observe(owner, (position) -> + { + if (position != null) + notifyItemChanged(position); + }); } @NonNull @@ -34,7 +41,7 @@ public class CheatsAdapter extends RecyclerView.Adapter @Override public void onBindViewHolder(@NonNull CheatViewHolder holder, int position) { - holder.bind(mViewModel, getItemAt(position)); + holder.bind(mViewModel, getItemAt(position), position); } @Override