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.
This commit is contained in:
JosJuice 2021-08-07 19:40:45 +02:00
parent 43dcbf33ad
commit fc6c31c3db
5 changed files with 46 additions and 6 deletions

View File

@ -10,9 +10,11 @@ public class CheatsViewModel extends ViewModel
{
private boolean mLoaded = false;
private int mSelectedCheatPosition = -1;
private final MutableLiveData<Cheat> mSelectedCheat = new MutableLiveData<>(null);
private final MutableLiveData<Boolean> mIsEditing = new MutableLiveData<>(false);
private final MutableLiveData<Integer> mCheatChangedEvent = new MutableLiveData<>(null);
private final MutableLiveData<Boolean> 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<Boolean> 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<Integer> 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<Boolean> getOpenDetailsViewEvent()
{
return mOpenDetailsViewEvent;

View File

@ -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:

View File

@ -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));
}

View File

@ -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);
}
}

View File

@ -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<CheatViewHolder>
{
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<CheatViewHolder>
@Override
public void onBindViewHolder(@NonNull CheatViewHolder holder, int position)
{
holder.bind(mViewModel, getItemAt(position));
holder.bind(mViewModel, getItemAt(position), position);
}
@Override