Makes monster editor smoother and fixes colors.

This commit is contained in:
2026-09-16 22:04:30 -07:00
parent d63b125175
commit ddb58622d6
14 changed files with 944 additions and 308 deletions

View File

@@ -1,9 +1,11 @@
package com.majinnaibu.monstercards.ui.editmonster;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.activity.OnBackPressedCallback;
@@ -14,7 +16,7 @@ import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavBackStackEntry;
import androidx.navigation.NavController;
import androidx.navigation.NavDirections;
import androidx.navigation.Navigation;
import androidx.navigation.fragment.NavHostFragment;
import com.google.android.material.snackbar.Snackbar;
import com.majinnaibu.monstercards.R;
@@ -22,10 +24,11 @@ import com.majinnaibu.monstercards.data.MonsterRepository;
import com.majinnaibu.monstercards.data.enums.StringType;
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;
import com.majinnaibu.monstercards.utils.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
@@ -43,21 +46,34 @@ public class EditMonsterFragment extends MCFragment {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
MonsterRepository repository = getMonsterRepository();
Bundle arguments = getArguments();
assert arguments != null;
UUID monsterId = UUID.fromString(MonsterDetailFragmentArgs.fromBundle(arguments).getMonsterId());
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_monster, container, false);
mHolder = new ViewHolder(root);
MonsterRepository repository = getMonsterRepository();
Bundle arguments = getArguments();
if (arguments == null) {
Logger.logError("Arguments bundle is null in EditMonsterFragment");
return root;
}
String monsterIdStr = EditMonsterFragmentArgs.fromBundle(arguments).getMonsterId();
if (monsterIdStr == null || monsterIdStr.isEmpty()) {
Logger.logError("monsterId is null or empty in EditMonsterFragment");
return root;
}
UUID monsterId = UUID.fromString(monsterIdStr);
try {
NavController navController = NavHostFragment.findNavController(this);
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
mViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
} catch (Exception e) {
mViewModel = new ViewModelProvider(this).get(EditMonsterViewModel.class);
}
setTitle(getString(R.string.title_editMonster_fmt, getString(R.string.default_monster_name)));
// TODO: Show a loading spinner until we have the monster loaded.
if (mViewModel.hasError() || !mViewModel.hasLoaded() || !Objects.equals(mViewModel.getMonsterId().getValue(), monsterId)) {
repository.getMonster(monsterId).toObservable()
.firstOrError()
@@ -73,7 +89,6 @@ public class EditMonsterFragment extends MCFragment {
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
// TODO: Show an error state.
Logger.logError(e);
mViewModel.setHasError(true);
mViewModel.setErrorMessage(e.toString());
@@ -82,101 +97,9 @@ public class EditMonsterFragment extends MCFragment {
});
}
mHolder.basicInfoButton.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditBasicInfoFragment();
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.armorButton.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditArmorFragment();
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.speedButton.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSpeedFragment();
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.abilityScoresButton.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditAbilityScoresFragment();
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.savingThrows.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSavingThrowsFragment();
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.challengeRating.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditChallengeRatingFragment();
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.skills.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSkillsFragment();
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.senses.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.SENSE);
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.conditionImmunities.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.CONDITION_IMMUNITY);
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.damageImmunities.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_IMMUNITY);
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.damageResistances.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_RESISTANCE);
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.damageVulnerabilities.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_VULNERABILITY);
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.languages.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditLanguagesFragment();
Navigation.findNavController(requireView()).navigate(action);
});
mHolder.abilities.setOnClickListener(v -> {
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);
});
setupAccordions();
setupSummaries();
setupSubClickListeners();
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
@Override
@@ -187,7 +110,6 @@ public class EditMonsterFragment extends MCFragment {
alertDialog.setTitle("Unsaved Changes");
alertDialog.setMessage("Do you want to save your changes?");
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Save", (dialog, id) -> {
// Save the monster. Navigate up if the save is successful. Show a SnackBar if there was an error.
getMonsterRepository().saveMonster(mViewModel.buildMonster())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@@ -195,29 +117,23 @@ public class EditMonsterFragment extends MCFragment {
new DisposableCompletableObserver() {
@Override
public void onComplete() {
Navigation.findNavController(requireView()).navigateUp();
NavHostFragment.findNavController(EditMonsterFragment.this).navigateUp();
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
Logger.logError("Error creating monster", e);
Logger.logError("Error saving monster", e);
assert view != null;
Snackbar.make(view, getString(R.string.snackbar_failed_to_create_monster), Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Discard", (dialog, id) -> {
// Navigate up ignoring unsaved changes.
Navigation.findNavController(requireView()).navigateUp();
});
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Cancel", (dialog, id) -> {
// Do nothing.
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Discard", (dialog, id) -> NavHostFragment.findNavController(EditMonsterFragment.this).navigateUp());
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Cancel", (dialog, id) -> {});
alertDialog.show();
} else {
// No changes so we can safely leave.
Navigation.findNavController(requireView()).navigateUp();
NavHostFragment.findNavController(EditMonsterFragment.this).navigateUp();
}
}
});
@@ -225,42 +141,344 @@ public class EditMonsterFragment extends MCFragment {
return root;
}
private static class ViewHolder {
private void setupAccordions() {
if (mHolder.headerBasicInfo != null && mHolder.bodyBasicInfo != null && mHolder.chevronBasicInfo != null) {
setupAccordion(mHolder.headerBasicInfo, mHolder.bodyBasicInfo, mHolder.chevronBasicInfo);
}
if (mHolder.headerCombatAbilities != null && mHolder.bodyCombatAbilities != null && mHolder.chevronCombatAbilities != null) {
setupAccordion(mHolder.headerCombatAbilities, mHolder.bodyCombatAbilities, mHolder.chevronCombatAbilities);
}
if (mHolder.headerSavesSkillsLanguages != null && mHolder.bodySavesSkillsLanguages != null && mHolder.chevronSavesSkillsLanguages != null) {
setupAccordion(mHolder.headerSavesSkillsLanguages, mHolder.bodySavesSkillsLanguages, mHolder.chevronSavesSkillsLanguages);
}
if (mHolder.headerDefenses != null && mHolder.bodyDefenses != null && mHolder.chevronDefenses != null) {
setupAccordion(mHolder.headerDefenses, mHolder.bodyDefenses, mHolder.chevronDefenses);
}
if (mHolder.headerTraitsActions != null && mHolder.bodyTraitsActions != null && mHolder.chevronTraitsActions != null) {
setupAccordion(mHolder.headerTraitsActions, mHolder.bodyTraitsActions, mHolder.chevronTraitsActions);
}
}
TextView basicInfoButton;
TextView armorButton;
TextView speedButton;
TextView abilityScoresButton;
TextView savingThrows;
TextView skills;
TextView conditionImmunities;
TextView damageImmunities;
TextView damageResistances;
TextView damageVulnerabilities;
TextView senses;
TextView languages;
TextView challengeRating;
TextView abilities;
TextView actions;
TextView reactions;
TextView legendaryActions;
TextView lairActions;
TextView regionalActions;
private void setupAccordion(View header, View body, ImageView chevron) {
header.setOnClickListener(v -> {
boolean isExpanded = body.getVisibility() == View.VISIBLE;
body.setVisibility(isExpanded ? View.GONE : View.VISIBLE);
chevron.setImageResource(isExpanded ? R.drawable.ic_expand_more_24 : R.drawable.ic_expand_less_24);
});
}
private void setupSummaries() {
mViewModel.getName().observe(getViewLifecycleOwner(), v -> updateBasicInfoSummary());
mViewModel.getSize().observe(getViewLifecycleOwner(), v -> updateBasicInfoSummary());
mViewModel.getType().observe(getViewLifecycleOwner(), v -> updateBasicInfoSummary());
mViewModel.getChallengeRating().observe(getViewLifecycleOwner(), v -> updateBasicInfoSummary());
mViewModel.getStrength().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
mViewModel.getDexterity().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
mViewModel.getConstitution().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
mViewModel.getIntelligence().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
mViewModel.getWisdom().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
mViewModel.getCharisma().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
mViewModel.getSkills().observe(getViewLifecycleOwner(), v -> updateSavesSkillsSummary());
mViewModel.getLanguages().observe(getViewLifecycleOwner(), v -> updateSavesSkillsSummary());
mViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), v -> updateDefensesSummary());
mViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), v -> updateDefensesSummary());
mViewModel.getDamageResistances().observe(getViewLifecycleOwner(), v -> updateDefensesSummary());
mViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), v -> updateDefensesSummary());
mViewModel.getAbilities().observe(getViewLifecycleOwner(), v -> updateTraitsActionsSummary());
mViewModel.getActions().observe(getViewLifecycleOwner(), v -> updateTraitsActionsSummary());
mViewModel.getReactions().observe(getViewLifecycleOwner(), v -> updateTraitsActionsSummary());
}
private void updateBasicInfoSummary() {
if (mHolder.summaryBasicInfo == null) return;
String name = mViewModel.getName().getValue();
String size = mViewModel.getSize().getValue();
String type = mViewModel.getType().getValue();
List<String> parts = new ArrayList<>();
if (!TextUtils.isEmpty(name)) parts.add(name);
if (!TextUtils.isEmpty(size)) parts.add(size);
if (!TextUtils.isEmpty(type)) parts.add(type);
mHolder.summaryBasicInfo.setText(parts.isEmpty() ? "Tap to edit basic info" : TextUtils.join(", ", parts));
}
private void updateCombatAbilitiesSummary() {
if (mHolder.summaryCombatAbilities == null) return;
Integer str = mViewModel.getStrength().getValue();
Integer dex = mViewModel.getDexterity().getValue();
Integer con = mViewModel.getConstitution().getValue();
Integer intel = mViewModel.getIntelligence().getValue();
Integer wis = mViewModel.getWisdom().getValue();
Integer cha = mViewModel.getCharisma().getValue();
String summary = String.format("STR %d | DEX %d | CON %d | INT %d | WIS %d | CHA %d",
str != null ? str : 10,
dex != null ? dex : 10,
con != null ? con : 10,
intel != null ? intel : 10,
wis != null ? wis : 10,
cha != null ? cha : 10);
mHolder.summaryCombatAbilities.setText(summary);
}
private void updateSavesSkillsSummary() {
if (mHolder.summarySavesSkillsLanguages == null) return;
int skillsCount = mViewModel.getSkills().getValue() != null ? mViewModel.getSkills().getValue().size() : 0;
int languagesCount = mViewModel.getLanguages().getValue() != null ? mViewModel.getLanguages().getValue().size() : 0;
mHolder.summarySavesSkillsLanguages.setText(String.format("%d Skills, %d Languages", skillsCount, languagesCount));
}
private void updateDefensesSummary() {
if (mHolder.summaryDefenses == null) return;
List<String> defenses = new ArrayList<>();
if (mViewModel.getConditionImmunities().getValue() != null && !mViewModel.getConditionImmunities().getValue().isEmpty()) {
defenses.add(mViewModel.getConditionImmunities().getValue().size() + " Condition Immunities");
}
if (mViewModel.getDamageImmunities().getValue() != null && !mViewModel.getDamageImmunities().getValue().isEmpty()) {
defenses.add(mViewModel.getDamageImmunities().getValue().size() + " Damage Immunities");
}
if (mViewModel.getDamageResistances().getValue() != null && !mViewModel.getDamageResistances().getValue().isEmpty()) {
defenses.add(mViewModel.getDamageResistances().getValue().size() + " Resistances");
}
mHolder.summaryDefenses.setText(defenses.isEmpty() ? "None" : TextUtils.join(", ", defenses));
}
private void updateTraitsActionsSummary() {
if (mHolder.summaryTraitsActions == null) return;
int abilitiesCount = mViewModel.getAbilities().getValue() != null ? mViewModel.getAbilities().getValue().size() : 0;
int actionsCount = mViewModel.getActions().getValue() != null ? mViewModel.getActions().getValue().size() : 0;
int reactionsCount = mViewModel.getReactions().getValue() != null ? mViewModel.getReactions().getValue().size() : 0;
mHolder.summaryTraitsActions.setText(String.format("%d Abilities, %d Actions, %d Reactions", abilitiesCount, actionsCount, reactionsCount));
}
private void setupSubClickListeners() {
if (mHolder.basicInfoButton != null) {
mHolder.basicInfoButton.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditBasicInfoFragment();
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.challengeRating != null) {
mHolder.challengeRating.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditChallengeRatingFragment();
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.armorButton != null) {
mHolder.armorButton.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditArmorFragment();
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.speedButton != null) {
mHolder.speedButton.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSpeedFragment();
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.abilityScoresButton != null) {
mHolder.abilityScoresButton.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditAbilityScoresFragment();
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.savingThrows != null) {
mHolder.savingThrows.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSavingThrowsFragment();
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.skills != null) {
mHolder.skills.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSkillsFragment();
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.senses != null) {
mHolder.senses.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.SENSE);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.languages != null) {
mHolder.languages.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditLanguagesFragment();
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.conditionImmunities != null) {
mHolder.conditionImmunities.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.CONDITION_IMMUNITY);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.damageImmunities != null) {
mHolder.damageImmunities.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_IMMUNITY);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.damageResistances != null) {
mHolder.damageResistances.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_RESISTANCE);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.damageVulnerabilities != null) {
mHolder.damageVulnerabilities.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_VULNERABILITY);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.abilities != null) {
mHolder.abilities.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.ABILITY);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.actions != null) {
mHolder.actions.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.ACTION);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.reactions != null) {
mHolder.reactions.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.REACTIONS);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.legendaryActions != null) {
mHolder.legendaryActions.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.LEGENDARY_ACTION);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.lairActions != null) {
mHolder.lairActions.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.LAIR_ACTION);
NavHostFragment.findNavController(this).navigate(action);
});
}
if (mHolder.regionalActions != null) {
mHolder.regionalActions.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.REGIONAL_ACTION);
NavHostFragment.findNavController(this).navigate(action);
});
}
}
private static class ViewHolder {
final View headerBasicInfo;
final View bodyBasicInfo;
final ImageView chevronBasicInfo;
final TextView summaryBasicInfo;
final View headerCombatAbilities;
final View bodyCombatAbilities;
final ImageView chevronCombatAbilities;
final TextView summaryCombatAbilities;
final View headerSavesSkillsLanguages;
final View bodySavesSkillsLanguages;
final ImageView chevronSavesSkillsLanguages;
final TextView summarySavesSkillsLanguages;
final View headerDefenses;
final View bodyDefenses;
final ImageView chevronDefenses;
final TextView summaryDefenses;
final View headerTraitsActions;
final View bodyTraitsActions;
final ImageView chevronTraitsActions;
final TextView summaryTraitsActions;
final TextView basicInfoButton;
final TextView challengeRating;
final TextView armorButton;
final TextView speedButton;
final TextView abilityScoresButton;
final TextView savingThrows;
final TextView skills;
final TextView senses;
final TextView languages;
final TextView conditionImmunities;
final TextView damageImmunities;
final TextView damageResistances;
final TextView damageVulnerabilities;
final TextView abilities;
final TextView actions;
final TextView reactions;
final TextView legendaryActions;
final TextView lairActions;
final TextView regionalActions;
ViewHolder(@NonNull View root) {
headerBasicInfo = root.findViewById(R.id.headerBasicInfo);
bodyBasicInfo = root.findViewById(R.id.bodyBasicInfo);
chevronBasicInfo = root.findViewById(R.id.chevronBasicInfo);
summaryBasicInfo = root.findViewById(R.id.summaryBasicInfo);
headerCombatAbilities = root.findViewById(R.id.headerCombatAbilities);
bodyCombatAbilities = root.findViewById(R.id.bodyCombatAbilities);
chevronCombatAbilities = root.findViewById(R.id.chevronCombatAbilities);
summaryCombatAbilities = root.findViewById(R.id.summaryCombatAbilities);
headerSavesSkillsLanguages = root.findViewById(R.id.headerSavesSkillsLanguages);
bodySavesSkillsLanguages = root.findViewById(R.id.bodySavesSkillsLanguages);
chevronSavesSkillsLanguages = root.findViewById(R.id.chevronSavesSkillsLanguages);
summarySavesSkillsLanguages = root.findViewById(R.id.summarySavesSkillsLanguages);
headerDefenses = root.findViewById(R.id.headerDefenses);
bodyDefenses = root.findViewById(R.id.bodyDefenses);
chevronDefenses = root.findViewById(R.id.chevronDefenses);
summaryDefenses = root.findViewById(R.id.summaryDefenses);
headerTraitsActions = root.findViewById(R.id.headerTraitsActions);
bodyTraitsActions = root.findViewById(R.id.bodyTraitsActions);
chevronTraitsActions = root.findViewById(R.id.chevronTraitsActions);
summaryTraitsActions = root.findViewById(R.id.summaryTraitsActions);
basicInfoButton = root.findViewById(R.id.basicInfo);
challengeRating = root.findViewById(R.id.challengeRating);
armorButton = root.findViewById(R.id.armor);
speedButton = root.findViewById(R.id.speed);
abilityScoresButton = root.findViewById(R.id.abilityScores);
savingThrows = root.findViewById(R.id.savingThrows);
skills = root.findViewById(R.id.skills);
senses = root.findViewById(R.id.senses);
languages = root.findViewById(R.id.languages);
conditionImmunities = root.findViewById(R.id.conditionImmunities);
damageImmunities = root.findViewById(R.id.damageImmunities);
damageResistances = root.findViewById(R.id.damageResistances);
damageVulnerabilities = root.findViewById(R.id.damageVulnerabilities);
senses = root.findViewById(R.id.senses);
languages = root.findViewById(R.id.languages);
challengeRating = root.findViewById(R.id.challengeRating);
abilities = root.findViewById(R.id.abilities);
actions = root.findViewById(R.id.actions);
reactions = root.findViewById(R.id.reactions);

View File

@@ -702,6 +702,38 @@ public class EditMonsterViewModel extends ChangeTrackedViewModel {
return mDamageResistances;
}
public LiveData<List<String>> getDamageVulnerabilities() {
return mDamageVulnerabilities;
}
public LiveData<List<String>> getConditionImmunities() {
return mConditionImmunities;
}
public LiveData<List<Trait>> getAbilities() {
return mAbilities;
}
public LiveData<List<Trait>> getActions() {
return mActions;
}
public LiveData<List<Trait>> getReactions() {
return mReactions;
}
public LiveData<List<Trait>> getLairActions() {
return mLairActions;
}
public LiveData<List<Trait>> getLegendaryActions() {
return mLegendaryActions;
}
public LiveData<List<Trait>> getRegionalActions() {
return mRegionalActions;
}
public LiveData<List<Language>> getLanguages() {
return mLanguages;
}