Adds Edit Armor screen to edit a monster's armor stats.

This commit is contained in:
2021-05-29 19:46:28 -07:00
parent 82ce3d3788
commit f4dd3855d6
9 changed files with 396 additions and 91 deletions

View File

@@ -0,0 +1,15 @@
package com.majinnaibu.monstercards.helpers;
import java.util.Objects;
public final class ArrayHelper {
public static int indexOf(Object[] array, Object target) {
for (int index = 0; index < array.length; index++) {
if (Objects.equals(array[index], target)) {
return index;
}
}
return -1;
}
}

View File

@@ -0,0 +1,107 @@
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.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.Fragment;
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.data.enums.ArmorType;
import com.majinnaibu.monstercards.helpers.ArrayHelper;
import com.majinnaibu.monstercards.utils.TextChangedListener;
@SuppressWarnings("FieldCanBeLocal")
public class EditArmorFragment extends Fragment {
private EditMonsterViewModel mViewModel;
private ViewHolder mHolder;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
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);
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_edit_armor, container, false);
mHolder = new ViewHolder(root);
mHolder.armorType.setAdapter(new ArrayAdapter<ArmorType>(requireContext(), R.layout.dropdown_list_item, ArmorType.values()) {
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ArmorType item = getItem(position);
TextView view = (TextView) super.getView(position, convertView, parent);
view.setText(item.displayName);
return view;
}
@Override
public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ArmorType item = getItem(position);
TextView view = (TextView) super.getDropDownView(position, convertView, parent);
view.setText(item.displayName);
return view;
}
});
mHolder.armorType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
ArmorType selectedItem = (ArmorType) parent.getItemAtPosition(position);
mViewModel.setArmorType(selectedItem);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
mViewModel.setArmorType(ArmorType.NONE);
}
});
mHolder.armorType.setSelection(ArrayHelper.indexOf(ArmorType.values(), mViewModel.getArmorType().getValue()));
mHolder.naturalArmorBonus.setText(mViewModel.getNaturalArmorBonusValueAsString());
mHolder.naturalArmorBonus.addTextChangedListener((new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setNaturalArmorBonus(s.toString()))));
mHolder.hasShield.setChecked(mViewModel.getHasShieldValueAsBoolean());
mHolder.hasShield.setOnCheckedChangeListener((buttonView, isChecked) -> mViewModel.setHasShield(isChecked));
mHolder.shieldBonus.setText(mViewModel.getShieldBonusValueAsString());
mHolder.shieldBonus.addTextChangedListener((new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setShieldBonus(s.toString()))));
mHolder.customArmor.setText(mViewModel.getCustomArmor().getValue());
mHolder.customArmor.addTextChangedListener((new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setCustomArmor(s.toString()))));
return root;
}
private static class ViewHolder {
private final Spinner armorType;
private final EditText naturalArmorBonus;
private final SwitchCompat hasShield;
private final EditText shieldBonus;
private final EditText customArmor;
ViewHolder(View root) {
armorType = root.findViewById(R.id.armorType);
naturalArmorBonus = root.findViewById(R.id.naturalArmorBonus);
hasShield = root.findViewById(R.id.hasShield);
shieldBonus = root.findViewById(R.id.shieldBonus);
customArmor = root.findViewById(R.id.customArmor);
}
}
}

View File

@@ -6,7 +6,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavBackStackEntry;
import androidx.navigation.NavController;
@@ -15,12 +14,8 @@ import androidx.navigation.Navigation;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.majinnaibu.monstercards.R;
import com.majinnaibu.monstercards.ui.MCFragment;
import com.majinnaibu.monstercards.utils.Logger;
import com.majinnaibu.monstercards.utils.TextChangedListener;
/**
* A simple {@link Fragment} subclass.
*/
@SuppressWarnings("FieldCanBeLocal")
public class EditBasicInfoFragment extends MCFragment {
private EditMonsterViewModel mViewModel;
@@ -38,52 +33,28 @@ public class EditBasicInfoFragment extends MCFragment {
mHolder = new ViewHolder(root);
mHolder.name.setText(mViewModel.getName().getValue());
mHolder.name.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> {
mViewModel.setName(s.toString());
Logger.logDebug(String.format("Monster Name changed to %s", mViewModel.getName().getValue()));
}));
mHolder.name.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setName(s.toString())));
mHolder.size.setText(mViewModel.getSize().getValue());
mHolder.size.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> {
mViewModel.setSize(s.toString());
Logger.logDebug(String.format("Monster Size changed to %s", mViewModel.getSize().getValue()));
}));
mHolder.size.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setSize(s.toString())));
mHolder.type.setText(mViewModel.getType().getValue());
mHolder.type.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> {
mViewModel.setType(s.toString());
Logger.logDebug(String.format("Monster Type changed to %s", mViewModel.getType().getValue()));
}));
mHolder.type.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setType(s.toString())));
mHolder.subtype.setText(mViewModel.getSubtype().getValue());
mHolder.subtype.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> {
mViewModel.setSubtype(s.toString());
Logger.logDebug(String.format("Monster Subtype changed to %s", mViewModel.getSubtype().getValue()));
}));
mHolder.subtype.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setSubtype(s.toString())));
mHolder.alignment.setText(mViewModel.getAlignment().getValue());
mHolder.alignment.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> {
mViewModel.setAlignment(s.toString());
Logger.logDebug(String.format("Monster Alignment changed to %s", mViewModel.getAlignment().getValue()));
}));
mHolder.alignment.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setAlignment(s.toString())));
mHolder.customHitPoints.setText(mViewModel.getCustomHitPoints().getValue());
mHolder.customHitPoints.addTextChangedListener((new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> {
mViewModel.setCustomHitPoints(s.toString());
Logger.logDebug(String.format("Monster Custom Hit Points changed to %s", mViewModel.getCustomHitPoints().getValue()));
})));
mHolder.customHitPoints.addTextChangedListener((new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setCustomHitPoints(s.toString()))));
mHolder.hitDice.setText(mViewModel.getHitDiceValueAsString());
mHolder.hitDice.addTextChangedListener((new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> {
mViewModel.setHitDice(s.toString());
Logger.logDebug(String.format("Monster Hit Dice changed to %s", mViewModel.getHitDiceValueAsString()));
})));
mHolder.hitDice.addTextChangedListener((new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setHitDice(s.toString()))));
mHolder.hasCustomHitPoints.setChecked(mViewModel.getHasCustomHitPointsValueAsBoolean());
mHolder.hasCustomHitPoints.setOnCheckedChangeListener((button, isChecked) -> {
mViewModel.setHasCustomHitPoints(isChecked);
Logger.logDebug(String.format("Monster Has Custom Hit Points changed to %s", isChecked ? "TRUE" : "FALSE"));
});
mHolder.hasCustomHitPoints.setOnCheckedChangeListener((button, isChecked) -> mViewModel.setHasCustomHitPoints(isChecked));
return root;
}

View File

@@ -86,6 +86,12 @@ public class EditMonsterFragment extends MCFragment {
assert view != null;
Navigation.findNavController(view).navigate(action);
});
mHolder.armorButton.setOnClickListener(v -> {
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditArmorFragment();
View view = getView();
assert view != null;
Navigation.findNavController(view).navigate(action);
});
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
@Override
@@ -137,9 +143,11 @@ public class EditMonsterFragment extends MCFragment {
private static class ViewHolder {
TextView basicInfoButton;
TextView armorButton;
ViewHolder(View root) {
basicInfoButton = root.findViewById(R.id.basicInfo);
armorButton = root.findViewById(R.id.armor);
}
}
}

View File

@@ -5,26 +5,34 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.majinnaibu.monstercards.data.enums.ArmorType;
import com.majinnaibu.monstercards.helpers.StringHelper;
import com.majinnaibu.monstercards.models.Monster;
import com.majinnaibu.monstercards.utils.Logger;
import java.util.Objects;
import java.util.UUID;
@SuppressWarnings({"ConstantConditions", "unused"})
public class EditMonsterViewModel extends ViewModel {
private final MutableLiveData<String> mName;
private final MutableLiveData<UUID> mMonsterId;
private final MutableLiveData<String> mErrorMessage;
private final MutableLiveData<Boolean> mHasError;
private final MutableLiveData<Boolean> mHasLoaded;
private final MutableLiveData<Boolean> mHasChanges;
private final MutableLiveData<Boolean> mHasCustomHitPoints;
private final MutableLiveData<Boolean> mHasShield;
private final MutableLiveData<ArmorType> mArmorType;
private final MutableLiveData<Integer> mHitDice;
private final MutableLiveData<Integer> mNaturalArmorBonus;
private final MutableLiveData<Integer> mShieldBonus;
private final MutableLiveData<String> mName;
private final MutableLiveData<String> mErrorMessage;
private final MutableLiveData<String> mSize;
private final MutableLiveData<String> mType;
private final MutableLiveData<String> mSubtype;
private final MutableLiveData<String> mAlignment;
private final MutableLiveData<String> mCustomHitPoints;
private final MutableLiveData<Boolean> mHasChanges;
private final MutableLiveData<Integer> mHitDice;
private final MutableLiveData<Boolean> mHasCustomHitPoints;
private final MutableLiveData<String> mCustomArmor;
public EditMonsterViewModel() {
@@ -39,7 +47,12 @@ public class EditMonsterViewModel extends ViewModel {
mAlignment = new MutableLiveData<>("");
mCustomHitPoints = new MutableLiveData<>("");
mHitDice = new MutableLiveData<>(0);
mNaturalArmorBonus = new MutableLiveData<>(0);
mHasCustomHitPoints = new MutableLiveData<>(false);
mArmorType = new MutableLiveData<>(ArmorType.NONE);
mHasShield = new MutableLiveData<>(false);
mShieldBonus = new MutableLiveData<>(0);
mCustomArmor = new MutableLiveData<>("");
// TODO: consider initializing this to true so all new monsters need saving
mHasChanges = new MutableLiveData<>(false);
}
@@ -54,7 +67,12 @@ public class EditMonsterViewModel extends ViewModel {
mAlignment.setValue(monster.alignment);
mCustomHitPoints.setValue(monster.customHPDescription);
mHitDice.setValue(monster.hitDice);
mNaturalArmorBonus.setValue(monster.naturalArmorBonus);
mHasCustomHitPoints.setValue(monster.hasCustomHP);
mArmorType.setValue(monster.armorType);
mHasShield.setValue(monster.shieldBonus != 0);
mShieldBonus.setValue(monster.shieldBonus);
mCustomArmor.setValue(monster.otherArmorDescription);
mHasChanges.setValue(false);
}
@@ -63,8 +81,10 @@ public class EditMonsterViewModel extends ViewModel {
}
public void setName(@NonNull String name) {
mName.setValue(name);
mHasChanges.setValue(true);
if (!Objects.equals(mName.getValue(), name)) {
mName.setValue(name);
mHasChanges.setValue(true);
}
}
public LiveData<UUID> getMonsterId() {
@@ -108,8 +128,10 @@ public class EditMonsterViewModel extends ViewModel {
}
public void setSize(@NonNull String size) {
mSize.setValue(size);
mHasChanges.setValue(true);
if (!Objects.equals(mSize.getValue(), size)) {
mSize.setValue(size);
mHasChanges.setValue(true);
}
}
public LiveData<String> getType() {
@@ -117,17 +139,21 @@ public class EditMonsterViewModel extends ViewModel {
}
public void setType(@NonNull String type) {
mType.setValue(type);
mHasChanges.setValue(true);
if (!Objects.equals(mType.getValue(), type)) {
mType.setValue(type);
mHasChanges.setValue(true);
}
}
public LiveData<String> getSubtype() {
return mSubtype;
}
public void setSubtype(@NonNull String subType) {
mSubtype.setValue(subType);
mHasChanges.setValue(true);
public void setSubtype(@NonNull String subtype) {
if (!Objects.equals(mSubtype.getValue(), subtype)) {
mSubtype.setValue(subtype);
mHasChanges.setValue(true);
}
}
public LiveData<String> getAlignment() {
@@ -135,8 +161,10 @@ public class EditMonsterViewModel extends ViewModel {
}
public void setAlignment(@NonNull String alignment) {
mAlignment.setValue(alignment);
mHasChanges.setValue(true);
if (!Objects.equals(mAlignment.getValue(), alignment)) {
mAlignment.setValue(alignment);
mHasChanges.setValue(true);
}
}
public LiveData<String> getCustomHitPoints() {
@@ -144,8 +172,10 @@ public class EditMonsterViewModel extends ViewModel {
}
public void setCustomHitPoints(String customHitPoints) {
mCustomHitPoints.setValue(customHitPoints);
mHasChanges.setValue(true);
if (!Objects.equals(mCustomHitPoints.getValue(), customHitPoints)) {
mCustomHitPoints.setValue(customHitPoints);
mHasChanges.setValue(true);
}
}
public LiveData<Boolean> getHasChanges() {
@@ -165,8 +195,10 @@ public class EditMonsterViewModel extends ViewModel {
}
public void setHitDice(int hitDice) {
mHitDice.setValue(hitDice);
mHasChanges.setValue(true);
if (!Objects.equals(mHitDice.getValue(), hitDice)) {
mHitDice.setValue(hitDice);
mHasChanges.setValue(true);
}
}
public void setHitDice(String hitDice) {
@@ -178,19 +210,93 @@ public class EditMonsterViewModel extends ViewModel {
return mHitDice.getValue().toString();
}
public LiveData<Integer> getNaturalArmorBonus() {
return mNaturalArmorBonus;
}
public void setNaturalArmorBonus(int naturalArmorBonus) {
if (!Objects.equals(mNaturalArmorBonus.getValue(), naturalArmorBonus)) {
mNaturalArmorBonus.setValue(naturalArmorBonus);
mHasChanges.setValue(true);
}
}
public void setNaturalArmorBonus(String naturalArmorBonus) {
Integer parsedValue = StringHelper.parseInt(naturalArmorBonus);
this.setNaturalArmorBonus(parsedValue != null ? parsedValue : 0);
}
public String getNaturalArmorBonusValueAsString() {
return mNaturalArmorBonus.getValue().toString();
}
public LiveData<Boolean> getHasCustomHitPoints() {
return mHasCustomHitPoints;
}
public void setHasCustomHitPoints(boolean hasCustomHitPoints) {
mHasCustomHitPoints.setValue(hasCustomHitPoints);
mHasChanges.setValue(true);
if (!Objects.equals(mHasCustomHitPoints.getValue(), hasCustomHitPoints)) {
mHasCustomHitPoints.setValue(hasCustomHitPoints);
mHasChanges.setValue(true);
}
}
public boolean getHasCustomHitPointsValueAsBoolean() {
return mHasCustomHitPoints.getValue();
}
public LiveData<ArmorType> getArmorType() {
return mArmorType;
}
public void setArmorType(ArmorType armorType) {
Logger.logDebug(String.format("Setting ArmorType to %s", armorType.displayName));
if (!Objects.equals(mArmorType.getValue(), armorType)) {
mArmorType.setValue(armorType);
mHasChanges.setValue(true);
}
}
public LiveData<Boolean> getHasShield() {
return mHasShield;
}
public void setHasShield(boolean hasShield) {
mHasShield.setValue(hasShield);
mHasChanges.setValue(true);
}
public boolean getHasShieldValueAsBoolean() {
return mHasShield.getValue();
}
public LiveData<Integer> getShieldBonus() {
return mShieldBonus;
}
public void setShieldBonus(int shieldBonus) {
mShieldBonus.setValue(shieldBonus);
mHasChanges.setValue(true);
}
public void setShieldBonus(String shieldBonus) {
Integer parsedValue = StringHelper.parseInt(shieldBonus);
this.setShieldBonus(parsedValue != null ? parsedValue : 0);
}
public LiveData<String> getCustomArmor() {
return mCustomArmor;
}
public void setCustomArmor(String customArmor) {
mCustomArmor.setValue(customArmor);
mHasChanges.setValue(true);
}
public String getShieldBonusValueAsString() {
return mShieldBonus.getValue().toString();
}
public Monster buildMonster() {
Monster monster = new Monster();
@@ -203,6 +309,10 @@ public class EditMonsterViewModel extends ViewModel {
monster.customHPDescription = mCustomHitPoints.getValue();
monster.hitDice = mHitDice.getValue();
monster.hasCustomHP = mHasCustomHitPoints.getValue();
monster.armorType = mArmorType.getValue();
monster.naturalArmorBonus = mNaturalArmorBonus.getValue();
monster.shieldBonus = mShieldBonus.getValue();
monster.otherArmorDescription = mCustomArmor.getValue();
return monster;
}