Adds edit skill fragment to edit individual skills.

This commit is contained in:
2021-06-20 00:51:56 -07:00
parent 547b20292f
commit 3a3f78a31e
5 changed files with 279 additions and 4 deletions

View File

@@ -0,0 +1,96 @@
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.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.models.Skill;
import com.majinnaibu.monstercards.ui.components.AbilityScorePicker;
import com.majinnaibu.monstercards.ui.components.AdvantagePicker;
import com.majinnaibu.monstercards.ui.components.ProficiencyPicker;
import com.majinnaibu.monstercards.utils.Logger;
import com.majinnaibu.monstercards.utils.TextChangedListener;
public class EditSkillFragment extends Fragment {
private EditMonsterViewModel mEditMonsterViewModel;
private EditSkillViewModel mViewModel;
private ViewHolder mHolder;
private Skill mOldSkill;
@Override
public void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
mViewModel = new ViewModelProvider(this).get(EditSkillViewModel.class);
if (getArguments() != null) {
EditSkillFragmentArgs args = EditSkillFragmentArgs.fromBundle(getArguments());
mViewModel.copyFromSkill(args.getName(), args.getAbilityScore(), args.getProficiency(), args.getAdvantage());
mOldSkill = new Skill(args.getName(), args.getAbilityScore(), args.getAdvantage(), args.getProficiency());
} else {
Logger.logWTF("This should never happen. EditSkillFragment needs arguments.");
mOldSkill = null;
}
super.onCreate(savedInstanceState);
}
@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);
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_edit_skill, container, false);
mHolder = new ViewHolder(root);
mHolder.abilityScore.setValue(mViewModel.getAbilityScore().getValue());
mHolder.abilityScore.setOnValueChangedListener(value -> mViewModel.setAbilityScore(value));
mHolder.advantage.setValue(mViewModel.getAdvantage().getValue());
mHolder.advantage.setOnValueChangedListener(value -> mViewModel.setAdvantage(value));
mHolder.proficiency.setValue(mViewModel.getProficiency().getValue());
mHolder.proficiency.setOnValueChangedListener(value -> mViewModel.setProficiency(value));
mHolder.name.setText(mViewModel.getName().getValue());
mHolder.name.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setName(s.toString())));
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (mViewModel.hasChanges()) {
mEditMonsterViewModel.replaceSkill(mViewModel.getSkill().getValue(), mOldSkill);
}
Navigation.findNavController(requireView()).navigateUp();
}
});
return root;
}
private static class ViewHolder {
AbilityScorePicker abilityScore;
AdvantagePicker advantage;
ProficiencyPicker proficiency;
EditText name;
ViewHolder(View root) {
abilityScore = root.findViewById(R.id.abilityScore);
advantage = root.findViewById(R.id.advantage);
proficiency = root.findViewById(R.id.proficiency);
name = root.findViewById(R.id.name);
}
}
}

View File

@@ -0,0 +1,108 @@
package com.majinnaibu.monstercards.ui.editmonster;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.majinnaibu.monstercards.data.enums.AbilityScore;
import com.majinnaibu.monstercards.data.enums.AdvantageType;
import com.majinnaibu.monstercards.data.enums.ProficiencyType;
import com.majinnaibu.monstercards.models.Skill;
import com.majinnaibu.monstercards.utils.ChangeTrackedLiveData;
public class EditSkillViewModel extends ViewModel {
private final ChangeTrackedLiveData<AbilityScore> mAbilityScore;
private final ChangeTrackedLiveData<AdvantageType> mAdvantageType;
private final MutableLiveData<Boolean> mHasChanges;
private final ChangeTrackedLiveData<ProficiencyType> mProficiencyType;
private final ChangeTrackedLiveData<String> mName;
private final ChangeTrackedLiveData<Skill> mSkill;
public EditSkillViewModel() {
mHasChanges = new MutableLiveData<>(false);
ChangeTrackedLiveData.OnValueDirtiedCallback onDirtied = () -> mHasChanges.setValue(true);
mAbilityScore = new ChangeTrackedLiveData<>(AbilityScore.STRENGTH, onDirtied);
mAdvantageType = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied);
mProficiencyType = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied);
mName = new ChangeTrackedLiveData<>("Unknown Skill", onDirtied);
mSkill = new ChangeTrackedLiveData<>(makeSkill(), onDirtied);
}
public EditSkillViewModel(Skill skill) {
mHasChanges = new MutableLiveData<>(false);
ChangeTrackedLiveData.OnValueDirtiedCallback onDirtied = () -> mHasChanges.setValue(true);
mAbilityScore = new ChangeTrackedLiveData<>(skill.abilityScore, onDirtied);
mAdvantageType = new ChangeTrackedLiveData<>(skill.advantageType, onDirtied);
mProficiencyType = new ChangeTrackedLiveData<>(skill.proficiencyType, onDirtied);
mName = new ChangeTrackedLiveData<>(skill.name, onDirtied);
mSkill = new ChangeTrackedLiveData<>(makeSkill(), onDirtied);
}
public void copyFromSkill(Skill skill) {
mAbilityScore.resetValue(skill.abilityScore);
mAdvantageType.resetValue(skill.advantageType);
mProficiencyType.resetValue(skill.proficiencyType);
mName.resetValue(skill.name);
}
public void copyFromSkill(String name, AbilityScore abilityScore, ProficiencyType proficiency, AdvantageType advantage) {
mAbilityScore.resetValue(abilityScore);
mAdvantageType.resetValue(advantage);
mProficiencyType.resetValue(proficiency);
mName.resetValue(name);
}
public LiveData<Skill> getSkill() {
return mSkill;
}
public LiveData<AbilityScore> getAbilityScore() {
return mAbilityScore;
}
public void setAbilityScore(AbilityScore value) {
mAbilityScore.setValue(value);
mSkill.setValue(makeSkill());
}
public LiveData<AdvantageType> getAdvantage() {
return mAdvantageType;
}
public void setAdvantage(AdvantageType value) {
mAdvantageType.setValue(value);
mSkill.setValue(makeSkill());
}
public LiveData<ProficiencyType> getProficiency() {
return mProficiencyType;
}
public void setProficiency(ProficiencyType value) {
mProficiencyType.setValue(value);
mSkill.setValue(makeSkill());
}
public LiveData<String> getName() {
return mName;
}
public void setName(String value) {
mName.setValue(value);
mSkill.setValue(makeSkill());
}
public LiveData<Boolean> getHasChanges() {
return mHasChanges;
}
public boolean hasChanges() {
return mHasChanges.getValue();
}
private Skill makeSkill() {
return new Skill(mName.getValue(), mAbilityScore.getValue(), mAdvantageType.getValue(), mProficiencyType.getValue());
}
}

View File

@@ -11,6 +11,7 @@ import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavBackStackEntry;
import androidx.navigation.NavController;
import androidx.navigation.NavDirections;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.ItemTouchHelper;
@@ -32,7 +33,10 @@ public class EditSkillsFragment extends Fragment {
private ViewHolder mHolder;
private void navigateToEditSkill(Skill skill) {
Logger.logUnimplementedFeature("Navigate to the edit skill fragment.");
NavDirections action = EditSkillsFragmentDirections.actionEditSkillsFragmentToEditSkillFragment(skill.name, skill.abilityScore, skill.proficiencyType, skill.advantageType);
View view = getView();
assert view != null;
Navigation.findNavController(view).navigate(action);
}
@Override

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.editmonster.EditSkillFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/label_name"
android:importantForAutofill="no"
android:inputType="textCapWords"
tools:text="Medicine" />
</com.google.android.material.textfield.TextInputLayout>
<com.majinnaibu.monstercards.ui.components.AbilityScorePicker
android:id="@+id/abilityScore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin" />
<com.majinnaibu.monstercards.ui.components.ProficiencyPicker
android:id="@+id/proficiency"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin" />
<com.majinnaibu.monstercards.ui.components.AdvantagePicker
android:id="@+id/advantage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin" />
</LinearLayout>
</ScrollView>

View File

@@ -127,7 +127,28 @@
android:id="@+id/editSkillsFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditSkillsFragment"
android:label="fragment_edit_skills_list"
tools:layout="@layout/fragment_edit_skills_list" />
tools:layout="@layout/fragment_edit_skills_list">
<action
android:id="@+id/action_editSkillsFragment_to_editSkillFragment"
app:destination="@id/editSkillFragment" />
</fragment>
<fragment
android:id="@+id/editSkillFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditSkillFragment"
android:label="fragment_edit_skill"
tools:layout="@layout/fragment_edit_skill">
<argument
android:name="name"
app:argType="string" />
<argument
android:name="abilityScore"
app:argType="com.majinnaibu.monstercards.data.enums.AbilityScore" />
<argument
android:name="proficiency"
app:argType="com.majinnaibu.monstercards.data.enums.ProficiencyType" />
<argument
android:name="advantage"
app:argType="com.majinnaibu.monstercards.data.enums.AdvantageType" />
</fragment>
</navigation>
</navigation>
</navigation>