Adds edit skill fragment to edit individual skills.
This commit is contained in:
@@ -9,6 +9,7 @@ import android.widget.EditText;
|
|||||||
import androidx.activity.OnBackPressedCallback;
|
import androidx.activity.OnBackPressedCallback;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.NavBackStackEntry;
|
import androidx.navigation.NavBackStackEntry;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
@@ -19,25 +20,24 @@ import com.majinnaibu.monstercards.models.Skill;
|
|||||||
import com.majinnaibu.monstercards.ui.components.AbilityScorePicker;
|
import com.majinnaibu.monstercards.ui.components.AbilityScorePicker;
|
||||||
import com.majinnaibu.monstercards.ui.components.AdvantagePicker;
|
import com.majinnaibu.monstercards.ui.components.AdvantagePicker;
|
||||||
import com.majinnaibu.monstercards.ui.components.ProficiencyPicker;
|
import com.majinnaibu.monstercards.ui.components.ProficiencyPicker;
|
||||||
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
||||||
|
|
||||||
public class EditSkillFragment extends MCFragment {
|
public class EditSkillFragment extends Fragment {
|
||||||
private EditMonsterViewModel mEditMonsterViewModel;
|
private EditMonsterViewModel mEditMonsterViewModel;
|
||||||
private EditSkillViewModel mViewModel;
|
private EditSkillViewModel mViewModel;
|
||||||
private ViewHolder mHolder;
|
private ViewHolder mHolder;
|
||||||
private Skill mOldSkill;
|
private Skill mOldSkill;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
|
||||||
mViewModel = new ViewModelProvider(this).get(EditSkillViewModel.class);
|
mViewModel = new ViewModelProvider(this).get(EditSkillViewModel.class);
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
EditSkillFragmentArgs args = EditSkillFragmentArgs.fromBundle(getArguments());
|
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());
|
mOldSkill = new Skill(args.getName(), args.getAbilityScore(), args.getAdvantage(), args.getProficiency());
|
||||||
mViewModel.copyFromSkill(mOldSkill);
|
|
||||||
} else {
|
} else {
|
||||||
Logger.logWTF("EditSkillFragment needs arguments.");
|
Logger.logWTF("This should never happen. EditSkillFragment needs arguments.");
|
||||||
mOldSkill = null;
|
mOldSkill = null;
|
||||||
}
|
}
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -49,7 +49,10 @@ public class EditSkillFragment extends MCFragment {
|
|||||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
||||||
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
||||||
mEditMonsterViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
mEditMonsterViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
||||||
|
|
||||||
|
// Inflate the layout for this fragment
|
||||||
View root = inflater.inflate(R.layout.fragment_edit_skill, container, false);
|
View root = inflater.inflate(R.layout.fragment_edit_skill, container, false);
|
||||||
|
|
||||||
mHolder = new ViewHolder(root);
|
mHolder = new ViewHolder(root);
|
||||||
|
|
||||||
mHolder.abilityScore.setValue(mViewModel.getAbilityScore().getValue());
|
mHolder.abilityScore.setValue(mViewModel.getAbilityScore().getValue());
|
||||||
@@ -77,19 +80,13 @@ public class EditSkillFragment extends MCFragment {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
mHolder.name.requestFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ViewHolder {
|
private static class ViewHolder {
|
||||||
AbilityScorePicker abilityScore;
|
AbilityScorePicker abilityScore;
|
||||||
AdvantagePicker advantage;
|
AdvantagePicker advantage;
|
||||||
ProficiencyPicker proficiency;
|
ProficiencyPicker proficiency;
|
||||||
EditText name;
|
EditText name;
|
||||||
|
|
||||||
ViewHolder(@NonNull View root) {
|
ViewHolder(View root) {
|
||||||
abilityScore = root.findViewById(R.id.abilityScore);
|
abilityScore = root.findViewById(R.id.abilityScore);
|
||||||
advantage = root.findViewById(R.id.advantage);
|
advantage = root.findViewById(R.id.advantage);
|
||||||
proficiency = root.findViewById(R.id.proficiency);
|
proficiency = root.findViewById(R.id.proficiency);
|
||||||
|
|||||||
@@ -1,37 +1,57 @@
|
|||||||
package com.majinnaibu.monstercards.ui.editmonster;
|
package com.majinnaibu.monstercards.ui.editmonster;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.lifecycle.LiveData;
|
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.AbilityScore;
|
||||||
import com.majinnaibu.monstercards.data.enums.AdvantageType;
|
import com.majinnaibu.monstercards.data.enums.AdvantageType;
|
||||||
import com.majinnaibu.monstercards.data.enums.ProficiencyType;
|
import com.majinnaibu.monstercards.data.enums.ProficiencyType;
|
||||||
import com.majinnaibu.monstercards.models.Skill;
|
import com.majinnaibu.monstercards.models.Skill;
|
||||||
import com.majinnaibu.monstercards.ui.shared.ChangeTrackedViewModel;
|
|
||||||
import com.majinnaibu.monstercards.utils.ChangeTrackedLiveData;
|
import com.majinnaibu.monstercards.utils.ChangeTrackedLiveData;
|
||||||
|
|
||||||
public class EditSkillViewModel extends ChangeTrackedViewModel {
|
public class EditSkillViewModel extends ViewModel {
|
||||||
private final ChangeTrackedLiveData<AbilityScore> mAbilityScore;
|
private final ChangeTrackedLiveData<AbilityScore> mAbilityScore;
|
||||||
private final ChangeTrackedLiveData<AdvantageType> mAdvantageType;
|
private final ChangeTrackedLiveData<AdvantageType> mAdvantageType;
|
||||||
|
private final MutableLiveData<Boolean> mHasChanges;
|
||||||
private final ChangeTrackedLiveData<ProficiencyType> mProficiencyType;
|
private final ChangeTrackedLiveData<ProficiencyType> mProficiencyType;
|
||||||
private final ChangeTrackedLiveData<String> mName;
|
private final ChangeTrackedLiveData<String> mName;
|
||||||
private final ChangeTrackedLiveData<Skill> mSkill;
|
private final ChangeTrackedLiveData<Skill> mSkill;
|
||||||
|
|
||||||
public EditSkillViewModel() {
|
public EditSkillViewModel() {
|
||||||
super();
|
mHasChanges = new MutableLiveData<>(false);
|
||||||
mAbilityScore = new ChangeTrackedLiveData<>(AbilityScore.STRENGTH, this::makeDirty);
|
ChangeTrackedLiveData.OnValueDirtiedCallback onDirtied = () -> mHasChanges.setValue(true);
|
||||||
mAdvantageType = new ChangeTrackedLiveData<>(AdvantageType.NONE, this::makeDirty);
|
|
||||||
mProficiencyType = new ChangeTrackedLiveData<>(ProficiencyType.NONE, this::makeDirty);
|
mAbilityScore = new ChangeTrackedLiveData<>(AbilityScore.STRENGTH, onDirtied);
|
||||||
mName = new ChangeTrackedLiveData<>("New Skill", this::makeDirty);
|
mAdvantageType = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied);
|
||||||
mSkill = new ChangeTrackedLiveData<>(makeSkill(), this::makeDirty);
|
mProficiencyType = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied);
|
||||||
|
mName = new ChangeTrackedLiveData<>("Unknown Skill", onDirtied);
|
||||||
|
mSkill = new ChangeTrackedLiveData<>(makeSkill(), onDirtied);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFromSkill(@NonNull Skill skill) {
|
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);
|
mAbilityScore.resetValue(skill.abilityScore);
|
||||||
mAdvantageType.resetValue(skill.advantageType);
|
mAdvantageType.resetValue(skill.advantageType);
|
||||||
mProficiencyType.resetValue(skill.proficiencyType);
|
mProficiencyType.resetValue(skill.proficiencyType);
|
||||||
mName.resetValue(skill.name);
|
mName.resetValue(skill.name);
|
||||||
makeClean();
|
}
|
||||||
|
|
||||||
|
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() {
|
public LiveData<Skill> getSkill() {
|
||||||
@@ -74,7 +94,14 @@ public class EditSkillViewModel extends ChangeTrackedViewModel {
|
|||||||
mSkill.setValue(makeSkill());
|
mSkill.setValue(makeSkill());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
public LiveData<Boolean> getHasChanges() {
|
||||||
|
return mHasChanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasChanges() {
|
||||||
|
return mHasChanges.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
private Skill makeSkill() {
|
private Skill makeSkill() {
|
||||||
return new Skill(mName.getValue(), mAbilityScore.getValue(), mAdvantageType.getValue(), mProficiencyType.getValue());
|
return new Skill(mName.getValue(), mAbilityScore.getValue(), mAdvantageType.getValue(), mProficiencyType.getValue());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ package com.majinnaibu.monstercards.ui.editmonster;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
@@ -14,57 +11,87 @@ import androidx.fragment.app.Fragment;
|
|||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.NavBackStackEntry;
|
import androidx.navigation.NavBackStackEntry;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.NavDirections;
|
||||||
import androidx.navigation.Navigation;
|
import androidx.navigation.Navigation;
|
||||||
|
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
|
import com.majinnaibu.monstercards.models.Skill;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback;
|
||||||
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fragment representing a list of Items.
|
* A fragment representing a list of Items.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("FieldCanBeLocal")
|
||||||
public class EditSkillsFragment extends Fragment {
|
public class EditSkillsFragment extends Fragment {
|
||||||
private EditMonsterViewModel mViewModel;
|
private EditMonsterViewModel mViewModel;
|
||||||
// private ViewHolder mHolder;
|
private ViewHolder mHolder;
|
||||||
|
|
||||||
|
private void navigateToEditSkill(Skill skill) {
|
||||||
|
NavDirections action = EditSkillsFragmentDirections.actionEditSkillsFragmentToEditSkillFragment(skill.name, skill.abilityScore, skill.proficiencyType, skill.advantageType);
|
||||||
|
View view = getView();
|
||||||
|
assert view != null;
|
||||||
|
Navigation.findNavController(view).navigate(action);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_edit_skills_list, container, false);
|
|
||||||
|
|
||||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
||||||
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
||||||
mViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
mViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
||||||
setHasOptionsMenu(true);
|
|
||||||
|
|
||||||
// Set the adapter
|
View root = inflater.inflate(R.layout.fragment_edit_skills_list, container, false);
|
||||||
if (view instanceof RecyclerView) {
|
|
||||||
Context context = view.getContext();
|
|
||||||
RecyclerView recyclerView = (RecyclerView) view;
|
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(context));
|
|
||||||
mViewModel.getSkills().observe(getViewLifecycleOwner(), skills -> recyclerView.setAdapter(new EditSkillsRecyclerViewAdapter(mViewModel.getSkillsArray())));
|
|
||||||
}
|
|
||||||
|
|
||||||
return view;
|
mHolder = new ViewHolder(root);
|
||||||
|
setupRecyclerView(mHolder.list);
|
||||||
|
setupAddSkillButton(mHolder.addSkill);
|
||||||
|
|
||||||
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||||
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
Context context = requireContext();
|
||||||
inflater.inflate(R.menu.edit_skills_menu, menu);
|
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
|
|
||||||
|
mViewModel.getSkills().observe(getViewLifecycleOwner(), skills -> {
|
||||||
|
EditSkillsRecyclerViewAdapter adapter = new EditSkillsRecyclerViewAdapter(mViewModel.getSkillsArray(), skill -> {
|
||||||
|
if (skill != null) {
|
||||||
|
navigateToEditSkill(skill);
|
||||||
|
} else {
|
||||||
|
Logger.logError("Can't navigate to EditSkill with a null skill");
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
});
|
||||||
|
|
||||||
|
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, layoutManager.getOrientation());
|
||||||
|
recyclerView.addItemDecoration(dividerItemDecoration);
|
||||||
|
|
||||||
|
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(context, mViewModel::removeSkill));
|
||||||
|
itemTouchHelper.attachToRecyclerView(recyclerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void setupAddSkillButton(@NonNull FloatingActionButton fab) {
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
fab.setOnClickListener(view -> {
|
||||||
if (item.getItemId() == R.id.menu_action_add_skill) {
|
Skill newSkill = mViewModel.addNewSkill();
|
||||||
mViewModel.addNewSkill();
|
navigateToEditSkill(newSkill);
|
||||||
// TODO: navigate to editing the new skill
|
});
|
||||||
// NavDirections action = MonsterDetailFragmentDirections.actionNavigationMonsterToEditMonsterFragment(monsterDetailViewModel.getId().getValue().toString());
|
}
|
||||||
// View view = getView();
|
|
||||||
// assert view != null;
|
private static class ViewHolder {
|
||||||
// Navigation.findNavController(view).navigate(action);
|
RecyclerView list;
|
||||||
return true;
|
FloatingActionButton addSkill;
|
||||||
|
|
||||||
|
ViewHolder(View root) {
|
||||||
|
this.list = root.findViewById(R.id.list);
|
||||||
|
this.addSkill = root.findViewById(R.id.add_skill);
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,28 @@
|
|||||||
android:id="@+id/editSkillsFragment"
|
android:id="@+id/editSkillsFragment"
|
||||||
android:name="com.majinnaibu.monstercards.ui.editmonster.EditSkillsFragment"
|
android:name="com.majinnaibu.monstercards.ui.editmonster.EditSkillsFragment"
|
||||||
android:label="fragment_edit_skills_list"
|
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>
|
||||||
</navigation>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user