From 18d6f2a31e238754e3ffae1b7d998b61489286c4 Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Fri, 25 Jun 2021 17:29:39 -0700 Subject: [PATCH] Adds editing support for other traits using some shared fragments. --- .../EditAbilitiesRecyclerViewAdapter.java | 67 ----- .../ui/editmonster/EditAbilityFragment.java | 82 ------ .../ui/editmonster/EditMonsterFragment.java | 31 ++- .../ui/editmonster/EditMonsterViewModel.java | 234 ++++++++---------- .../ui/editmonster/EditTraitFragment.java | 33 +-- ...agment.java => EditTraitListFragment.java} | 71 ++++-- .../EditTraitsRecyclerViewAdapter.java | 41 ++- .../layout/fragment_edit_abilities_list.xml | 33 --- .../fragment_edit_abilities_list_item.xml | 13 - .../res/layout/fragment_edit_traits_list.xml | 4 +- .../layout/fragment_edit_traits_list_item.xml | 2 +- .../main/res/navigation/mobile_navigation.xml | 32 ++- Android/app/src/main/res/values/strings.xml | 3 +- 13 files changed, 225 insertions(+), 421 deletions(-) delete mode 100644 Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilitiesRecyclerViewAdapter.java delete mode 100644 Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilityFragment.java rename Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/{EditAbilitiesFragment.java => EditTraitListFragment.java} (51%) delete mode 100644 Android/app/src/main/res/layout/fragment_edit_abilities_list.xml delete mode 100644 Android/app/src/main/res/layout/fragment_edit_abilities_list_item.xml diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilitiesRecyclerViewAdapter.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilitiesRecyclerViewAdapter.java deleted file mode 100644 index 32f4f44..0000000 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilitiesRecyclerViewAdapter.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.majinnaibu.monstercards.ui.editmonster; - -import android.view.LayoutInflater; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.recyclerview.widget.RecyclerView; - -import com.majinnaibu.monstercards.databinding.FragmentEditAbilitiesListItemBinding; -import com.majinnaibu.monstercards.models.Trait; - -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class EditAbilitiesRecyclerViewAdapter extends RecyclerView.Adapter { - private final List mValues; - private final ItemCallback mOnClick; - - public EditAbilitiesRecyclerViewAdapter(List items, ItemCallback onClick) { - mValues = items; - mOnClick = onClick; - } - - @NotNull - @Override - public ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { - return new ViewHolder(FragmentEditAbilitiesListItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); - } - - @Override - public void onBindViewHolder(final ViewHolder holder, int position) { - holder.mItem = mValues.get(position); - holder.mContentView.setText(mValues.get(position).name); - holder.itemView.setOnClickListener(v -> { - if (mOnClick != null) { - mOnClick.onItemCallback(holder.mItem); - } - }); - } - - @Override - public int getItemCount() { - return mValues.size(); - } - - public interface ItemCallback { - void onItemCallback(Trait trait); - } - - public static class ViewHolder extends RecyclerView.ViewHolder { - public final TextView mContentView; - public Trait mItem; - - public ViewHolder(FragmentEditAbilitiesListItemBinding binding) { - super(binding.getRoot()); - mContentView = binding.content; - } - - @NotNull - @Override - public String toString() { - return super.toString() + " '" + mContentView.getText() + "'"; - } - - } -} diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilityFragment.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilityFragment.java deleted file mode 100644 index ee3a4e9..0000000 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilityFragment.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.majinnaibu.monstercards.ui.editmonster; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.EditText; - -import androidx.activity.OnBackPressedCallback; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.lifecycle.ViewModelProvider; -import androidx.navigation.NavBackStackEntry; -import androidx.navigation.NavController; -import androidx.navigation.Navigation; - -import com.majinnaibu.monstercards.R; -import com.majinnaibu.monstercards.models.Trait; -import com.majinnaibu.monstercards.ui.shared.MCFragment; -import com.majinnaibu.monstercards.utils.Logger; -import com.majinnaibu.monstercards.utils.TextChangedListener; - -public class EditAbilityFragment extends MCFragment { - private EditMonsterViewModel mEditMonsterViewModel; - private EditTraitViewModel mViewModel; - private ViewHolder mHolder; - private Trait mOldValue; - - @Override - public void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { - mViewModel = new ViewModelProvider(this).get(EditTraitViewModel.class); - if (getArguments() != null) { - EditAbilityFragmentArgs args = EditAbilityFragmentArgs.fromBundle(getArguments()); - mOldValue = new Trait(args.getName(), args.getDescription()); - mViewModel.copyFromTrait(mOldValue); - } else { - Logger.logWTF("EditAbilityFragment needs arguments"); - mOldValue = null; - } - - super.onCreate(savedInstanceState); - } - - @Nullable - @org.jetbrains.annotations.Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment); - NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation); - mEditMonsterViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class); - View root = inflater.inflate(R.layout.fragment_edit_trait, container, false); - mHolder = new ViewHolder(root); - - mHolder.name.setText(mViewModel.getNameAsString()); - mHolder.name.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setName(s.toString()))); - - mHolder.description.setText(mViewModel.getDescriptionAsString()); - mHolder.description.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setDescription(s.toString()))); - - requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { - @Override - public void handleOnBackPressed() { - if (mViewModel.hasChanges()) { - mEditMonsterViewModel.replaceAbility(mOldValue, mViewModel.getAbilityValue()); - } - Navigation.findNavController(requireView()).navigateUp(); - } - }); - - return root; - } - - private static class ViewHolder { - EditText description; - EditText name; - - ViewHolder(View root) { - description = root.findViewById(R.id.description); - name = root.findViewById(R.id.name); - } - } -} diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterFragment.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterFragment.java index 1841e13..f30614d 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterFragment.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterFragment.java @@ -19,6 +19,7 @@ import androidx.navigation.Navigation; import com.google.android.material.snackbar.Snackbar; import com.majinnaibu.monstercards.R; import com.majinnaibu.monstercards.data.MonsterRepository; +import com.majinnaibu.monstercards.data.enums.TraitType; import com.majinnaibu.monstercards.models.Monster; import com.majinnaibu.monstercards.ui.monster.MonsterDetailFragmentArgs; import com.majinnaibu.monstercards.ui.shared.MCFragment; @@ -146,10 +147,36 @@ public class EditMonsterFragment extends MCFragment { }); mHolder.abilities.setOnClickListener(v -> { - NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditAbilitiesFragment(); + NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.ABILITY); Navigation.findNavController(requireView()).navigate(action); }); + mHolder.actions.setOnClickListener(v -> { + NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.ACTION); + Navigation.findNavController(requireView()).navigate(action); + }); + + mHolder.lairActions.setOnClickListener(v -> { + NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.LAIR_ACTION); + Navigation.findNavController(requireView()).navigate(action); + }); + + mHolder.legendaryActions.setOnClickListener(v -> { + NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.LEGENDARY_ACTION); + Navigation.findNavController(requireView()).navigate(action); + }); + + mHolder.reactions.setOnClickListener(v -> { + NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.REACTIONS); + Navigation.findNavController(requireView()).navigate(action); + }); + + mHolder.regionalActions.setOnClickListener(v -> { + NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.REGIONAL_ACTION); + Navigation.findNavController(requireView()).navigate(action); + }); + + requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { @@ -241,4 +268,4 @@ public class EditMonsterFragment extends MCFragment { regionalActions = root.findViewById(R.id.regionalActions); } } -} \ No newline at end of file +} diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java index 58c990c..7cf7c32 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java @@ -9,6 +9,7 @@ import com.majinnaibu.monstercards.data.enums.AdvantageType; import com.majinnaibu.monstercards.data.enums.ArmorType; import com.majinnaibu.monstercards.data.enums.ChallengeRating; import com.majinnaibu.monstercards.data.enums.ProficiencyType; +import com.majinnaibu.monstercards.data.enums.TraitType; import com.majinnaibu.monstercards.helpers.StringHelper; import com.majinnaibu.monstercards.models.Language; import com.majinnaibu.monstercards.models.Monster; @@ -16,6 +17,7 @@ import com.majinnaibu.monstercards.models.Skill; import com.majinnaibu.monstercards.models.Trait; import com.majinnaibu.monstercards.ui.shared.ChangeTrackedViewModel; import com.majinnaibu.monstercards.utils.ChangeTrackedLiveData; +import com.majinnaibu.monstercards.utils.Logger; import java.util.ArrayList; import java.util.Collections; @@ -740,14 +742,14 @@ public class EditMonsterViewModel extends ChangeTrackedViewModel { return mTelepathyRange; } - public int getTelepathyRangeUnboxed() { - return Helpers.unboxInteger(mTelepathyRange.getValue(), 0); - } - public void setTelepathyRange(int telepathyRange) { mTelepathyRange.setValue(telepathyRange); } + public int getTelepathyRangeUnboxed() { + return Helpers.unboxInteger(mTelepathyRange.getValue(), 0); + } + public LiveData getUnderstandsButDescription() { return mUnderstandsButDescription; } @@ -923,133 +925,6 @@ public class EditMonsterViewModel extends ChangeTrackedViewModel { Helpers.replaceItemInList(mLanguages, oldLanguage, newLanguage, Language::compareTo); } - public LiveData> getAbilities() { - return mAbilities; - } - - public List getAbilitiesArray() { - return mAbilities.getValue(); - } - - public Trait addNewAbility() { - Trait newAbility = new Trait("", ""); - return Helpers.addItemToList(mAbilities, newAbility, Trait::compareTo); - } - - public void removeAbility(int position) { - Helpers.removeFromList(mAbilities, position); - } - - public void replaceAbility(Trait oldAbility, Trait newAbility) { - Helpers.replaceItemInList(mAbilities, oldAbility, newAbility); - } - - - public LiveData> getActions() { - return mActions; - } - - public List getActionsArray() { - return mActions.getValue(); - } - - public Trait addNewAction() { - Trait newAction = new Trait("", ""); - return Helpers.addItemToList(mActions, newAction, Trait::compareTo); - } - - public void removeAction(int position) { - Helpers.removeFromList(mActions, position); - } - - public void replaceAction(Trait oldAction, Trait newAction) { - Helpers.replaceItemInList(mActions, oldAction, newAction); - } - - public LiveData> getReactions() { - return mReactions; - } - - public List getReactionsArray() { - return mReactions.getValue(); - } - - public Trait addNewReaction() { - Trait newReaction = new Trait("", ""); - return Helpers.addItemToList(mReactions, newReaction, Trait::compareTo); - } - - public void removeReaction(int position) { - Helpers.removeFromList(mReactions, position); - } - - public void replaceReaction(Trait oldReaction, Trait newReaction) { - Helpers.replaceItemInList(mReactions, oldReaction, newReaction); - } - - public LiveData> getLairActions() { - return mLairActions; - } - - public List getLairActionsArray() { - return mLairActions.getValue(); - } - - public Trait addNewLairAction() { - Trait newLairAction = new Trait("", ""); - return Helpers.addItemToList(mLairActions, newLairAction, Trait::compareTo); - } - - public void removeLairAction(int position) { - Helpers.removeFromList(mLairActions, position); - } - - public void replaceLairAction(Trait oldLairAction, Trait newLairAction) { - Helpers.replaceItemInList(mLairActions, oldLairAction, newLairAction); - } - - public LiveData> getLegendaryActions() { - return mLegendaryActions; - } - - public List getLegendaryActionsArray() { - return mLegendaryActions.getValue(); - } - - public Trait addNewLegendaryAction() { - Trait newLegendaryAction = new Trait("", ""); - return Helpers.addItemToList(mLegendaryActions, newLegendaryAction, Trait::compareTo); - } - - public void removeLegendaryAction(int position) { - Helpers.removeFromList(mLegendaryActions, position); - } - - public void replaceLegendaryAction(Trait oldLegendaryAction, Trait newLegendaryAction) { - Helpers.replaceItemInList(mLegendaryActions, oldLegendaryAction, newLegendaryAction); - } - - public LiveData> getRegionalActions() { - return mRegionalActions; - } - - public List getRegionalActionsArray() { - return mRegionalActions.getValue(); - } - - public Trait addNewRegionalAction() { - Trait newRegionalAction = new Trait("", ""); - return Helpers.addItemToList(mRegionalActions, newRegionalAction, Trait::compareTo); - } - - public void removeRegionalAction(int position) { - Helpers.removeFromList(mRegionalActions, position); - } - - public void replaceRegionalAction(Trait oldRegionalAction, Trait newRegionalAction) { - Helpers.replaceItemInList(mRegionalActions, oldRegionalAction, newRegionalAction); - } - public Monster buildMonster() { Monster monster = new Monster(); @@ -1114,12 +989,107 @@ public class EditMonsterViewModel extends ChangeTrackedViewModel { return monster; } + public LiveData> getTraits(TraitType type) { + switch (type) { + case ABILITY: + return mAbilities; + case ACTION: + return mActions; + case LAIR_ACTION: + return mLairActions; + case LEGENDARY_ACTION: + return mLegendaryActions; + case REACTIONS: + return mReactions; + case REGIONAL_ACTION: + return mRegionalActions; + default: + Logger.logWTF(String.format("Unrecognized TraitType: %s", type)); + return null; + } + } + + public void removeTrait(TraitType type, int position) { + switch (type) { + case ABILITY: + Helpers.removeFromList(mAbilities, position); + break; + case ACTION: + Helpers.removeFromList(mActions, position); + break; + case LAIR_ACTION: + Helpers.removeFromList(mLairActions, position); + break; + case LEGENDARY_ACTION: + Helpers.removeFromList(mLegendaryActions, position); + break; + case REACTIONS: + Helpers.removeFromList(mReactions, position); + break; + case REGIONAL_ACTION: + Helpers.removeFromList(mRegionalActions, position); + break; + default: + Logger.logWTF(String.format("Unrecognized TraitType: %s", type)); + } + } + + public void replaceTrait(TraitType type, Trait oldTrait, Trait newTrait) { + switch (type) { + case ABILITY: + Helpers.replaceItemInList(mAbilities, oldTrait, newTrait); + break; + case ACTION: + Helpers.replaceItemInList(mActions, oldTrait, newTrait); + break; + case LAIR_ACTION: + Helpers.replaceItemInList(mLairActions, oldTrait, newTrait); + break; + case LEGENDARY_ACTION: + Helpers.replaceItemInList(mLegendaryActions, oldTrait, newTrait); + break; + case REACTIONS: + Helpers.replaceItemInList(mReactions, oldTrait, newTrait); + break; + case REGIONAL_ACTION: + Helpers.replaceItemInList(mRegionalActions, oldTrait, newTrait); + break; + default: + Logger.logWTF(String.format("Unrecognized TraitType: %s", type)); + } + } + + public Trait addNewTrait(TraitType type) { + Trait newAction = new Trait("", ""); + switch (type) { + case ABILITY: + return Helpers.addItemToList(mAbilities, newAction); + case ACTION: + return Helpers.addItemToList(mActions, newAction); + case LAIR_ACTION: + return Helpers.addItemToList(mLairActions, newAction); + case LEGENDARY_ACTION: + return Helpers.addItemToList(mLegendaryActions, newAction); + case REACTIONS: + return Helpers.addItemToList(mReactions, newAction); + case REGIONAL_ACTION: + return Helpers.addItemToList(mRegionalActions, newAction); + default: + Logger.logWTF(String.format("Unrecognized TraitType: %s", type)); + return null; + } + } + @SuppressWarnings("SameParameterValue") private static class Helpers { static String addStringToList(String newString, MutableLiveData> strings) { return addItemToList(strings, newString, String::compareToIgnoreCase); } + static T addItemToList(MutableLiveData> listData, T newItem) { + return addItemToList(listData, newItem, null); + } + static T addItemToList(MutableLiveData> listData, T newItem, Comparator comparator) { ArrayList newList = new ArrayList<>(listData.getValue()); newList.add(newItem); @@ -1174,7 +1144,7 @@ public class EditMonsterViewModel extends ChangeTrackedViewModel { boolean hasReplaced = false; ArrayList newList = new ArrayList<>(oldList.size()); for (T item : oldList) { - if (Objects.equals(item, oldItem)) { + if (!hasReplaced && Objects.equals(item, oldItem)) { newList.add(newItem); hasReplaced = true; } else { diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitFragment.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitFragment.java index b73ece1..e227340 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitFragment.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitFragment.java @@ -29,7 +29,7 @@ public class EditTraitFragment extends MCFragment { private TraitType mTraitType; @Override - public void onCreate(@Nullable Bundle savedInstanceState) { + public void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { mViewModel = new ViewModelProvider(this).get(EditTraitViewModel.class); if (getArguments() != null) { EditTraitFragmentArgs args = EditTraitFragmentArgs.fromBundle(getArguments()); @@ -40,11 +40,12 @@ public class EditTraitFragment extends MCFragment { Logger.logWTF("EditTraitFragment needs arguments"); mOldValue = null; } + super.onCreate(savedInstanceState); } @Nullable - + @org.jetbrains.annotations.Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment); @@ -52,7 +53,6 @@ public class EditTraitFragment extends MCFragment { mEditMonsterViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class); View root = inflater.inflate(R.layout.fragment_edit_trait, container, false); mHolder = new EditTraitFragment.ViewHolder(root); - setTitle(getTitleForTraitType(mTraitType)); mHolder.name.setText(mViewModel.getNameAsString()); mHolder.name.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setName(s.toString()))); @@ -73,36 +73,11 @@ public class EditTraitFragment extends MCFragment { return root; } - @Override - public void onStart() { - super.onStart(); - mHolder.name.requestFocus(); - } - - private String getTitleForTraitType(TraitType type) { - switch (type) { - case ABILITY: - return getString(R.string.title_editAbility); - case ACTION: - return getString(R.string.title_editAction); - case LAIR_ACTION: - return getString(R.string.title_editLairAction); - case LEGENDARY_ACTION: - return getString(R.string.title_editLegendaryAction); - case REACTIONS: - return getString(R.string.title_editReaction); - case REGIONAL_ACTION: - return getString(R.string.title_editRegionalAction); - default: - return getString(R.string.title_editTrait); - } - } - private static class ViewHolder { EditText description; EditText name; - ViewHolder(@NonNull View root) { + ViewHolder(View root) { description = root.findViewById(R.id.description); name = root.findViewById(R.id.name); } diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilitiesFragment.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitListFragment.java similarity index 51% rename from Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilitiesFragment.java rename to Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitListFragment.java index ce0a0d8..299d89c 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditAbilitiesFragment.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitListFragment.java @@ -8,6 +8,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.lifecycle.LiveData; import androidx.lifecycle.ViewModelProvider; import androidx.navigation.NavBackStackEntry; import androidx.navigation.NavController; @@ -20,30 +21,45 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.majinnaibu.monstercards.R; +import com.majinnaibu.monstercards.data.enums.TraitType; import com.majinnaibu.monstercards.models.Trait; import com.majinnaibu.monstercards.ui.shared.MCFragment; import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback; import com.majinnaibu.monstercards.utils.Logger; -public class EditAbilitiesFragment extends MCFragment { +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +// TODO: rename to EditTraitsFragment +public class EditTraitListFragment extends MCFragment { private EditMonsterViewModel mViewModel; private ViewHolder mHolder; + private TraitType mTraitType; - private void navigateToEditAbility(Trait trait) { - NavDirections action = EditAbilitiesFragmentDirections.actionEditAbilitiesFragmentToEditAbilityFragment(trait.description, trait.name); - Navigation.findNavController(requireView()).navigate(action); + + @Override + public void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + if (getArguments() != null) { + EditTraitListFragmentArgs args = EditTraitListFragmentArgs.fromBundle(getArguments()); + mTraitType = args.getTraitType(); + } else { + Logger.logWTF("EditTraitFragment needs arguments"); + } + super.onCreate(savedInstanceState); } @Nullable + @org.jetbrains.annotations.Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment); NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation); mViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class); - View root = inflater.inflate(R.layout.fragment_edit_abilities_list, container, false); + View root = inflater.inflate(R.layout.fragment_edit_traits_list, container, false); mHolder = new ViewHolder(root); setupRecyclerView(mHolder.list); - setupAddAbilityButton(mHolder.addAbility); + setupAddButton(mHolder.addTrait); return root; } @@ -52,38 +68,47 @@ public class EditAbilitiesFragment extends MCFragment { LinearLayoutManager layoutManager = new LinearLayoutManager(context); recyclerView.setLayoutManager(layoutManager); - mViewModel.getAbilities().observe(getViewLifecycleOwner(), abilities -> { - EditAbilitiesRecyclerViewAdapter adapter = new EditAbilitiesRecyclerViewAdapter(abilities, ability -> { - if (ability != null) { - navigateToEditAbility(ability); - } else { - Logger.logError("Can't navigate to EditAbilityFragment with a null ability"); - } + LiveData> traitData = mViewModel.getTraits(mTraitType); + if (traitData != null) { + traitData.observe(getViewLifecycleOwner(), traits -> { + EditTraitsRecyclerViewAdapter adapter = new EditTraitsRecyclerViewAdapter(traits, trait -> { + if (trait != null) { + navigateToEditTrait(trait); + } else { + Logger.logError("Can't navigate to EditTraitFragment with a null trait"); + } + }); + recyclerView.setAdapter(adapter); }); - recyclerView.setAdapter(adapter); - }); - + } DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, layoutManager.getOrientation()); recyclerView.addItemDecoration(dividerItemDecoration); - ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(context, mViewModel::removeAbility)); + ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(context, position -> mViewModel.removeTrait(mTraitType, position))); itemTouchHelper.attachToRecyclerView(recyclerView); } - private void setupAddAbilityButton(@NonNull FloatingActionButton fab) { + private void setupAddButton(@NonNull FloatingActionButton fab) { fab.setOnClickListener(view -> { - Trait ability = mViewModel.addNewAbility(); - navigateToEditAbility(ability); + Trait newTrait = mViewModel.addNewTrait(mTraitType); + if (newTrait != null) { + navigateToEditTrait(newTrait); + } }); } + protected void navigateToEditTrait(Trait trait) { + NavDirections action = EditTraitListFragmentDirections.actionEditTraitListFragmentToEditTraitFragment(trait.description, trait.name, mTraitType); + Navigation.findNavController(requireView()).navigate(action); + } + private static class ViewHolder { RecyclerView list; - FloatingActionButton addAbility; + FloatingActionButton addTrait; ViewHolder(View root) { list = root.findViewById(R.id.list); - addAbility = root.findViewById(R.id.add_ability); + addTrait = root.findViewById(R.id.add_trait); } } } diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitsRecyclerViewAdapter.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitsRecyclerViewAdapter.java index b7fc0c6..175fa35 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitsRecyclerViewAdapter.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditTraitsRecyclerViewAdapter.java @@ -4,44 +4,34 @@ import android.view.LayoutInflater; import android.view.ViewGroup; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.ListAdapter; import androidx.recyclerview.widget.RecyclerView; import com.majinnaibu.monstercards.databinding.FragmentEditTraitsListItemBinding; import com.majinnaibu.monstercards.models.Trait; -public class EditTraitsRecyclerViewAdapter extends ListAdapter { - private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { +import org.jetbrains.annotations.NotNull; - @Override - public boolean areItemsTheSame(@NonNull Trait oldItem, @NonNull Trait newItem) { - return oldItem.equals(newItem); - } +import java.util.List; - @Override - public boolean areContentsTheSame(@NonNull Trait oldItem, @NonNull Trait newItem) { - return oldItem.equals(newItem); - } - }; +public class EditTraitsRecyclerViewAdapter extends RecyclerView.Adapter { + private final List mValues; private final ItemCallback mOnClick; - protected EditTraitsRecyclerViewAdapter(ItemCallback onClick) { - super(DIFF_CALLBACK); + public EditTraitsRecyclerViewAdapter(List items, ItemCallback onClick) { + mValues = items; mOnClick = onClick; } - @NonNull + @NotNull @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + public ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { return new ViewHolder(FragmentEditTraitsListItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); } @Override - public void onBindViewHolder(@NonNull final ViewHolder holder, int position) { - holder.mItem = getItem(position); - holder.mContentView.setText(holder.mItem.name); + public void onBindViewHolder(final ViewHolder holder, int position) { + holder.mItem = mValues.get(position); + holder.mContentView.setText(mValues.get(position).name); holder.itemView.setOnClickListener(v -> { if (mOnClick != null) { mOnClick.onItemCallback(holder.mItem); @@ -49,6 +39,11 @@ public class EditTraitsRecyclerViewAdapter extends ListAdapter - - - - - - \ No newline at end of file diff --git a/Android/app/src/main/res/layout/fragment_edit_abilities_list_item.xml b/Android/app/src/main/res/layout/fragment_edit_abilities_list_item.xml deleted file mode 100644 index 6e9049a..0000000 --- a/Android/app/src/main/res/layout/fragment_edit_abilities_list_item.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Android/app/src/main/res/layout/fragment_edit_traits_list.xml b/Android/app/src/main/res/layout/fragment_edit_traits_list.xml index a4b9f4b..697c700 100644 --- a/Android/app/src/main/res/layout/fragment_edit_traits_list.xml +++ b/Android/app/src/main/res/layout/fragment_edit_traits_list.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.editmonster.EditTraitsFragment"> + tools:context=".ui.editmonster.EditAbilitiesFragment"> + tools:listitem="@layout/fragment_edit_abilities_list_item" /> diff --git a/Android/app/src/main/res/navigation/mobile_navigation.xml b/Android/app/src/main/res/navigation/mobile_navigation.xml index d2f48e8..977670b 100644 --- a/Android/app/src/main/res/navigation/mobile_navigation.xml +++ b/Android/app/src/main/res/navigation/mobile_navigation.xml @@ -112,8 +112,8 @@ android:id="@+id/action_editMonsterFragment_to_editLanguagesFragment" app:destination="@id/editLanguagesFragment" /> + android:id="@+id/action_editMonsterFragment_to_editTraitListFragment" + app:destination="@id/editTraitListFragment" /> - - - + android:id="@+id/editTraitFragment" + android:name="com.majinnaibu.monstercards.ui.editmonster.EditTraitFragment" + android:label="EditTraitFragment"> + + + + + diff --git a/Android/app/src/main/res/values/strings.xml b/Android/app/src/main/res/values/strings.xml index 3ee197d..bd8f358 100644 --- a/Android/app/src/main/res/values/strings.xml +++ b/Android/app/src/main/res/values/strings.xml @@ -6,6 +6,7 @@ Add monster Add Sense Add Skill + Add Trait Edit Actions MonsterCards @@ -88,4 +89,4 @@ Library Search WIS - \ No newline at end of file +