diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/library/LibraryFragment.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/library/LibraryFragment.java index 6626d1e..18cf407 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/library/LibraryFragment.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/library/LibraryFragment.java @@ -35,8 +35,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.schedulers.Schedulers; public class LibraryFragment extends MCFragment { - // TODO: TOM: rename MonsterFragment MonsterDetailFragment - + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_library, container, false); diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterDetailFragment.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterDetailFragment.java index f910dfa..5f32746 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterDetailFragment.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterDetailFragment.java @@ -8,37 +8,29 @@ import android.text.Spanned; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.lifecycle.ViewModelProvider; -import androidx.navigation.NavDirections; -import androidx.navigation.Navigation; import com.majinnaibu.monstercards.R; import com.majinnaibu.monstercards.data.MonsterRepository; import com.majinnaibu.monstercards.helpers.CommonMarkHelper; import com.majinnaibu.monstercards.helpers.StringHelper; import com.majinnaibu.monstercards.models.Monster; -import com.majinnaibu.monstercards.ui.shared.MCFragment; +import com.majinnaibu.monstercards.ui.MCFragment; import com.majinnaibu.monstercards.utils.Logger; -import java.util.List; import java.util.UUID; import io.reactivex.rxjava3.observers.DisposableSingleObserver; public class MonsterDetailFragment extends MCFragment { - private ViewHolder mHolder; - private MonsterDetailViewModel mViewModel; + private MonsterDetailViewModel monsterDetailViewModel; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -46,14 +38,16 @@ public class MonsterDetailFragment extends MCFragment { Bundle arguments = getArguments(); assert arguments != null; UUID monsterId = UUID.fromString(MonsterDetailFragmentArgs.fromBundle(arguments).getMonsterId()); - setHasOptionsMenu(true); - mViewModel = new ViewModelProvider(this).get(MonsterDetailViewModel.class); + + monsterDetailViewModel = new ViewModelProvider(this).get(MonsterDetailViewModel.class); + View root = inflater.inflate(R.layout.fragment_monster, container, false); + repository.getMonster(monsterId).toObservable() .firstOrError() .subscribe(new DisposableSingleObserver() { @Override public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull Monster monster) { - mViewModel.setMonster(monster); + monsterDetailViewModel.setMonster(monster); dispose(); } @@ -63,194 +57,172 @@ public class MonsterDetailFragment extends MCFragment { dispose(); } }); - View root = inflater.inflate(R.layout.fragment_monster, container, false); - mHolder = new ViewHolder(root); - mViewModel.getName().observe(getViewLifecycleOwner(), name -> { - mHolder.name.setText(name); - setTitle(getString(R.string.title_monsterDetails_fmt, name)); + final TextView monsterName = root.findViewById(R.id.name); + monsterDetailViewModel.getName().observe(getViewLifecycleOwner(), monsterName::setText); + + final TextView monsterMeta = root.findViewById(R.id.meta); + monsterDetailViewModel.getMeta().observe(getViewLifecycleOwner(), monsterMeta::setText); + + final TextView monsterArmorClass = root.findViewById(R.id.armor_class); + monsterDetailViewModel.getArmorClass().observe(getViewLifecycleOwner(), armorText -> monsterArmorClass.setText(Html.fromHtml("Armor Class " + armorText))); + + final TextView monsterHitPoints = root.findViewById(R.id.hit_points); + monsterDetailViewModel.getHitPoints().observe(getViewLifecycleOwner(), hitPoints -> monsterHitPoints.setText(Html.fromHtml("Hit Points " + hitPoints))); + + final TextView monsterSpeed = root.findViewById(R.id.speed); + monsterDetailViewModel.getSpeed().observe(getViewLifecycleOwner(), speed -> monsterSpeed.setText(Html.fromHtml("Speed " + speed))); + + final TextView monsterStrength = root.findViewById(R.id.strength); + monsterDetailViewModel.getStrength().observe(getViewLifecycleOwner(), monsterStrength::setText); + + final TextView monsterDexterity = root.findViewById(R.id.dexterity); + monsterDetailViewModel.getDexterity().observe(getViewLifecycleOwner(), monsterDexterity::setText); + + final TextView monsterConstitution = root.findViewById(R.id.constitution); + monsterDetailViewModel.getConstitution().observe(getViewLifecycleOwner(), monsterConstitution::setText); + + final TextView monsterIntelligence = root.findViewById(R.id.intelligence); + monsterDetailViewModel.getIntelligence().observe(getViewLifecycleOwner(), monsterIntelligence::setText); + + final TextView monsterWisdom = root.findViewById(R.id.wisdom); + monsterDetailViewModel.getWisdom().observe(getViewLifecycleOwner(), monsterWisdom::setText); + + final TextView monsterCharisma = root.findViewById(R.id.charisma); + monsterDetailViewModel.getCharisma().observe(getViewLifecycleOwner(), monsterCharisma::setText); + + final TextView monsterSavingThrows = root.findViewById(R.id.saving_throws); + monsterDetailViewModel.getSavingThrows().observe(getViewLifecycleOwner(), savingThrows -> { + if (StringHelper.isNullOrEmpty(savingThrows)) { + monsterSavingThrows.setVisibility(View.GONE); + } else { + monsterSavingThrows.setVisibility(View.VISIBLE); + } + monsterSavingThrows.setText(Html.fromHtml("Saving Throws " + savingThrows)); + }); + + final TextView monsterSkills = root.findViewById(R.id.skills); + monsterDetailViewModel.getSkills().observe(getViewLifecycleOwner(), skills -> { + if (StringHelper.isNullOrEmpty(skills)) { + monsterSkills.setVisibility(View.GONE); + } else { + monsterSkills.setVisibility(View.VISIBLE); + } + monsterSkills.setText(Html.fromHtml("Skills " + skills)); + }); + + final TextView monsterDamageVulnerabilities = root.findViewById(R.id.damage_vulnerabilities); + monsterDetailViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), damageType -> { + if (StringHelper.isNullOrEmpty(damageType)) { + monsterDamageVulnerabilities.setVisibility(View.GONE); + } else { + monsterDamageVulnerabilities.setVisibility(View.VISIBLE); + } + monsterDamageVulnerabilities.setText(Html.fromHtml("Damage Vulnerabilities " + damageType)); + }); + + final TextView monsterDamageResistances = root.findViewById(R.id.damage_resistances); + monsterDetailViewModel.getDamageResistances().observe(getViewLifecycleOwner(), damageType -> { + if (StringHelper.isNullOrEmpty(damageType)) { + monsterDamageResistances.setVisibility(View.GONE); + } else { + monsterDamageResistances.setVisibility(View.VISIBLE); + } + monsterDamageResistances.setText(Html.fromHtml("Damage Resistances " + damageType)); + }); + + final TextView monsterDamageImmunities = root.findViewById(R.id.damage_immunities); + monsterDetailViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), damageType -> { + if (StringHelper.isNullOrEmpty(damageType)) { + monsterDamageImmunities.setVisibility(View.GONE); + } else { + monsterDamageImmunities.setVisibility(View.VISIBLE); + } + monsterDamageImmunities.setText(Html.fromHtml("Damage Immunities " + damageType)); + }); + + final TextView monsterConditionImmunities = root.findViewById(R.id.condition_immunities); + monsterDetailViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), conditionImmunities -> { + if (StringHelper.isNullOrEmpty(conditionImmunities)) { + monsterConditionImmunities.setVisibility(View.GONE); + } else { + monsterConditionImmunities.setVisibility(View.VISIBLE); + } + monsterConditionImmunities.setText(Html.fromHtml("Condition Immunities " + conditionImmunities)); + }); + + final TextView monsterSenses = root.findViewById(R.id.senses); + monsterDetailViewModel.getSenses().observe(getViewLifecycleOwner(), senses -> { + if (StringHelper.isNullOrEmpty(senses)) { + monsterSenses.setVisibility(View.GONE); + } else { + monsterSenses.setVisibility(View.VISIBLE); + } + monsterSenses.setText(Html.fromHtml("Senses " + senses)); + }); + + final TextView monsterLanguages = root.findViewById(R.id.languages); + monsterDetailViewModel.getLanguages().observe(getViewLifecycleOwner(), languages -> { + if (StringHelper.isNullOrEmpty(languages)) { + monsterLanguages.setVisibility(View.GONE); + } else { + monsterLanguages.setVisibility(View.VISIBLE); + } + monsterLanguages.setText(Html.fromHtml("Languages " + languages)); + }); + + final TextView monsterChallenge = root.findViewById(R.id.challenge); + monsterDetailViewModel.getChallenge().observe(getViewLifecycleOwner(), challengeRating -> monsterChallenge.setText(Html.fromHtml("Challenge " + challengeRating))); + + final LinearLayout monsterAbilities = root.findViewById(R.id.abilities); + monsterDetailViewModel.getAbilities().observe(getViewLifecycleOwner(), abilities -> { + Context context = getContext(); + DisplayMetrics displayMetrics = null; + if (context != null) { + Resources resources = context.getResources(); + if (resources != null) { + displayMetrics = resources.getDisplayMetrics(); + } + } + monsterAbilities.removeAllViews(); + if (abilities != null) { + for (String ability : abilities) { + TextView tvAbility = new TextView(context); + // TODO: Handle multiline block quotes specially so they stay multiline. + // TODO: Replace QuoteSpans in the result of fromHtml with something like this https://stackoverflow.com/questions/7717567/how-to-style-blockquotes-in-android-textviews to make them indent as expected + Spanned spannedText = Html.fromHtml(CommonMarkHelper.toHtml(ability)); + tvAbility.setText(spannedText); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + layoutParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, displayMetrics); + tvAbility.setLayoutParams(layoutParams); + monsterAbilities.addView(tvAbility); + } + } + }); + + final LinearLayout monsterActions = root.findViewById(R.id.actions); + monsterDetailViewModel.getActions().observe(getViewLifecycleOwner(), actions -> { + Context context = getContext(); + DisplayMetrics displayMetrics = null; + if (context != null) { + Resources resources = context.getResources(); + if (resources != null) { + displayMetrics = resources.getDisplayMetrics(); + } + } + monsterActions.removeAllViews(); + if (actions != null) { + for (String action : actions) { + TextView tvAction = new TextView(getContext()); + tvAction.setText(Html.fromHtml(CommonMarkHelper.toHtml(action))); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + layoutParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, displayMetrics); + tvAction.setLayoutParams(layoutParams); + monsterActions.addView(tvAction); + } + } }); - mViewModel.getMeta().observe(getViewLifecycleOwner(), mHolder.meta::setText); - mViewModel.getArmorClass().observe(getViewLifecycleOwner(), armorText -> setupLabeledTextView(mHolder.armorClass, armorText, R.string.label_armor_class)); - mViewModel.getHitPoints().observe(getViewLifecycleOwner(), hitPoints -> setupLabeledTextView(mHolder.hitPoints, hitPoints, R.string.label_hit_points)); - mViewModel.getSpeed().observe(getViewLifecycleOwner(), speed -> setupLabeledTextView(mHolder.speed, speed, R.string.label_speed)); - mViewModel.getStrength().observe(getViewLifecycleOwner(), mHolder.strength::setText); - mViewModel.getDexterity().observe(getViewLifecycleOwner(), mHolder.dexterity::setText); - mViewModel.getConstitution().observe(getViewLifecycleOwner(), mHolder.constitution::setText); - mViewModel.getIntelligence().observe(getViewLifecycleOwner(), mHolder.intelligence::setText); - mViewModel.getWisdom().observe(getViewLifecycleOwner(), mHolder.wisdom::setText); - mViewModel.getCharisma().observe(getViewLifecycleOwner(), mHolder.charisma::setText); - mViewModel.getSavingThrows().observe(getViewLifecycleOwner(), savingThrows -> setupOptionalTextView(mHolder.savingThrows, savingThrows, R.string.label_saving_throws)); - mViewModel.getSkills().observe(getViewLifecycleOwner(), skills -> setupOptionalTextView(mHolder.skills, skills, R.string.label_skills)); - mViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), damageTypes -> setupOptionalTextView(mHolder.damageVulnerabilities, damageTypes, R.string.label_damage_vulnerabilities)); - mViewModel.getDamageResistances().observe(getViewLifecycleOwner(), damageTypes -> setupOptionalTextView(mHolder.damageResistances, damageTypes, R.string.label_damage_resistances)); - mViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), damageTypes -> setupOptionalTextView(mHolder.damageImmunities, damageTypes, R.string.label_damage_immunities)); - mViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), conditionImmunities -> setupOptionalTextView(mHolder.conditionImmunities, conditionImmunities, R.string.label_condition_immunities)); - mViewModel.getSenses().observe(getViewLifecycleOwner(), senses -> setupOptionalTextView(mHolder.senses, senses, R.string.label_senses)); - mViewModel.getLanguages().observe(getViewLifecycleOwner(), languages -> setupOptionalTextView(mHolder.languages, languages, R.string.label_languages)); - mViewModel.getChallenge().observe(getViewLifecycleOwner(), challengeRating -> setupLabeledTextView(mHolder.challenge, challengeRating, R.string.label_challenge_rating)); - mViewModel.getAbilities().observe(getViewLifecycleOwner(), abilities -> setupTraitList(mHolder.abilities, abilities)); - mViewModel.getActions().observe(getViewLifecycleOwner(), actions -> setupTraitList(mHolder.actions, actions, mHolder.actions_label, mHolder.actions_divider)); - mViewModel.getReactions().observe(getViewLifecycleOwner(), reactions -> setupTraitList(mHolder.reactions, reactions, mHolder.reactions_label, mHolder.reactions_divider)); - mViewModel.getRegionalEffects().observe(getViewLifecycleOwner(), regionalEffects -> setupTraitList(mHolder.regionalEffects, regionalEffects, mHolder.regionalEffects_label, mHolder.regionalEffects_divider)); - mViewModel.getLairActions().observe(getViewLifecycleOwner(), lairActions -> setupTraitList(mHolder.lairActions, lairActions, mHolder.lairActions_label, mHolder.lairActions_divider)); - mViewModel.getLegendaryActions().observe(getViewLifecycleOwner(), legendaryActions -> setupTraitList(mHolder.legendaryActions, legendaryActions, mHolder.legendaryActions_label, mHolder.legendaryActions_divider)); return root; } - - private void setupLabeledTextView(@NonNull TextView view, String text, int titleId) { - String title = getString(titleId); - String fullText = String.format("%s %s", title, text); - view.setText(Html.fromHtml(fullText)); - } - - private void setupOptionalTextView(TextView root, String text, int titleId) { - String title = getString(titleId); - if (StringHelper.isNullOrEmpty(text)) { - root.setVisibility(View.GONE); - } else { - root.setVisibility(View.VISIBLE); - } - Spanned formatted; - if (StringHelper.isNullOrEmpty(title)) { - formatted = Html.fromHtml(text); - } else { - formatted = Html.fromHtml(String.format("%s %s", title, text)); - } - root.setText(formatted); - } - - private void setupTraitList(@NonNull LinearLayout root, @NonNull List traits) { - setupTraitList(root, traits, null, null); - } - - private void setupTraitList(@NonNull LinearLayout root, @NonNull List traits, View label, View divider) { - int visibility = traits.size() > 0 ? View.VISIBLE : View.GONE; - Context context = getContext(); - DisplayMetrics displayMetrics = null; - if (context != null) { - Resources resources = context.getResources(); - if (resources != null) { - displayMetrics = resources.getDisplayMetrics(); - } - } - root.removeAllViews(); - for (String action : traits) { - TextView tvAction = new TextView(getContext()); - // TODO: Handle multiline block quotes specially so they stay multiline. - // TODO: Replace QuoteSpans in the result of fromHtml with something like this https://stackoverflow.com/questions/7717567/how-to-style-blockquotes-in-android-textviews to make them indent as expected - tvAction.setText(Html.fromHtml(CommonMarkHelper.toHtml(action))); - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - layoutParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, displayMetrics); - tvAction.setLayoutParams(layoutParams); - root.addView(tvAction); - } - root.setVisibility(visibility); - if (label != null) { - label.setVisibility(visibility); - } - if (divider != null) { - divider.setVisibility(visibility); - } - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - inflater.inflate(R.menu.monster_detail_menu, menu); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.menu_action_edit_monster) { - UUID monsterId = mViewModel.getId().getValue(); - if (monsterId != null) { - NavDirections action = MonsterDetailFragmentDirections.actionNavigationMonsterToEditMonsterFragment(monsterId.toString()); - Navigation.findNavController(requireView()).navigate(action); - } else { - Logger.logWTF("monsterId cannot be null."); - } - return true; - } - return super.onOptionsItemSelected(item); - } - - private static class ViewHolder { - final TextView name; - final TextView meta; - final TextView armorClass; - final TextView hitPoints; - final TextView speed; - final TextView strength; - final TextView dexterity; - final TextView constitution; - final TextView intelligence; - final TextView wisdom; - final TextView charisma; - final TextView savingThrows; - final TextView skills; - final TextView damageVulnerabilities; - final TextView damageResistances; - final TextView damageImmunities; - final TextView conditionImmunities; - final TextView senses; - final TextView languages; - final TextView challenge; - final LinearLayout abilities; - final LinearLayout actions; - final TextView actions_label; - final ImageView actions_divider; - final LinearLayout reactions; - final TextView reactions_label; - final ImageView reactions_divider; - final LinearLayout legendaryActions; - final TextView legendaryActions_label; - final ImageView legendaryActions_divider; - final LinearLayout lairActions; - final TextView lairActions_label; - final ImageView lairActions_divider; - final LinearLayout regionalEffects; - final TextView regionalEffects_label; - final ImageView regionalEffects_divider; - - ViewHolder(@NonNull View root) { - name = root.findViewById(R.id.name); - meta = root.findViewById(R.id.meta); - armorClass = root.findViewById(R.id.armorClass); - hitPoints = root.findViewById(R.id.hitPoints); - speed = root.findViewById(R.id.speed); - strength = root.findViewById(R.id.strength); - dexterity = root.findViewById(R.id.dexterity); - constitution = root.findViewById(R.id.constitution); - intelligence = root.findViewById(R.id.intelligence); - wisdom = root.findViewById(R.id.wisdom); - charisma = root.findViewById(R.id.charisma); - savingThrows = root.findViewById(R.id.savingThrows); - skills = root.findViewById(R.id.skills); - damageVulnerabilities = root.findViewById(R.id.damageVulnerabilities); - damageResistances = root.findViewById(R.id.damageResistances); - damageImmunities = root.findViewById(R.id.damageImmunities); - conditionImmunities = root.findViewById(R.id.conditionImmunities); - senses = root.findViewById(R.id.senses); - languages = root.findViewById(R.id.languages); - challenge = root.findViewById(R.id.challenge); - abilities = root.findViewById(R.id.abilities); - actions = root.findViewById(R.id.actions); - actions_divider = root.findViewById(R.id.actions_divider); - actions_label = root.findViewById(R.id.actions_label); - reactions = root.findViewById(R.id.reactions); - reactions_divider = root.findViewById(R.id.reactions_divider); - reactions_label = root.findViewById(R.id.reactions_label); - legendaryActions = root.findViewById(R.id.legendaryActions); - legendaryActions_divider = root.findViewById(R.id.legendaryActions_divider); - legendaryActions_label = root.findViewById(R.id.legendaryActions_label); - lairActions = root.findViewById(R.id.lairActions); - lairActions_divider = root.findViewById(R.id.lairActions_divider); - lairActions_label = root.findViewById(R.id.lairActions_label); - regionalEffects = root.findViewById(R.id.regionalEffects); - regionalEffects_divider = root.findViewById(R.id.regionalEffects_divider); - regionalEffects_label = root.findViewById(R.id.regionalEffects_label); - } - } } diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterDetailViewModel.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterDetailViewModel.java index 38e5d13..115edc7 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterDetailViewModel.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterDetailViewModel.java @@ -1,6 +1,5 @@ package com.majinnaibu.monstercards.ui.monster; -import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; @@ -9,180 +8,194 @@ import com.majinnaibu.monstercards.models.Monster; import java.util.ArrayList; import java.util.List; -import java.util.UUID; public class MonsterDetailViewModel extends ViewModel { - private final MutableLiveData> mAbilities; - private final MutableLiveData> mActions; - private final MutableLiveData mArmorClass; - private final MutableLiveData mChallenge; - private final MutableLiveData mCharisma; - private final MutableLiveData mConditionImmunities; - private final MutableLiveData mConstitution; - private final MutableLiveData mDamageResistances; - private final MutableLiveData mDamageImmunities; - private final MutableLiveData mDamageVulnerabilities; - private final MutableLiveData mDexterity; - private final MutableLiveData mHitPoints; - private final MutableLiveData mIntelligence; - private final MutableLiveData> mLairActions; - private final MutableLiveData mLanguages; - private final MutableLiveData> mLegendaryActions; - private final MutableLiveData mMeta; - private final MutableLiveData mName; - private final MutableLiveData> mReactions; - private final MutableLiveData> mRegionalEffects; - private final MutableLiveData mSavingThrows; - private final MutableLiveData mSenses; - private final MutableLiveData mSkills; - private final MutableLiveData mSpeed; - private final MutableLiveData mStrength; - private final MutableLiveData mWisdom; - private final MutableLiveData mMonsterId; - private Monster mMonster; - public MonsterDetailViewModel() { mMonster = null; - mAbilities = new MutableLiveData<>(new ArrayList<>()); - mActions = new MutableLiveData<>(new ArrayList<>()); - mArmorClass = new MutableLiveData<>(""); - mChallenge = new MutableLiveData<>(""); - mCharisma = new MutableLiveData<>(""); - mConditionImmunities = new MutableLiveData<>(""); - mConstitution = new MutableLiveData<>(""); - mDamageImmunities = new MutableLiveData<>(""); - mDamageResistances = new MutableLiveData<>(""); - mDamageVulnerabilities = new MutableLiveData<>(""); - mDexterity = new MutableLiveData<>(""); - mHitPoints = new MutableLiveData<>(""); - mIntelligence = new MutableLiveData<>(""); - mLairActions = new MutableLiveData<>(new ArrayList<>()); - mLanguages = new MutableLiveData<>(""); - mLegendaryActions = new MutableLiveData<>(new ArrayList<>()); - mMeta = new MutableLiveData<>(""); - mName = new MutableLiveData<>(""); - mReactions = new MutableLiveData<>(new ArrayList<>()); - mRegionalEffects = new MutableLiveData<>(new ArrayList<>()); - mSavingThrows = new MutableLiveData<>(""); - mSenses = new MutableLiveData<>(""); - mSkills = new MutableLiveData<>(""); - mSpeed = new MutableLiveData<>(""); - mStrength = new MutableLiveData<>(""); - mWisdom = new MutableLiveData<>(""); - mMonsterId = new MutableLiveData<>(UUID.fromString("00000000-0000-0000-0000-000000000000")); + mAbilities = new MutableLiveData<>(); + mAbilities.setValue(new ArrayList<>()); + mActions = new MutableLiveData<>(); + mActions.setValue(new ArrayList<>()); + mArmorClass = new MutableLiveData<>(); + mArmorClass.setValue(""); + mChallenge = new MutableLiveData<>(); + mChallenge.setValue(""); + mCharisma = new MutableLiveData<>(); + mCharisma.setValue(""); + mConditionImmunities = new MutableLiveData<>(); + mConditionImmunities.setValue(""); + mConstitution = new MutableLiveData<>(); + mConstitution.setValue(""); + mDamageImmunities = new MutableLiveData<>(); + mDamageImmunities.setValue(""); + mDamageResistances = new MutableLiveData<>(); + mDamageResistances.setValue(""); + mDamageVulnerabilities = new MutableLiveData<>(); + mDamageVulnerabilities.setValue(""); + mDexterity = new MutableLiveData<>(); + mDexterity.setValue(""); + mHitPoints = new MutableLiveData<>(); + mHitPoints.setValue(""); + mIntelligence = new MutableLiveData<>(); + mIntelligence.setValue(""); + mLanguages = new MutableLiveData<>(); + mLanguages.setValue(""); + mMeta = new MutableLiveData<>(); + mMeta.setValue(""); + mName = new MutableLiveData<>(); + mName.setValue(""); + mSavingThrows = new MutableLiveData<>(); + mSavingThrows.setValue(""); + mSenses = new MutableLiveData<>(); + mSenses.setValue(""); + mSkills = new MutableLiveData<>(); + mSkills.setValue(""); + mSpeed = new MutableLiveData<>(); + mSpeed.setValue(""); + mStrength = new MutableLiveData<>(); + mStrength.setValue(""); + mWisdom = new MutableLiveData<>(); + mWisdom.setValue(""); } + private final MutableLiveData> mAbilities; + public LiveData> getAbilities() { return mAbilities; } + private final MutableLiveData> mActions; + public LiveData> getActions() { return mActions; } - public LiveData> getReactions() { - return mReactions; - } - - public LiveData> getLegendaryActions() { - return mLegendaryActions; - } - - public LiveData> getLairActions() { - return mLairActions; - } - - public LiveData> getRegionalEffects() { - return mRegionalEffects; - } + private final MutableLiveData mArmorClass; public LiveData getArmorClass() { return mArmorClass; } + private final MutableLiveData mChallenge; + public LiveData getChallenge() { return mChallenge; } + private final MutableLiveData mCharisma; + public LiveData getCharisma() { return mCharisma; } + private final MutableLiveData mConditionImmunities; + public LiveData getConditionImmunities() { return mConditionImmunities; } + private final MutableLiveData mConstitution; + public LiveData getConstitution() { return mConstitution; } + private final MutableLiveData mDamageResistances; + public LiveData getDamageResistances() { return mDamageResistances; } + private final MutableLiveData mDamageImmunities; + public LiveData getDamageImmunities() { return mDamageImmunities; } + private final MutableLiveData mDamageVulnerabilities; + public LiveData getDamageVulnerabilities() { return mDamageVulnerabilities; } + private final MutableLiveData mDexterity; + public LiveData getDexterity() { return mDexterity; } + private final MutableLiveData mHitPoints; + public LiveData getHitPoints() { return mHitPoints; } + private final MutableLiveData mIntelligence; + public LiveData getIntelligence() { return mIntelligence; } + private final MutableLiveData mLanguages; + public LiveData getLanguages() { return mLanguages; } + private final MutableLiveData mMeta; + public LiveData getMeta() { return mMeta; } + private final MutableLiveData mName; + public LiveData getName() { return mName; } + private final MutableLiveData mSavingThrows; + public LiveData getSavingThrows() { return mSavingThrows; } + private final MutableLiveData mSenses; + public LiveData getSenses() { return mSenses; } + private final MutableLiveData mSkills; + public LiveData getSkills() { return mSkills; } + private final MutableLiveData mSpeed; + public LiveData getSpeed() { return mSpeed; } + private final MutableLiveData mStrength; + public LiveData getStrength() { return mStrength; } + private final MutableLiveData mWisdom; + public LiveData getWisdom() { return mWisdom; } - public LiveData getId() { - return mMonsterId; - } + private Monster mMonster; - public void setMonster(@NonNull Monster monster) { + public void setMonster(Monster monster) { mMonster = monster; + mAbilities.setValue(mMonster.getAbilityDescriptions()); mActions.setValue(mMonster.getActionDescriptions()); mArmorClass.setValue(mMonster.getArmorClass()); @@ -196,14 +209,9 @@ public class MonsterDetailViewModel extends ViewModel { mDexterity.setValue(monster.getDexterityDescription()); mHitPoints.setValue(mMonster.getHitPoints()); mIntelligence.setValue(monster.getIntelligenceDescription()); - mLairActions.setValue(mMonster.getLairActionDescriptions()); mLanguages.setValue(mMonster.getLanguagesDescription()); - mLegendaryActions.setValue(mMonster.getLegendaryActionDescriptions()); mMeta.setValue(mMonster.getMeta()); - mMonsterId.setValue(mMonster.id); mName.setValue(mMonster.name); - mReactions.setValue(monster.getReactionDescriptions()); - mRegionalEffects.setValue(monster.getRegionalActionDescriptions()); mSavingThrows.setValue(monster.getSavingThrowsDescription()); mSenses.setValue(monster.getSensesDescription()); mSkills.setValue(monster.getSkillsDescription()); @@ -211,4 +219,4 @@ public class MonsterDetailViewModel extends ViewModel { mStrength.setValue(monster.getStrengthDescription()); mWisdom.setValue(monster.getWisdomDescription()); } -} +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterFragment.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterFragment.java deleted file mode 100644 index 59b1020..0000000 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterFragment.java +++ /dev/null @@ -1,229 +0,0 @@ -package com.majinnaibu.monstercards.ui.monster; - -import android.content.Context; -import android.content.res.Resources; -import android.os.Bundle; -import android.text.Html; -import android.text.Spanned; -import android.util.DisplayMetrics; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.lifecycle.ViewModelProvider; - -import com.majinnaibu.monstercards.R; -import com.majinnaibu.monstercards.data.MonsterRepository; -import com.majinnaibu.monstercards.helpers.CommonMarkHelper; -import com.majinnaibu.monstercards.helpers.StringHelper; -import com.majinnaibu.monstercards.models.Monster; -import com.majinnaibu.monstercards.ui.MCFragment; -import com.majinnaibu.monstercards.utils.Logger; - -import java.util.UUID; - -import io.reactivex.rxjava3.observers.DisposableSingleObserver; - -@SuppressWarnings("FieldCanBeLocal") -public class MonsterFragment extends MCFragment { - - private MonsterViewModel monsterViewModel; - - public View onCreateView(@NonNull LayoutInflater inflater, - ViewGroup container, Bundle savedInstanceState) { - MonsterRepository repository = getMonsterRepository(); - Bundle arguments = getArguments(); - assert arguments != null; - UUID monsterId = UUID.fromString(MonsterFragmentArgs.fromBundle(arguments).getMonsterId()); - - monsterViewModel = new ViewModelProvider(this).get(MonsterViewModel.class); - View root = inflater.inflate(R.layout.fragment_monster, container, false); - - repository.getMonster(monsterId).toObservable() - .firstOrError() - .subscribe(new DisposableSingleObserver() { - @Override - public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull Monster monster) { - monsterViewModel.setMonster(monster); - dispose(); - } - - @Override - public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) { - Logger.logError(e); - dispose(); - } - }); - - final TextView monsterName = root.findViewById(R.id.name); - monsterViewModel.getName().observe(getViewLifecycleOwner(), monsterName::setText); - - final TextView monsterMeta = root.findViewById(R.id.meta); - monsterViewModel.getMeta().observe(getViewLifecycleOwner(), monsterMeta::setText); - - final TextView monsterArmorClass = root.findViewById(R.id.armor_class); - monsterViewModel.getArmorClass().observe(getViewLifecycleOwner(), armorText -> monsterArmorClass.setText(Html.fromHtml("Armor Class " + armorText))); - - final TextView monsterHitPoints = root.findViewById(R.id.hit_points); - monsterViewModel.getHitPoints().observe(getViewLifecycleOwner(), hitPoints -> monsterHitPoints.setText(Html.fromHtml("Hit Points " + hitPoints))); - - final TextView monsterSpeed = root.findViewById(R.id.speed); - monsterViewModel.getSpeed().observe(getViewLifecycleOwner(), speed -> monsterSpeed.setText(Html.fromHtml("Speed " + speed))); - - final TextView monsterStrength = root.findViewById(R.id.strength); - monsterViewModel.getStrength().observe(getViewLifecycleOwner(), monsterStrength::setText); - - final TextView monsterDexterity = root.findViewById(R.id.dexterity); - monsterViewModel.getDexterity().observe(getViewLifecycleOwner(), monsterDexterity::setText); - - final TextView monsterConstitution = root.findViewById(R.id.constitution); - monsterViewModel.getConstitution().observe(getViewLifecycleOwner(), monsterConstitution::setText); - - final TextView monsterIntelligence = root.findViewById(R.id.intelligence); - monsterViewModel.getIntelligence().observe(getViewLifecycleOwner(), monsterIntelligence::setText); - - final TextView monsterWisdom = root.findViewById(R.id.wisdom); - monsterViewModel.getWisdom().observe(getViewLifecycleOwner(), monsterWisdom::setText); - - final TextView monsterCharisma = root.findViewById(R.id.charisma); - monsterViewModel.getCharisma().observe(getViewLifecycleOwner(), monsterCharisma::setText); - - final TextView monsterSavingThrows = root.findViewById(R.id.saving_throws); - monsterViewModel.getSavingThrows().observe(getViewLifecycleOwner(), savingThrows -> { - if (StringHelper.isNullOrEmpty(savingThrows)) { - monsterSavingThrows.setVisibility(View.GONE); - } else { - monsterSavingThrows.setVisibility(View.VISIBLE); - } - monsterSavingThrows.setText(Html.fromHtml("Saving Throws " + savingThrows)); - }); - - final TextView monsterSkills = root.findViewById(R.id.skills); - monsterViewModel.getSkills().observe(getViewLifecycleOwner(), skills -> { - if (StringHelper.isNullOrEmpty(skills)) { - monsterSkills.setVisibility(View.GONE); - } else { - monsterSkills.setVisibility(View.VISIBLE); - } - monsterSkills.setText(Html.fromHtml("Skills " + skills)); - }); - - final TextView monsterDamageVulnerabilities = root.findViewById(R.id.damage_vulnerabilities); - monsterViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), damageType -> { - if (StringHelper.isNullOrEmpty(damageType)) { - monsterDamageVulnerabilities.setVisibility(View.GONE); - } else { - monsterDamageVulnerabilities.setVisibility(View.VISIBLE); - } - monsterDamageVulnerabilities.setText(Html.fromHtml("Damage Vulnerabilities " + damageType)); - }); - - final TextView monsterDamageResistances = root.findViewById(R.id.damage_resistances); - monsterViewModel.getDamageResistances().observe(getViewLifecycleOwner(), damageType -> { - if (StringHelper.isNullOrEmpty(damageType)) { - monsterDamageResistances.setVisibility(View.GONE); - } else { - monsterDamageResistances.setVisibility(View.VISIBLE); - } - monsterDamageResistances.setText(Html.fromHtml("Damage Resistances " + damageType)); - }); - - final TextView monsterDamageImmunities = root.findViewById(R.id.damage_immunities); - monsterViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), damageType -> { - if (StringHelper.isNullOrEmpty(damageType)) { - monsterDamageImmunities.setVisibility(View.GONE); - } else { - monsterDamageImmunities.setVisibility(View.VISIBLE); - } - monsterDamageImmunities.setText(Html.fromHtml("Damage Immunities " + damageType)); - }); - - final TextView monsterConditionImmunities = root.findViewById(R.id.condition_immunities); - monsterViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), conditionImmunities -> { - if (StringHelper.isNullOrEmpty(conditionImmunities)) { - monsterConditionImmunities.setVisibility(View.GONE); - } else { - monsterConditionImmunities.setVisibility(View.VISIBLE); - } - monsterConditionImmunities.setText(Html.fromHtml("Condition Immunities " + conditionImmunities)); - }); - - final TextView monsterSenses = root.findViewById(R.id.senses); - monsterViewModel.getSenses().observe(getViewLifecycleOwner(), senses -> { - if (StringHelper.isNullOrEmpty(senses)) { - monsterSenses.setVisibility(View.GONE); - } else { - monsterSenses.setVisibility(View.VISIBLE); - } - monsterSenses.setText(Html.fromHtml("Senses " + senses)); - }); - - final TextView monsterLanguages = root.findViewById(R.id.languages); - monsterViewModel.getLanguages().observe(getViewLifecycleOwner(), languages -> { - if (StringHelper.isNullOrEmpty(languages)) { - monsterLanguages.setVisibility(View.GONE); - } else { - monsterLanguages.setVisibility(View.VISIBLE); - } - monsterLanguages.setText(Html.fromHtml("Languages " + languages)); - }); - - final TextView monsterChallenge = root.findViewById(R.id.challenge); - monsterViewModel.getChallenge().observe(getViewLifecycleOwner(), challengeRating -> monsterChallenge.setText(Html.fromHtml("Challenge " + challengeRating))); - - final LinearLayout monsterAbilities = root.findViewById(R.id.abilities); - monsterViewModel.getAbilities().observe(getViewLifecycleOwner(), abilities -> { - Context context = getContext(); - DisplayMetrics displayMetrics = null; - if (context != null) { - Resources resources = context.getResources(); - if (resources != null) { - displayMetrics = resources.getDisplayMetrics(); - } - } - monsterAbilities.removeAllViews(); - if (abilities != null) { - for (String ability : abilities) { - TextView tvAbility = new TextView(context); - // TODO: Handle multiline block quotes specially so they stay multiline. - // TODO: Replace QuoteSpans in the result of fromHtml with something like this https://stackoverflow.com/questions/7717567/how-to-style-blockquotes-in-android-textviews to make them indent as expected - Spanned spannedText = Html.fromHtml(CommonMarkHelper.toHtml(ability)); - tvAbility.setText(spannedText); - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - layoutParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, displayMetrics); - tvAbility.setLayoutParams(layoutParams); - monsterAbilities.addView(tvAbility); - } - } - }); - - final LinearLayout monsterActions = root.findViewById(R.id.actions); - monsterViewModel.getActions().observe(getViewLifecycleOwner(), actions -> { - Context context = getContext(); - DisplayMetrics displayMetrics = null; - if (context != null) { - Resources resources = context.getResources(); - if (resources != null) { - displayMetrics = resources.getDisplayMetrics(); - } - } - monsterActions.removeAllViews(); - if (actions != null) { - for (String action : actions) { - TextView tvAction = new TextView(getContext()); - tvAction.setText(Html.fromHtml(CommonMarkHelper.toHtml(action))); - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - layoutParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, displayMetrics); - tvAction.setLayoutParams(layoutParams); - monsterActions.addView(tvAction); - } - } - }); - - return root; - } -} diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterViewModel.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterViewModel.java deleted file mode 100644 index 63bc378..0000000 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterViewModel.java +++ /dev/null @@ -1,222 +0,0 @@ -package com.majinnaibu.monstercards.ui.monster; - -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; - -import com.majinnaibu.monstercards.models.Monster; - -import java.util.ArrayList; -import java.util.List; - -public class MonsterViewModel extends ViewModel { - - public MonsterViewModel() { - mMonster = null; - mAbilities = new MutableLiveData<>(); - mAbilities.setValue(new ArrayList<>()); - mActions = new MutableLiveData<>(); - mActions.setValue(new ArrayList<>()); - mArmorClass = new MutableLiveData<>(); - mArmorClass.setValue(""); - mChallenge = new MutableLiveData<>(); - mChallenge.setValue(""); - mCharisma = new MutableLiveData<>(); - mCharisma.setValue(""); - mConditionImmunities = new MutableLiveData<>(); - mConditionImmunities.setValue(""); - mConstitution = new MutableLiveData<>(); - mConstitution.setValue(""); - mDamageImmunities = new MutableLiveData<>(); - mDamageImmunities.setValue(""); - mDamageResistances = new MutableLiveData<>(); - mDamageResistances.setValue(""); - mDamageVulnerabilities = new MutableLiveData<>(); - mDamageVulnerabilities.setValue(""); - mDexterity = new MutableLiveData<>(); - mDexterity.setValue(""); - mHitPoints = new MutableLiveData<>(); - mHitPoints.setValue(""); - mIntelligence = new MutableLiveData<>(); - mIntelligence.setValue(""); - mLanguages = new MutableLiveData<>(); - mLanguages.setValue(""); - mMeta = new MutableLiveData<>(); - mMeta.setValue(""); - mName = new MutableLiveData<>(); - mName.setValue(""); - mSavingThrows = new MutableLiveData<>(); - mSavingThrows.setValue(""); - mSenses = new MutableLiveData<>(); - mSenses.setValue(""); - mSkills = new MutableLiveData<>(); - mSkills.setValue(""); - mSpeed = new MutableLiveData<>(); - mSpeed.setValue(""); - mStrength = new MutableLiveData<>(); - mStrength.setValue(""); - mWisdom = new MutableLiveData<>(); - mWisdom.setValue(""); - } - - private final MutableLiveData> mAbilities; - - public LiveData> getAbilities() { - return mAbilities; - } - - private final MutableLiveData> mActions; - - public LiveData> getActions() { - return mActions; - } - - private final MutableLiveData mArmorClass; - - public LiveData getArmorClass() { - return mArmorClass; - } - - private final MutableLiveData mChallenge; - - public LiveData getChallenge() { - return mChallenge; - } - - private final MutableLiveData mCharisma; - - public LiveData getCharisma() { - return mCharisma; - } - - private final MutableLiveData mConditionImmunities; - - public LiveData getConditionImmunities() { - return mConditionImmunities; - } - - private final MutableLiveData mConstitution; - - public LiveData getConstitution() { - return mConstitution; - } - - private final MutableLiveData mDamageResistances; - - public LiveData getDamageResistances() { - return mDamageResistances; - } - - private final MutableLiveData mDamageImmunities; - - public LiveData getDamageImmunities() { - return mDamageImmunities; - } - - private final MutableLiveData mDamageVulnerabilities; - - public LiveData getDamageVulnerabilities() { - return mDamageVulnerabilities; - } - - private final MutableLiveData mDexterity; - - public LiveData getDexterity() { - return mDexterity; - } - - private final MutableLiveData mHitPoints; - - public LiveData getHitPoints() { - return mHitPoints; - } - - private final MutableLiveData mIntelligence; - - public LiveData getIntelligence() { - return mIntelligence; - } - - private final MutableLiveData mLanguages; - - public LiveData getLanguages() { - return mLanguages; - } - - private final MutableLiveData mMeta; - - public LiveData getMeta() { - return mMeta; - } - - private final MutableLiveData mName; - - public LiveData getName() { - return mName; - } - - private final MutableLiveData mSavingThrows; - - public LiveData getSavingThrows() { - return mSavingThrows; - } - - private final MutableLiveData mSenses; - - public LiveData getSenses() { - return mSenses; - } - - private final MutableLiveData mSkills; - - public LiveData getSkills() { - return mSkills; - } - - private final MutableLiveData mSpeed; - - public LiveData getSpeed() { - return mSpeed; - } - - private final MutableLiveData mStrength; - - public LiveData getStrength() { - return mStrength; - } - - private final MutableLiveData mWisdom; - - public LiveData getWisdom() { - return mWisdom; - } - - private Monster mMonster; - - public void setMonster(Monster monster) { - mMonster = monster; - - mAbilities.setValue(mMonster.getAbilityDescriptions()); - mActions.setValue(mMonster.getActionDescriptions()); - mArmorClass.setValue(mMonster.getArmorClass()); - mChallenge.setValue(mMonster.getChallengeRatingDescription()); - mCharisma.setValue(monster.getCharismaDescription()); - mConditionImmunities.setValue(mMonster.getConditionImmunitiesDescription()); - mConstitution.setValue(monster.getConstitutionDescription()); - mDamageImmunities.setValue(mMonster.getDamageImmunitiesDescription()); - mDamageResistances.setValue(mMonster.getDamageResistancesDescription()); - mDamageVulnerabilities.setValue(mMonster.getDamageVulnerabilitiesDescription()); - mDexterity.setValue(monster.getDexterityDescription()); - mHitPoints.setValue(mMonster.getHitPoints()); - mIntelligence.setValue(monster.getIntelligenceDescription()); - mLanguages.setValue(mMonster.getLanguagesDescription()); - mMeta.setValue(mMonster.getMeta()); - mName.setValue(mMonster.name); - mSavingThrows.setValue(monster.getSavingThrowsDescription()); - mSenses.setValue(monster.getSensesDescription()); - mSkills.setValue(monster.getSkillsDescription()); - mSpeed.setValue(mMonster.getSpeedText()); - mStrength.setValue(monster.getStrengthDescription()); - mWisdom.setValue(monster.getWisdomDescription()); - } -} \ No newline at end of file diff --git a/Android/app/src/main/res/layout/fragment_monster.xml b/Android/app/src/main/res/layout/fragment_monster.xml index caf7b31..07013ab 100644 --- a/Android/app/src/main/res/layout/fragment_monster.xml +++ b/Android/app/src/main/res/layout/fragment_monster.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.monster.MonsterFragment"> + tools:context=".ui.monster.MonsterDetailFragment"> + tools:layout="@layout/fragment_search"> @@ -19,7 +19,7 @@ android:id="@+id/navigation_dashboard" android:name="com.majinnaibu.monstercards.ui.dashboard.DashboardFragment" android:label="@string/title_dashboard" - tools:layout="@layout/fragment_dashboard" > + tools:layout="@layout/fragment_dashboard"> @@ -29,7 +29,7 @@ android:id="@+id/navigation_collections" android:name="com.majinnaibu.monstercards.ui.collections.CollectionsFragment" android:label="@string/title_collections" - tools:layout="@layout/fragment_collections" > + tools:layout="@layout/fragment_collections"> @@ -39,7 +39,7 @@ android:id="@+id/navigation_library" android:name="com.majinnaibu.monstercards.ui.library.LibraryFragment" android:label="@string/title_library" - tools:layout="@layout/fragment_library" > + tools:layout="@layout/fragment_library"> @@ -47,7 +47,7 @@