Adds functional dashboard based on recycler view that picks the number of columns based on screen width.
This commit is contained in:
@@ -3,6 +3,7 @@ package com.majinnaibu.monstercards.models;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.room.ColumnInfo;
|
import androidx.room.ColumnInfo;
|
||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
@@ -531,10 +532,9 @@ public class Monster {
|
|||||||
int dieSize = Helpers.getHitDieForSize(size);
|
int dieSize = Helpers.getHitDieForSize(size);
|
||||||
int conMod = getConstitutionModifier();
|
int conMod = getConstitutionModifier();
|
||||||
// For PC style calculations use this
|
// For PC style calculations use this
|
||||||
//int hpTotal = (int) Math.max(1, Math.ceil(dieSize + conMod + (hitDice - 1) * ((dieSize + 1) / 2.0 + conMod)));
|
//return (int) Math.max(1, Math.ceil(dieSize + conMod + (hitDice - 1) * ((dieSize + 1) / 2.0 + conMod)));
|
||||||
// For monster style calculations use this
|
// For monster style calculations use this
|
||||||
int hpTotal = (int) Math.max(1, Math.ceil(hitDice * ((dieSize + 1) / 2.0 + conMod)));
|
return (int) Math.max(1, Math.ceil(hitDice * ((dieSize + 1) / 2.0 + conMod)));
|
||||||
return hpTotal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,6 +817,235 @@ public class Monster {
|
|||||||
return actionDescriptions;
|
return actionDescriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable @org.jetbrains.annotations.Nullable Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof Monster)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Monster other = (Monster) obj;
|
||||||
|
if (!challengeRating.equals(other.challengeRating)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!understandsButDescription.equals(other.understandsButDescription)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!languages.equals(other.languages)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!damageVulnerabilities.equals(other.damageVulnerabilities)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!damageResistances.equals(other.damageResistances)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!damageImmunities.equals(other.damageImmunities)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!conditionImmunities.equals(other.conditionImmunities)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!charismaSavingThrowProficiency.equals(other.charismaSavingThrowProficiency)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!wisdomSavingThrowProficiency.equals(other.wisdomSavingThrowProficiency)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!intelligenceSavingThrowProficiency.equals(other.intelligenceSavingThrowProficiency)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (constitutionSavingThrowProficiency.equals(other.constitutionSavingThrowProficiency)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dexteritySavingThrowProficiency.equals(other.dexteritySavingThrowProficiency)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strengthSavingThrowProficiency.equals(other.strengthSavingThrowProficiency)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (legendaryActions.equals(other.legendaryActions)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customChallengeRatingDescription.equals(other.customChallengeRatingDescription)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customSpeedDescription.equals(other.customSpeedDescription)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customHPDescription.equals(other.customHPDescription)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (otherArmorDescription.equals(other.otherArmorDescription)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alignment.equals(other.alignment)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subtype.equals(other.subtype)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abilities.equals(other.abilities)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actions.equals(other.actions)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (armorType.equals(other.armorType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (charismaSavingThrowAdvantage.equals(other.charismaSavingThrowAdvantage)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constitutionSavingThrowAdvantage.equals(other.constitutionSavingThrowAdvantage)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dexteritySavingThrowAdvantage.equals(other.dexteritySavingThrowAdvantage)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hitDice == other.hitDice) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id.equals(other.id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intelligenceSavingThrowAdvantage.equals(other.intelligenceSavingThrowAdvantage)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lairActions.equals(other.lairActions)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals(other.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reactions.equals(other.reactions)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regionalActions.equals(other.regionalActions)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (senses.equals(other.senses)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shieldBonus == other.shieldBonus) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size.equals(other.size)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skills.equals(other.skills)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strengthSavingThrowAdvantage.equals(other.strengthSavingThrowAdvantage)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strengthScore == other.strengthScore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.equals(other.type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wisdomSavingThrowAdvantage.equals(other.wisdomSavingThrowAdvantage)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wisdomScore == other.wisdomScore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (customProficiencyBonus == other.customProficiencyBonus) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (telepathyRange == other.telepathyRange) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intelligenceScore == other.intelligenceScore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constitutionScore == other.constitutionScore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dexterityScore == other.dexterityScore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCustomSpeed == other.hasCustomSpeed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCustomHP == other.hasCustomHP) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (swimSpeed == other.swimSpeed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flySpeed == other.flySpeed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (climbSpeed == other.climbSpeed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (burrowSpeed == other.burrowSpeed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walkSpeed == other.walkSpeed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (naturalArmorBonus == other.naturalArmorBonus) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canHover == other.canHover) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (charismaScore == other.charismaScore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Helpers {
|
public static class Helpers {
|
||||||
public static int getAbilityModifierForScore(int score) {
|
public static int getAbilityModifierForScore(int score) {
|
||||||
return (int) Math.floor((score - 10) / 2.0);
|
return (int) Math.floor((score - 10) / 2.0);
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
package com.majinnaibu.monstercards.ui.dashboard;
|
package com.majinnaibu.monstercards.ui.dashboard;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.GridLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.NavDirections;
|
||||||
|
import androidx.navigation.Navigation;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.data.enums.AbilityScore;
|
|
||||||
import com.majinnaibu.monstercards.data.enums.AdvantageType;
|
|
||||||
import com.majinnaibu.monstercards.data.enums.ChallengeRating;
|
|
||||||
import com.majinnaibu.monstercards.data.enums.ProficiencyType;
|
|
||||||
import com.majinnaibu.monstercards.models.Monster;
|
import com.majinnaibu.monstercards.models.Monster;
|
||||||
import com.majinnaibu.monstercards.models.Trait;
|
|
||||||
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
@@ -27,8 +26,9 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
|
|||||||
|
|
||||||
public class DashboardFragment extends MCFragment {
|
public class DashboardFragment extends MCFragment {
|
||||||
private static final String MODIFIER_FORMAT = "%+d";
|
private static final String MODIFIER_FORMAT = "%+d";
|
||||||
private ViewHolder mHolder;
|
|
||||||
private DashboardViewModel mViewModel;
|
private DashboardViewModel mViewModel;
|
||||||
|
private ViewHolder mHolder;
|
||||||
|
private DashboardRecyclerViewAdapter mAdapter;
|
||||||
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
ViewGroup container, Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
@@ -36,12 +36,7 @@ public class DashboardFragment extends MCFragment {
|
|||||||
View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
|
View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
|
||||||
mHolder = new ViewHolder(root);
|
mHolder = new ViewHolder(root);
|
||||||
|
|
||||||
mViewModel.getMonsters().observe(getViewLifecycleOwner(), monsters -> {
|
setupRecyclerView(mHolder.list);
|
||||||
setupMonsterCards(mHolder.monsterCards, R.layout.card_monster, monsters);
|
|
||||||
setupMonsterCards(mHolder.monsterShortCards, R.layout.card_monster_short, monsters);
|
|
||||||
setupMonsterCards(mHolder.monsterTiles, R.layout.tile_monster, monsters);
|
|
||||||
setupMonsterCards(mHolder.monsterShortTiles, R.layout.tile_monster_short, monsters);
|
|
||||||
});
|
|
||||||
|
|
||||||
getMonsterRepository()
|
getMonsterRepository()
|
||||||
.getMonsters()
|
.getMonsters()
|
||||||
@@ -54,362 +49,38 @@ public class DashboardFragment extends MCFragment {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupMonsterCards(GridLayout parent, int layout, List<Monster> monsters) {
|
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||||
LayoutInflater inflater = LayoutInflater.from(requireContext());
|
int columnCount = Math.max(1, (int) Math.floor(getResources().getConfiguration().screenWidthDp / 396));
|
||||||
parent.removeAllViews();
|
Logger.logWTF(String.format("Setting column count to %d", columnCount));
|
||||||
for (Monster monster : monsters) {
|
Context context = requireContext();
|
||||||
|
GridLayoutManager layoutManager = new GridLayoutManager(context, columnCount);
|
||||||
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
|
|
||||||
|
LiveData<List<Monster>> monsterData = mViewModel.getMonsters();
|
||||||
|
mAdapter = new DashboardRecyclerViewAdapter(monster -> {
|
||||||
if (monster != null) {
|
if (monster != null) {
|
||||||
View root = inflater.inflate(layout, parent, false);
|
navigateToMonsterDetail(monster);
|
||||||
setupCardOrTile(root, monster, layout);
|
|
||||||
GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams(root.getLayoutParams());
|
|
||||||
ViewGroup.LayoutParams lp2 = root.getLayoutParams();
|
|
||||||
layoutParams.width = 0;
|
|
||||||
layoutParams.height = GridLayout.LayoutParams.WRAP_CONTENT;
|
|
||||||
layoutParams.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 01.0f);
|
|
||||||
root.setLayoutParams(layoutParams);
|
|
||||||
parent.addView(root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupCardOrTile(View root, Monster monster, int layout) {
|
|
||||||
if (layout == R.layout.card_monster || layout == R.layout.card_monster_short) {
|
|
||||||
MonsterCardViewHolder holder = new MonsterCardViewHolder(root);
|
|
||||||
int numActions = monster.actions.size();
|
|
||||||
Trait action1 = numActions > 0 ? monster.actions.get(0) : null;
|
|
||||||
Trait action2 = numActions > 1 ? monster.actions.get(1) : null;
|
|
||||||
Trait action3 = numActions > 2 ? monster.actions.get(2) : null;
|
|
||||||
setupAction(holder.action1, action1);
|
|
||||||
setupAction(holder.action2, action2);
|
|
||||||
setupAction(holder.action3, action3);
|
|
||||||
int acValue = monster.getArmorClassValue();
|
|
||||||
holder.armorClass.value.setText(acValue <= 0 ? "*" : String.format("%d", acValue));
|
|
||||||
holder.challengeRating.setText(String.format("CR %s", getChallengeRatingAbbreviation(monster.challengeRating)));
|
|
||||||
setupAttribute(holder.strength, monster, AbilityScore.STRENGTH);
|
|
||||||
setupAttribute(holder.dexterity, monster, AbilityScore.DEXTERITY);
|
|
||||||
setupAttribute(holder.constitution, monster, AbilityScore.CONSTITUTION);
|
|
||||||
setupAttribute(holder.intelligence, monster, AbilityScore.INTELLIGENCE);
|
|
||||||
setupAttribute(holder.wisdom, monster, AbilityScore.WISDOM);
|
|
||||||
setupAttribute(holder.charisma, monster, AbilityScore.CHARISMA);
|
|
||||||
int hpValue = monster.getHitPointsValue();
|
|
||||||
holder.hitPoints.value.setText(hpValue <= 0 ? "*" : String.format("%d", hpValue));
|
|
||||||
holder.meta.setText(monster.getMeta());
|
|
||||||
holder.name.setText(monster.name);
|
|
||||||
} else {
|
} else {
|
||||||
MonsterTileViewHolder holder = new MonsterTileViewHolder(root);
|
Logger.logError("Can't navigate to MonsterDetailFragment with a null monster");
|
||||||
holder.name.setText(monster.name);
|
|
||||||
holder.meta.setText(monster.getMeta());
|
|
||||||
int acValue = monster.getArmorClassValue();
|
|
||||||
holder.armorClass.value.setText(acValue <= 0 ? "*" : String.format("%d", acValue));
|
|
||||||
holder.challengeRating.value.setText(getChallengeRatingAbbreviation(monster.challengeRating));
|
|
||||||
int hpValue = monster.getHitPointsValue();
|
|
||||||
holder.hitPoints.value.setText(hpValue <= 0 ? "*" : String.format("%d", hpValue));
|
|
||||||
holder.initiative.value.setText(String.format(MODIFIER_FORMAT, monster.getDexterityModifier()));
|
|
||||||
setupAction(holder.action, monster.actions.size() > 0 ? monster.actions.get(0) : null);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
if (monsterData != null) {
|
||||||
|
monsterData.observe(getViewLifecycleOwner(), monsters -> mAdapter.submitList(monsters));
|
||||||
|
}
|
||||||
|
recyclerView.setAdapter(mAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupAttribute(AttributeViewHolder holder, Monster monster, AbilityScore abilityScore) {
|
private void navigateToMonsterDetail(Monster monster) {
|
||||||
holder.name.setText(getAbilityScoreAbbreviation(abilityScore));
|
NavDirections action = DashboardFragmentDirections.actionNavigationDashboardToNavigationMonster(monster.id.toString());
|
||||||
holder.modifier.setText(String.format(MODIFIER_FORMAT, monster.getAbilityModifier(abilityScore)));
|
Navigation.findNavController(requireView()).navigate(action);
|
||||||
holder.proficiency.setText(getProficiencyAbbreviation(monster.getSavingThrowProficiencyType(abilityScore)));
|
|
||||||
holder.advantage.setText(getAdvantageAbbreviation(monster.getSavingThrowAdvantageType(abilityScore)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getAbilityScoreAbbreviation(AbilityScore abilityScore) {
|
|
||||||
switch (abilityScore) {
|
|
||||||
case STRENGTH:
|
|
||||||
return "S";
|
|
||||||
case DEXTERITY:
|
|
||||||
return "D";
|
|
||||||
case CONSTITUTION:
|
|
||||||
return "C";
|
|
||||||
case INTELLIGENCE:
|
|
||||||
return "I";
|
|
||||||
case WISDOM:
|
|
||||||
return "W";
|
|
||||||
case CHARISMA:
|
|
||||||
return "Ch";
|
|
||||||
default:
|
|
||||||
Logger.logUnimplementedFeature(String.format("Get an abbreviation for AbilityScore value %s", abilityScore));
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getChallengeRatingAbbreviation(ChallengeRating challengeRating) {
|
|
||||||
Logger.logUnimplementedMethod();
|
|
||||||
switch (challengeRating) {
|
|
||||||
case CUSTOM:
|
|
||||||
return "*";
|
|
||||||
case ZERO:
|
|
||||||
return "0";
|
|
||||||
case ONE_EIGHTH:
|
|
||||||
return "1/8";
|
|
||||||
case ONE_QUARTER:
|
|
||||||
return "1/4";
|
|
||||||
case ONE_HALF:
|
|
||||||
return "1/2";
|
|
||||||
case ONE:
|
|
||||||
return "1";
|
|
||||||
case TWO:
|
|
||||||
return "2";
|
|
||||||
case THREE:
|
|
||||||
return "3";
|
|
||||||
case FOUR:
|
|
||||||
return "4";
|
|
||||||
case FIVE:
|
|
||||||
return "5";
|
|
||||||
case SIX:
|
|
||||||
return "6";
|
|
||||||
case SEVEN:
|
|
||||||
return "7";
|
|
||||||
case EIGHT:
|
|
||||||
return "8";
|
|
||||||
case NINE:
|
|
||||||
return "9";
|
|
||||||
case TEN:
|
|
||||||
return "10";
|
|
||||||
case ELEVEN:
|
|
||||||
return "11";
|
|
||||||
case TWELVE:
|
|
||||||
return "12";
|
|
||||||
case THIRTEEN:
|
|
||||||
return "13";
|
|
||||||
case FOURTEEN:
|
|
||||||
return "14";
|
|
||||||
case FIFTEEN:
|
|
||||||
return "15";
|
|
||||||
case SIXTEEN:
|
|
||||||
return "16";
|
|
||||||
case SEVENTEEN:
|
|
||||||
return "17";
|
|
||||||
case EIGHTEEN:
|
|
||||||
return "18";
|
|
||||||
case NINETEEN:
|
|
||||||
return "19";
|
|
||||||
case TWENTY:
|
|
||||||
return "20";
|
|
||||||
case TWENTY_ONE:
|
|
||||||
return "21";
|
|
||||||
case TWENTY_TWO:
|
|
||||||
return "22";
|
|
||||||
case TWENTY_THREE:
|
|
||||||
return "23";
|
|
||||||
case TWENTY_FOUR:
|
|
||||||
return "24";
|
|
||||||
case TWENTY_FIVE:
|
|
||||||
return "25";
|
|
||||||
case TWENTY_SIX:
|
|
||||||
return "26";
|
|
||||||
case TWENTY_SEVEN:
|
|
||||||
return "27";
|
|
||||||
case TWENTY_EIGHT:
|
|
||||||
return "28";
|
|
||||||
case TWENTY_NINE:
|
|
||||||
return "29";
|
|
||||||
case THIRTY:
|
|
||||||
return "30";
|
|
||||||
default:
|
|
||||||
Logger.logUnimplementedFeature(String.format("Get an abbreviation for ChallengeRating value %s", challengeRating));
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getProficiencyAbbreviation(ProficiencyType proficiency) {
|
|
||||||
switch (proficiency) {
|
|
||||||
case NONE:
|
|
||||||
return "";
|
|
||||||
case EXPERTISE:
|
|
||||||
return "E";
|
|
||||||
case PROFICIENT:
|
|
||||||
return "P";
|
|
||||||
default:
|
|
||||||
Logger.logUnimplementedFeature(String.format("Get an abbreviation for ProficiencyType value %s", proficiency));
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getAdvantageAbbreviation(AdvantageType advantage) {
|
|
||||||
switch (advantage) {
|
|
||||||
case NONE:
|
|
||||||
return "";
|
|
||||||
case ADVANTAGE:
|
|
||||||
return "A";
|
|
||||||
case DISADVANTAGE:
|
|
||||||
return "D";
|
|
||||||
default:
|
|
||||||
Logger.logUnimplementedFeature(String.format("Get an abbreviation for AdvantageType value %s", advantage));
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupAction(ActionViewHolder holder, Trait action) {
|
|
||||||
if (action == null) {
|
|
||||||
if (holder.root != null) {
|
|
||||||
holder.root.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (holder.name != null) {
|
|
||||||
holder.name.setText(action.name);
|
|
||||||
}
|
|
||||||
if (holder.description != null) {
|
|
||||||
holder.description.setText(action.description);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ViewHolder {
|
private static class ViewHolder {
|
||||||
final GridLayout monsterCards;
|
final RecyclerView list;
|
||||||
final GridLayout monsterShortCards;
|
|
||||||
final GridLayout monsterTiles;
|
|
||||||
final GridLayout monsterShortTiles;
|
|
||||||
|
|
||||||
ViewHolder(View root) {
|
ViewHolder(View root) {
|
||||||
monsterCards = root.findViewById(R.id.monsterCards);
|
list = root.findViewById(R.id.list);
|
||||||
monsterShortCards = root.findViewById(R.id.monsterShortCards);
|
|
||||||
monsterTiles = root.findViewById(R.id.monsterTiles);
|
|
||||||
monsterShortTiles = root.findViewById(R.id.monsterShortTiles);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MonsterCardViewHolder {
|
|
||||||
final TextView name;
|
|
||||||
final TextView meta;
|
|
||||||
final TextView challengeRating;
|
|
||||||
final AttributeViewHolder strength;
|
|
||||||
final AttributeViewHolder dexterity;
|
|
||||||
final AttributeViewHolder constitution;
|
|
||||||
final AttributeViewHolder intelligence;
|
|
||||||
final AttributeViewHolder wisdom;
|
|
||||||
final AttributeViewHolder charisma;
|
|
||||||
final ArmorClassViewHolder armorClass;
|
|
||||||
final HitPointsViewHolder hitPoints;
|
|
||||||
final ActionViewHolder action1;
|
|
||||||
final ActionViewHolder action2;
|
|
||||||
final ActionViewHolder action3;
|
|
||||||
|
|
||||||
MonsterCardViewHolder(View root) {
|
|
||||||
name = root.findViewById(R.id.name);
|
|
||||||
meta = root.findViewById(R.id.meta);
|
|
||||||
challengeRating = root.findViewById(R.id.challengeRating);
|
|
||||||
strength = new AttributeViewHolder(root.findViewById(R.id.strength));
|
|
||||||
dexterity = new AttributeViewHolder(root.findViewById(R.id.dexterity));
|
|
||||||
constitution = new AttributeViewHolder(root.findViewById(R.id.constitution));
|
|
||||||
intelligence = new AttributeViewHolder(root.findViewById(R.id.intelligence));
|
|
||||||
wisdom = new AttributeViewHolder(root.findViewById(R.id.wisdom));
|
|
||||||
charisma = new AttributeViewHolder(root.findViewById(R.id.charisma));
|
|
||||||
armorClass = new ArmorClassViewHolder(root.findViewById(R.id.armorClass));
|
|
||||||
hitPoints = new HitPointsViewHolder(root.findViewById(R.id.hitPoints));
|
|
||||||
action1 = new ActionViewHolder(root.findViewById(R.id.action1));
|
|
||||||
action2 = new ActionViewHolder(root.findViewById(R.id.action2));
|
|
||||||
action3 = new ActionViewHolder(root.findViewById(R.id.action3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class MonsterTileViewHolder {
|
|
||||||
final TextView name;
|
|
||||||
final TextView meta;
|
|
||||||
final ArmorClassViewHolder armorClass;
|
|
||||||
final HitPointsViewHolder hitPoints;
|
|
||||||
final InitiativeViewHolder initiative;
|
|
||||||
final ChallengeRatingViewHolder challengeRating;
|
|
||||||
final ActionViewHolder action;
|
|
||||||
|
|
||||||
MonsterTileViewHolder(View root) {
|
|
||||||
name = root.findViewById(R.id.name);
|
|
||||||
meta = root.findViewById(R.id.meta);
|
|
||||||
armorClass = new ArmorClassViewHolder(root.findViewById(R.id.armorClass));
|
|
||||||
hitPoints = new HitPointsViewHolder(root.findViewById(R.id.hitPoints));
|
|
||||||
initiative = new InitiativeViewHolder(root.findViewById(R.id.initiative));
|
|
||||||
challengeRating = new ChallengeRatingViewHolder(root.findViewById(R.id.challengeRating));
|
|
||||||
action = new ActionViewHolder(root.findViewById(R.id.action));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ArmorClassViewHolder {
|
|
||||||
final TextView value;
|
|
||||||
|
|
||||||
ArmorClassViewHolder(View root) {
|
|
||||||
if (root == null) {
|
|
||||||
value = null;
|
|
||||||
} else {
|
|
||||||
value = root.findViewById(R.id.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class HitPointsViewHolder {
|
|
||||||
final TextView value;
|
|
||||||
|
|
||||||
HitPointsViewHolder(View root) {
|
|
||||||
if (root == null) {
|
|
||||||
value = null;
|
|
||||||
} else {
|
|
||||||
value = root.findViewById(R.id.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class InitiativeViewHolder {
|
|
||||||
final TextView value;
|
|
||||||
|
|
||||||
InitiativeViewHolder(View root) {
|
|
||||||
if (root == null) {
|
|
||||||
value = null;
|
|
||||||
} else {
|
|
||||||
value = root.findViewById(R.id.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ChallengeRatingViewHolder {
|
|
||||||
final TextView value;
|
|
||||||
|
|
||||||
ChallengeRatingViewHolder(View root) {
|
|
||||||
if (root == null) {
|
|
||||||
value = null;
|
|
||||||
} else {
|
|
||||||
value = root.findViewById(R.id.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class AttributeViewHolder {
|
|
||||||
final TextView name;
|
|
||||||
final TextView advantage;
|
|
||||||
final TextView proficiency;
|
|
||||||
final TextView modifier;
|
|
||||||
|
|
||||||
AttributeViewHolder(View root) {
|
|
||||||
if (root == null) {
|
|
||||||
name = null;
|
|
||||||
advantage = null;
|
|
||||||
proficiency = null;
|
|
||||||
modifier = null;
|
|
||||||
} else {
|
|
||||||
name = root.findViewById(R.id.name);
|
|
||||||
advantage = root.findViewById(R.id.advantage);
|
|
||||||
proficiency = root.findViewById(R.id.proficiency);
|
|
||||||
modifier = root.findViewById(R.id.modifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ActionViewHolder {
|
|
||||||
final TextView name;
|
|
||||||
final TextView description;
|
|
||||||
final View root;
|
|
||||||
|
|
||||||
ActionViewHolder(View root) {
|
|
||||||
this.root = root;
|
|
||||||
if (root == null) {
|
|
||||||
name = null;
|
|
||||||
description = null;
|
|
||||||
} else {
|
|
||||||
name = root.findViewById(R.id.name);
|
|
||||||
description = root.findViewById(R.id.description);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,348 @@
|
|||||||
|
package com.majinnaibu.monstercards.ui.dashboard;
|
||||||
|
|
||||||
|
import android.text.Html;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
|
import androidx.recyclerview.widget.ListAdapter;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.majinnaibu.monstercards.data.enums.AbilityScore;
|
||||||
|
import com.majinnaibu.monstercards.data.enums.AdvantageType;
|
||||||
|
import com.majinnaibu.monstercards.data.enums.ChallengeRating;
|
||||||
|
import com.majinnaibu.monstercards.data.enums.ProficiencyType;
|
||||||
|
import com.majinnaibu.monstercards.databinding.CardMonsterBinding;
|
||||||
|
import com.majinnaibu.monstercards.helpers.CommonMarkHelper;
|
||||||
|
import com.majinnaibu.monstercards.models.Monster;
|
||||||
|
import com.majinnaibu.monstercards.models.Trait;
|
||||||
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class DashboardRecyclerViewAdapter extends ListAdapter<Monster, DashboardRecyclerViewAdapter.ViewHolder> {
|
||||||
|
private static final DiffUtil.ItemCallback<Monster> DIFF_CALLBACK = new DiffUtil.ItemCallback<Monster>() {
|
||||||
|
@Override
|
||||||
|
public boolean areItemsTheSame(@NonNull @NotNull Monster oldItem, @NonNull @NotNull Monster newItem) {
|
||||||
|
return oldItem.id.equals(newItem.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areContentsTheSame(@NonNull @NotNull Monster oldItem, @NonNull @NotNull Monster newItem) {
|
||||||
|
return oldItem.equals(newItem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private final ItemCallback mOnClick;
|
||||||
|
|
||||||
|
protected DashboardRecyclerViewAdapter(ItemCallback onClick) {
|
||||||
|
super(DIFF_CALLBACK);
|
||||||
|
mOnClick = onClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
|
||||||
|
return new ViewHolder(CardMonsterBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull @NotNull ViewHolder holder, int position) {
|
||||||
|
Logger.logUnimplementedMethod();
|
||||||
|
Monster monster = getItem(position);
|
||||||
|
holder.monster = monster;
|
||||||
|
holder.name.setText(monster.name);
|
||||||
|
holder.meta.setText(monster.getMeta());
|
||||||
|
holder.strengthAdvantage.setText(Helpers.getAdvantageAbbreviation(monster.strengthSavingThrowAdvantage));
|
||||||
|
holder.strengthModifier.setText(Helpers.getModifierString(monster.getStrengthModifier()));
|
||||||
|
holder.strengthName.setText(Helpers.getAbilityScoreAbbreviation(AbilityScore.STRENGTH));
|
||||||
|
holder.strengthProficiency.setText(Helpers.getProficiencyAbbreviation(monster.strengthSavingThrowProficiency));
|
||||||
|
|
||||||
|
holder.dexterityAdvantage.setText(Helpers.getAdvantageAbbreviation(monster.dexteritySavingThrowAdvantage));
|
||||||
|
holder.dexterityModifier.setText(Helpers.getModifierString(monster.getDexterityModifier()));
|
||||||
|
holder.dexterityName.setText(Helpers.getAbilityScoreAbbreviation(AbilityScore.DEXTERITY));
|
||||||
|
holder.dexterityProficiency.setText(Helpers.getProficiencyAbbreviation(monster.dexteritySavingThrowProficiency));
|
||||||
|
|
||||||
|
holder.constitutionAdvantage.setText(Helpers.getAdvantageAbbreviation(monster.constitutionSavingThrowAdvantage));
|
||||||
|
holder.constitutionModifier.setText(Helpers.getModifierString(monster.getConstitutionModifier()));
|
||||||
|
holder.constitutionName.setText(Helpers.getAbilityScoreAbbreviation(AbilityScore.CONSTITUTION));
|
||||||
|
holder.constitutionProficiency.setText(Helpers.getProficiencyAbbreviation(monster.constitutionSavingThrowProficiency));
|
||||||
|
|
||||||
|
holder.intelligenceAdvantage.setText(Helpers.getAdvantageAbbreviation(monster.intelligenceSavingThrowAdvantage));
|
||||||
|
holder.intelligenceModifier.setText(Helpers.getModifierString(monster.getIntelligenceModifier()));
|
||||||
|
holder.intelligenceName.setText(Helpers.getAbilityScoreAbbreviation(AbilityScore.INTELLIGENCE));
|
||||||
|
holder.intelligenceProficiency.setText(Helpers.getProficiencyAbbreviation(monster.intelligenceSavingThrowProficiency));
|
||||||
|
|
||||||
|
holder.wisdomAdvantage.setText(Helpers.getAdvantageAbbreviation(monster.wisdomSavingThrowAdvantage));
|
||||||
|
holder.wisdomModifier.setText(Helpers.getModifierString(monster.getWisdomModifier()));
|
||||||
|
holder.wisdomName.setText(Helpers.getAbilityScoreAbbreviation(AbilityScore.WISDOM));
|
||||||
|
holder.wisdomProficiency.setText(Helpers.getProficiencyAbbreviation(monster.wisdomSavingThrowProficiency));
|
||||||
|
|
||||||
|
holder.charismaAdvantage.setText(Helpers.getAdvantageAbbreviation(monster.charismaSavingThrowAdvantage));
|
||||||
|
holder.charismaModifier.setText(Helpers.getModifierString(monster.getCharismaModifier()));
|
||||||
|
holder.charismaName.setText(Helpers.getAbilityScoreAbbreviation(AbilityScore.CHARISMA));
|
||||||
|
holder.charismaProficiency.setText(Helpers.getProficiencyAbbreviation(monster.charismaSavingThrowProficiency));
|
||||||
|
|
||||||
|
holder.armorClass.setText(String.valueOf(monster.getArmorClassValue()));
|
||||||
|
holder.hitPoints.setText(String.valueOf(monster.getHitPointsValue()));
|
||||||
|
holder.challengeRating.setText("CR " + Helpers.getChallengeRatingAbbreviation(monster.challengeRating));
|
||||||
|
|
||||||
|
int numActions = monster.actions.size();
|
||||||
|
if (numActions > 0) {
|
||||||
|
holder.action1Group.setVisibility(View.VISIBLE);
|
||||||
|
Trait action = monster.actions.get(0);
|
||||||
|
holder.action1Description.setText(Html.fromHtml(CommonMarkHelper.toHtml(action.description)));
|
||||||
|
holder.action1Name.setText(Html.fromHtml(CommonMarkHelper.toHtml(action.name)));
|
||||||
|
} else {
|
||||||
|
holder.action1Group.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numActions > 1) {
|
||||||
|
holder.action2Group.setVisibility(View.VISIBLE);
|
||||||
|
Trait action = monster.actions.get(1);
|
||||||
|
holder.action2Description.setText(Html.fromHtml(CommonMarkHelper.toHtml(action.description)));
|
||||||
|
holder.action2Name.setText(Html.fromHtml(CommonMarkHelper.toHtml(action.name)));
|
||||||
|
} else {
|
||||||
|
holder.action2Group.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numActions > 2) {
|
||||||
|
holder.action3Group.setVisibility(View.VISIBLE);
|
||||||
|
Trait action = monster.actions.get(2);
|
||||||
|
holder.action3Description.setText(Html.fromHtml(CommonMarkHelper.toHtml(action.description)));
|
||||||
|
holder.action3Name.setText(Html.fromHtml(CommonMarkHelper.toHtml(action.name)));
|
||||||
|
} else {
|
||||||
|
holder.action3Group.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(v -> {
|
||||||
|
if (mOnClick != null) {
|
||||||
|
mOnClick.onItemCallback(holder.monster);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ItemCallback {
|
||||||
|
void onItemCallback(Monster monster);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
public final TextView name;
|
||||||
|
public final TextView meta;
|
||||||
|
public final View action1Group;
|
||||||
|
public final TextView action1Name;
|
||||||
|
public final TextView action1Description;
|
||||||
|
public final View action2Group;
|
||||||
|
public final TextView action2Name;
|
||||||
|
public final TextView action2Description;
|
||||||
|
public final View action3Group;
|
||||||
|
public final TextView action3Name;
|
||||||
|
public final TextView action3Description;
|
||||||
|
public final TextView strengthName;
|
||||||
|
public final TextView strengthModifier;
|
||||||
|
public final TextView strengthProficiency;
|
||||||
|
public final TextView strengthAdvantage;
|
||||||
|
public final TextView dexterityName;
|
||||||
|
public final TextView dexterityModifier;
|
||||||
|
public final TextView dexterityProficiency;
|
||||||
|
public final TextView dexterityAdvantage;
|
||||||
|
public final TextView constitutionName;
|
||||||
|
public final TextView constitutionModifier;
|
||||||
|
public final TextView constitutionProficiency;
|
||||||
|
public final TextView constitutionAdvantage;
|
||||||
|
public final TextView intelligenceName;
|
||||||
|
public final TextView intelligenceModifier;
|
||||||
|
public final TextView intelligenceProficiency;
|
||||||
|
public final TextView intelligenceAdvantage;
|
||||||
|
public final TextView wisdomName;
|
||||||
|
public final TextView wisdomModifier;
|
||||||
|
public final TextView wisdomProficiency;
|
||||||
|
public final TextView wisdomAdvantage;
|
||||||
|
public final TextView charismaName;
|
||||||
|
public final TextView charismaModifier;
|
||||||
|
public final TextView charismaProficiency;
|
||||||
|
public final TextView charismaAdvantage;
|
||||||
|
public final TextView armorClass;
|
||||||
|
public final TextView hitPoints;
|
||||||
|
public final TextView challengeRating;
|
||||||
|
public Monster monster;
|
||||||
|
|
||||||
|
public ViewHolder(CardMonsterBinding binding) {
|
||||||
|
super(binding.getRoot());
|
||||||
|
name = binding.name;
|
||||||
|
meta = binding.meta;
|
||||||
|
action1Group = binding.action1.getRoot();
|
||||||
|
action1Name = binding.action1.name;
|
||||||
|
action1Description = binding.action1.description;
|
||||||
|
action2Group = binding.action2.getRoot();
|
||||||
|
action2Name = binding.action2.name;
|
||||||
|
action2Description = binding.action2.description;
|
||||||
|
action3Group = binding.action3.getRoot();
|
||||||
|
action3Name = binding.action3.name;
|
||||||
|
action3Description = binding.action3.description;
|
||||||
|
strengthName = binding.strength.name;
|
||||||
|
strengthModifier = binding.strength.modifier;
|
||||||
|
strengthProficiency = binding.strength.proficiency;
|
||||||
|
strengthAdvantage = binding.strength.advantage;
|
||||||
|
dexterityName = binding.dexterity.name;
|
||||||
|
dexterityModifier = binding.dexterity.modifier;
|
||||||
|
dexterityProficiency = binding.dexterity.proficiency;
|
||||||
|
dexterityAdvantage = binding.dexterity.advantage;
|
||||||
|
constitutionName = binding.constitution.name;
|
||||||
|
constitutionModifier = binding.constitution.modifier;
|
||||||
|
constitutionProficiency = binding.constitution.proficiency;
|
||||||
|
constitutionAdvantage = binding.constitution.advantage;
|
||||||
|
intelligenceName = binding.intelligence.name;
|
||||||
|
intelligenceModifier = binding.intelligence.modifier;
|
||||||
|
intelligenceProficiency = binding.intelligence.proficiency;
|
||||||
|
intelligenceAdvantage = binding.intelligence.advantage;
|
||||||
|
wisdomName = binding.wisdom.name;
|
||||||
|
wisdomModifier = binding.wisdom.modifier;
|
||||||
|
wisdomProficiency = binding.wisdom.proficiency;
|
||||||
|
wisdomAdvantage = binding.wisdom.advantage;
|
||||||
|
charismaName = binding.charisma.name;
|
||||||
|
charismaModifier = binding.charisma.modifier;
|
||||||
|
charismaProficiency = binding.charisma.proficiency;
|
||||||
|
charismaAdvantage = binding.charisma.advantage;
|
||||||
|
armorClass = binding.armorClass.value;
|
||||||
|
hitPoints = binding.hitPoints.value;
|
||||||
|
challengeRating = binding.challengeRating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Helpers {
|
||||||
|
public static String getModifierString(int value) {
|
||||||
|
return String.format("%+d", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAbilityScoreAbbreviation(AbilityScore abilityScore) {
|
||||||
|
switch (abilityScore) {
|
||||||
|
case STRENGTH:
|
||||||
|
return "S";
|
||||||
|
case DEXTERITY:
|
||||||
|
return "D";
|
||||||
|
case CONSTITUTION:
|
||||||
|
return "C";
|
||||||
|
case INTELLIGENCE:
|
||||||
|
return "I";
|
||||||
|
case WISDOM:
|
||||||
|
return "W";
|
||||||
|
case CHARISMA:
|
||||||
|
return "Ch";
|
||||||
|
default:
|
||||||
|
Logger.logUnimplementedFeature(String.format("Get an abbreviation for AbilityScore value %s", abilityScore));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getChallengeRatingAbbreviation(ChallengeRating challengeRating) {
|
||||||
|
Logger.logUnimplementedMethod();
|
||||||
|
switch (challengeRating) {
|
||||||
|
case CUSTOM:
|
||||||
|
return "*";
|
||||||
|
case ZERO:
|
||||||
|
return "0";
|
||||||
|
case ONE_EIGHTH:
|
||||||
|
return "1/8";
|
||||||
|
case ONE_QUARTER:
|
||||||
|
return "1/4";
|
||||||
|
case ONE_HALF:
|
||||||
|
return "1/2";
|
||||||
|
case ONE:
|
||||||
|
return "1";
|
||||||
|
case TWO:
|
||||||
|
return "2";
|
||||||
|
case THREE:
|
||||||
|
return "3";
|
||||||
|
case FOUR:
|
||||||
|
return "4";
|
||||||
|
case FIVE:
|
||||||
|
return "5";
|
||||||
|
case SIX:
|
||||||
|
return "6";
|
||||||
|
case SEVEN:
|
||||||
|
return "7";
|
||||||
|
case EIGHT:
|
||||||
|
return "8";
|
||||||
|
case NINE:
|
||||||
|
return "9";
|
||||||
|
case TEN:
|
||||||
|
return "10";
|
||||||
|
case ELEVEN:
|
||||||
|
return "11";
|
||||||
|
case TWELVE:
|
||||||
|
return "12";
|
||||||
|
case THIRTEEN:
|
||||||
|
return "13";
|
||||||
|
case FOURTEEN:
|
||||||
|
return "14";
|
||||||
|
case FIFTEEN:
|
||||||
|
return "15";
|
||||||
|
case SIXTEEN:
|
||||||
|
return "16";
|
||||||
|
case SEVENTEEN:
|
||||||
|
return "17";
|
||||||
|
case EIGHTEEN:
|
||||||
|
return "18";
|
||||||
|
case NINETEEN:
|
||||||
|
return "19";
|
||||||
|
case TWENTY:
|
||||||
|
return "20";
|
||||||
|
case TWENTY_ONE:
|
||||||
|
return "21";
|
||||||
|
case TWENTY_TWO:
|
||||||
|
return "22";
|
||||||
|
case TWENTY_THREE:
|
||||||
|
return "23";
|
||||||
|
case TWENTY_FOUR:
|
||||||
|
return "24";
|
||||||
|
case TWENTY_FIVE:
|
||||||
|
return "25";
|
||||||
|
case TWENTY_SIX:
|
||||||
|
return "26";
|
||||||
|
case TWENTY_SEVEN:
|
||||||
|
return "27";
|
||||||
|
case TWENTY_EIGHT:
|
||||||
|
return "28";
|
||||||
|
case TWENTY_NINE:
|
||||||
|
return "29";
|
||||||
|
case THIRTY:
|
||||||
|
return "30";
|
||||||
|
default:
|
||||||
|
Logger.logUnimplementedFeature(String.format("Get an abbreviation for ChallengeRating value %s", challengeRating));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getProficiencyAbbreviation(ProficiencyType proficiency) {
|
||||||
|
switch (proficiency) {
|
||||||
|
case NONE:
|
||||||
|
return "";
|
||||||
|
case EXPERTISE:
|
||||||
|
return "E";
|
||||||
|
case PROFICIENT:
|
||||||
|
return "P";
|
||||||
|
default:
|
||||||
|
Logger.logUnimplementedFeature(String.format("Get an abbreviation for ProficiencyType value %s", proficiency));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAdvantageAbbreviation(AdvantageType advantage) {
|
||||||
|
switch (advantage) {
|
||||||
|
case NONE:
|
||||||
|
return "";
|
||||||
|
case ADVANTAGE:
|
||||||
|
return "A";
|
||||||
|
case DISADVANTAGE:
|
||||||
|
return "D";
|
||||||
|
default:
|
||||||
|
Logger.logUnimplementedFeature(String.format("Get an abbreviation for AdvantageType value %s", advantage));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/text_margin"
|
||||||
android:background="@drawable/rectangle_background">
|
android:background="@drawable/rectangle_background">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -1,145 +1,21 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ui.dashboard.DashboardFragment">
|
tools:context=".ui.dashboard.DashboardFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_margin="8dp"
|
android:divider="?android:attr/dividerVertical"
|
||||||
android:orientation="vertical">
|
android:dividerPadding="@dimen/text_margin"
|
||||||
|
app:layoutManager="LinearLayoutManager"
|
||||||
<GridLayout
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:id="@+id/monsterCards"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:layout_width="match_parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
android:layout_height="wrap_content"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:columnCount="2">
|
tools:listitem="@layout/card_monster" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/card_monster"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/card_monster"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/card_monster"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/card_monster"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
</GridLayout>
|
|
||||||
|
|
||||||
<GridLayout
|
|
||||||
android:id="@+id/monsterShortCards"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:columnCount="2">
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/card_monster_short"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/card_monster_short"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/card_monster_short"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/card_monster_short"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
</GridLayout>
|
|
||||||
|
|
||||||
<GridLayout
|
|
||||||
android:id="@+id/monsterTiles"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:columnCount="2">
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/tile_monster"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/tile_monster"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp" />-->
|
|
||||||
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/tile_monster"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp"/>-->
|
|
||||||
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/tile_monster"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp" />-->
|
|
||||||
</GridLayout>
|
|
||||||
|
|
||||||
<GridLayout
|
|
||||||
android:id="@+id/monsterShortTiles"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:columnCount="2">
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/tile_monster_short"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp" />-->
|
|
||||||
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/tile_monster_short"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp" />-->
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/tile_monster_short"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp" />-->
|
|
||||||
|
|
||||||
<!-- <include-->
|
|
||||||
<!-- layout="@layout/tile_monster_short"-->
|
|
||||||
<!-- android:layout_width="0dp"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:layout_columnWeight="1"-->
|
|
||||||
<!-- android:layout_marginVertical="8dp" />-->
|
|
||||||
</GridLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
|
|||||||
42
app/src/main/res/layout/fragment_dashboard_list_item.xml
Normal file
42
app/src/main/res/layout/fragment_dashboard_list_item.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/text_margin"
|
||||||
|
android:textAppearance="?attr/textAppearanceListItem" />
|
||||||
|
|
||||||
|
<!-- <include-->
|
||||||
|
<!-- layout="@layout/card_monster"-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:layout_columnWeight="1"-->
|
||||||
|
<!-- android:layout_marginVertical="8dp"/>-->
|
||||||
|
|
||||||
|
<!-- <include-->
|
||||||
|
<!-- layout="@layout/card_monster_short"-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:layout_columnWeight="1"-->
|
||||||
|
<!-- android:layout_marginVertical="8dp"/>-->
|
||||||
|
|
||||||
|
<!-- <include-->
|
||||||
|
<!-- layout="@layout/tile_monster"-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:layout_columnWeight="1"-->
|
||||||
|
<!-- android:layout_marginVertical="8dp"/>-->
|
||||||
|
|
||||||
|
<!-- <include-->
|
||||||
|
<!-- layout="@layout/tile_monster_short"-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:layout_columnWeight="1"-->
|
||||||
|
<!-- android:layout_marginVertical="8dp" />-->
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
Reference in New Issue
Block a user