Adds a Stepper control and uses it for the steppers in the editor.

This commit is contained in:
2021-05-30 03:40:30 -07:00
parent 5a94408f7b
commit aa850ecfc6
8 changed files with 329 additions and 528 deletions

View File

@@ -0,0 +1,144 @@
package com.majinnaibu.monstercards.ui.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.majinnaibu.monstercards.R;
import com.majinnaibu.monstercards.utils.Logger;
import java.util.Objects;
public class Stepper extends ConstraintLayout {
private final ViewHolder mHolder;
private int mCurrentValue;
private int mStep;
private int mMinValue;
private int mMaxValue;
private String mLabel;
private OnValueChangeListener mOnValueChangeListener;
private OnFormatValueCallback mOnFormatValueCallback;
public Stepper(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mCurrentValue = 0;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Stepper, 0, 0);
mStep = a.getInt(R.styleable.Stepper_stepAmount, 1);
mMinValue = a.getInt(R.styleable.Stepper_minValue, Integer.MIN_VALUE);
mMaxValue = a.getInt(R.styleable.Stepper_maxValue, Integer.MAX_VALUE);
mLabel = a.getString(R.styleable.Stepper_label);
a.recycle();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View root = inflater.inflate(R.layout.component_stepper, this, true);
mHolder = new ViewHolder(root);
setValue(mCurrentValue);
mHolder.increment.setOnClickListener(v -> setValue(mCurrentValue + mStep));
mHolder.decrement.setOnClickListener(v -> setValue(mCurrentValue - mStep));
mHolder.label.setText(mLabel);
}
public Stepper(Context context) {
this(context, null);
}
public String getLabel() {
return mLabel;
}
public void setLabel(String newLabel) {
if (!Objects.equals(mLabel, newLabel)) {
mLabel = newLabel;
mHolder.label.setText(mLabel);
}
}
public int getValue() {
return mCurrentValue;
}
public void setValue(int value) {
int oldValue = this.mCurrentValue;
int newValue = Math.min(mMaxValue, Math.max(mMinValue, value));
Logger.logDebug(String.format("Setting stepper value value: %d, oldValue: %d, newValue: %d", value, oldValue, newValue));
if (newValue != oldValue) {
this.mCurrentValue = newValue;
if (mOnValueChangeListener != null) {
mOnValueChangeListener.onChange(newValue, oldValue);
}
if (mOnFormatValueCallback != null) {
mHolder.text.setText(mOnFormatValueCallback.onFormatValue(this.mCurrentValue));
} else {
mHolder.text.setText(String.valueOf(this.mCurrentValue));
}
}
}
public void setOnValueChangeListener(OnValueChangeListener listener) {
mOnValueChangeListener = listener;
}
public void setOnFormatValueCallback(OnFormatValueCallback callback) {
mOnFormatValueCallback = callback;
}
public int getStep() {
return mStep;
}
public void setStep(int step) {
this.mStep = step;
}
public int getMinValue() {
return mMinValue;
}
public void setMinValue(int minValue) {
this.mMinValue = minValue;
}
public int getMaxValue() {
return mMaxValue;
}
public void setMaxValue(int maxValue) {
this.mMaxValue = maxValue;
}
public interface OnValueChangeListener {
void onChange(int value, int previousValue);
}
public interface OnFormatValueCallback {
String onFormatValue(int value);
}
private static class ViewHolder {
final TextView text;
final TextView label;
final Button increment;
final Button decrement;
ViewHolder(View root) {
text = root.findViewById(R.id.text);
label = root.findViewById(R.id.label);
increment = root.findViewById(R.id.increment);
decrement = root.findViewById(R.id.decrement);
}
}
}

View File

@@ -4,8 +4,6 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
@@ -14,11 +12,17 @@ import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import com.majinnaibu.monstercards.R;
import com.majinnaibu.monstercards.ui.components.Stepper;
public class EditAbilityScoresFragment extends Fragment {
private final String ABILITY_SCORE_FORMAT = "%d (%+d)";
private EditMonsterViewModel mViewModel;
private ViewHolder mHolder;
private int getModifier(int value) {
return value / 2 - 5;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -31,72 +35,48 @@ public class EditAbilityScoresFragment extends Fragment {
mHolder = new ViewHolder(root);
mViewModel.getStrength().observe(getViewLifecycleOwner(), value -> mHolder.strength.setText(String.valueOf(value)));
mHolder.increaseStrength.setOnClickListener(v -> mViewModel.incrementStrength());
mHolder.decreaseStrength.setOnClickListener(v -> mViewModel.decrementStrength());
mViewModel.getStrength().observe(getViewLifecycleOwner(), value -> mHolder.strength.setValue(value));
mHolder.strength.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setStrength(newValue));
mHolder.strength.setOnFormatValueCallback(value -> String.format(ABILITY_SCORE_FORMAT, value, getModifier(value)));
mViewModel.getDexterity().observe(getViewLifecycleOwner(), value -> mHolder.dexterity.setText(String.valueOf(value)));
mHolder.increaseDexterity.setOnClickListener(v -> mViewModel.incrementDexterity());
mHolder.decreaseDexterity.setOnClickListener(v -> mViewModel.decrementDexterity());
mViewModel.getDexterity().observe(getViewLifecycleOwner(), value -> mHolder.dexterity.setValue(value));
mHolder.dexterity.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setDexterity(newValue));
mHolder.dexterity.setOnFormatValueCallback(value -> String.format(ABILITY_SCORE_FORMAT, value, getModifier(value)));
mViewModel.getConstitution().observe(getViewLifecycleOwner(), value -> mHolder.constitution.setText(String.valueOf(value)));
mHolder.increaseConstitution.setOnClickListener(v -> mViewModel.incrementConstitution());
mHolder.decreaseConstitution.setOnClickListener(v -> mViewModel.decrementConstitution());
mViewModel.getConstitution().observe(getViewLifecycleOwner(), value -> mHolder.constitution.setValue(value));
mHolder.constitution.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setConstitution(newValue));
mHolder.constitution.setOnFormatValueCallback(value -> String.format(ABILITY_SCORE_FORMAT, value, getModifier(value)));
mViewModel.getIntelligence().observe(getViewLifecycleOwner(), value -> mHolder.intelligence.setText(String.valueOf(value)));
mHolder.increaseIntelligence.setOnClickListener(v -> mViewModel.incrementIntelligence());
mHolder.decreaseIntelligence.setOnClickListener(v -> mViewModel.decrementIntelligence());
mViewModel.getIntelligence().observe(getViewLifecycleOwner(), value -> mHolder.intelligence.setValue(value));
mHolder.intelligence.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setIntelligence(newValue));
mHolder.intelligence.setOnFormatValueCallback(value -> String.format(ABILITY_SCORE_FORMAT, value, getModifier(value)));
mViewModel.getWisdom().observe(getViewLifecycleOwner(), value -> mHolder.wisdom.setText(String.valueOf(value)));
mHolder.increaseWisdom.setOnClickListener(v -> mViewModel.incrementWisdom());
mHolder.decreaseWisdom.setOnClickListener(v -> mViewModel.decrementWisdom());
mViewModel.getWisdom().observe(getViewLifecycleOwner(), value -> mHolder.wisdom.setValue(value));
mHolder.wisdom.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setWisdom(newValue));
mHolder.wisdom.setOnFormatValueCallback(value -> String.format(ABILITY_SCORE_FORMAT, value, getModifier(value)));
mViewModel.getCharisma().observe(getViewLifecycleOwner(), value -> mHolder.charisma.setText(String.valueOf(value)));
mHolder.increaseCharisma.setOnClickListener(v -> mViewModel.incrementCharisma());
mHolder.decreaseCharisma.setOnClickListener(v -> mViewModel.decrementCharisma());
mViewModel.getCharisma().observe(getViewLifecycleOwner(), value -> mHolder.charisma.setValue(value));
mHolder.charisma.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setCharisma(newValue));
mHolder.charisma.setOnFormatValueCallback(value -> String.format(ABILITY_SCORE_FORMAT, value, getModifier(value)));
return root;
}
private static class ViewHolder {
TextView strength;
Button decreaseStrength;
Button increaseStrength;
TextView dexterity;
Button increaseDexterity;
Button decreaseDexterity;
TextView constitution;
Button increaseConstitution;
Button decreaseConstitution;
TextView intelligence;
Button increaseIntelligence;
Button decreaseIntelligence;
TextView wisdom;
Button increaseWisdom;
Button decreaseWisdom;
TextView charisma;
Button increaseCharisma;
Button decreaseCharisma;
final Stepper strength;
final Stepper dexterity;
final Stepper constitution;
final Stepper intelligence;
final Stepper wisdom;
final Stepper charisma;
ViewHolder(View root) {
strength = root.findViewById(R.id.strength);
increaseStrength = root.findViewById(R.id.strength_increment);
decreaseStrength = root.findViewById(R.id.strength_decrement);
dexterity = root.findViewById(R.id.dexterity);
increaseDexterity = root.findViewById(R.id.dexterity_increment);
decreaseDexterity = root.findViewById(R.id.dexterity_decrement);
constitution = root.findViewById(R.id.constitution);
increaseConstitution = root.findViewById(R.id.constitution_increment);
decreaseConstitution = root.findViewById(R.id.constitution_decrement);
intelligence = root.findViewById(R.id.intelligence);
increaseIntelligence = root.findViewById(R.id.intelligence_increment);
decreaseIntelligence = root.findViewById(R.id.intelligence_decrement);
wisdom = root.findViewById(R.id.wisdom);
increaseWisdom = root.findViewById(R.id.wisdom_increment);
decreaseWisdom = root.findViewById(R.id.wisdom_decrement);
charisma = root.findViewById(R.id.charisma);
increaseCharisma = root.findViewById(R.id.charisma_increment);
decreaseCharisma = root.findViewById(R.id.charisma_decrement);
}
}
}

View File

@@ -4,9 +4,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.Fragment;
@@ -16,6 +14,7 @@ import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import com.majinnaibu.monstercards.R;
import com.majinnaibu.monstercards.ui.components.Stepper;
import com.majinnaibu.monstercards.utils.TextChangedListener;
public class EditSpeedFragment extends Fragment {
@@ -34,29 +33,25 @@ public class EditSpeedFragment extends Fragment {
mHolder = new ViewHolder(root);
mViewModel.getWalkSpeed().observe(getViewLifecycleOwner(), value -> {
mHolder.baseSpeed.setText(String.format(getString(R.string.format_distance_in_feet), value));
});
mHolder.incrementBaseSpeed.setOnClickListener(v -> mViewModel.incrementWalkSpeed());
mHolder.decrementBaseSpeed.setOnClickListener(v -> mViewModel.decrementWalkSpeed());
mHolder.baseSpeed.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setWalkSpeed(newValue));
mHolder.baseSpeed.setOnFormatValueCallback(value -> String.format(getString(R.string.format_distance_in_feet), value));
mViewModel.getWalkSpeed().observe(getViewLifecycleOwner(), value -> mHolder.baseSpeed.setValue(value));
mViewModel.getBurrowSpeed().observe(getViewLifecycleOwner(), value -> {
mHolder.burrowSpeed.setText(String.format(getString(R.string.format_distance_in_feet), value));
});
mHolder.incrementBurrowSpeed.setOnClickListener(v -> mViewModel.incrementBurrowSpeed());
mHolder.decrementBurrowSpeed.setOnClickListener(v -> mViewModel.decrementBurrowSpeed());
mHolder.burrowSpeed.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setBurrowSpeed(newValue));
mHolder.burrowSpeed.setOnFormatValueCallback(value -> String.format(getString(R.string.format_distance_in_feet), value));
mViewModel.getBurrowSpeed().observe(getViewLifecycleOwner(), value -> mHolder.burrowSpeed.setValue(value));
mViewModel.getClimbSpeed().observe(getViewLifecycleOwner(), value -> mHolder.climbSpeed.setText(String.format(getString(R.string.format_distance_in_feet), value)));
mHolder.incrementClimbSpeed.setOnClickListener(v -> mViewModel.incrementClimbSpeed());
mHolder.decrementBurrowSpeed.setOnClickListener(v -> mViewModel.decrementClimbSpeed());
mHolder.climbSpeed.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setClimbSpeed(newValue));
mHolder.climbSpeed.setOnFormatValueCallback(value -> String.format(getString(R.string.format_distance_in_feet), value));
mViewModel.getClimbSpeed().observe(getViewLifecycleOwner(), value -> mHolder.climbSpeed.setValue(value));
mViewModel.getFlySpeed().observe(getViewLifecycleOwner(), value -> mHolder.flySpeed.setText(String.format(getString(R.string.format_distance_in_feet), value)));
mHolder.incrementFlySpeed.setOnClickListener(v -> mViewModel.incrementFlySpeed());
mHolder.decrementBurrowSpeed.setOnClickListener(v -> mViewModel.decrementFlySpeed());
mHolder.flySpeed.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setFlySpeed(newValue));
mHolder.flySpeed.setOnFormatValueCallback(value -> String.format(getString(R.string.format_distance_in_feet), value));
mViewModel.getFlySpeed().observe(getViewLifecycleOwner(), value -> mHolder.flySpeed.setValue(value));
mViewModel.getSwimSpeed().observe(getViewLifecycleOwner(), value -> mHolder.swimSpeed.setText(String.format(getString(R.string.format_distance_in_feet), value)));
mHolder.incrementSwimSpeed.setOnClickListener(v -> mViewModel.incrementSwimSpeed());
mHolder.decrementBurrowSpeed.setOnClickListener(v -> mViewModel.decrementSwimSpeed());
mHolder.swimSpeed.setOnValueChangeListener((newValue, oldValue) -> mViewModel.setSwimSpeed(newValue));
mHolder.swimSpeed.setOnFormatValueCallback(value -> String.format(getString(R.string.format_distance_in_feet), value));
mViewModel.getSwimSpeed().observe(getViewLifecycleOwner(), value -> mHolder.swimSpeed.setValue(value));
mViewModel.getCanHover().observe(getViewLifecycleOwner(), value -> mHolder.canHover.setChecked(value));
mHolder.canHover.setOnCheckedChangeListener((buttonView, isChecked) -> mViewModel.setCanHover(isChecked));
@@ -73,41 +68,21 @@ public class EditSpeedFragment extends Fragment {
private static class ViewHolder {
final TextView baseSpeed;
final Button incrementBaseSpeed;
final Button decrementBaseSpeed;
final TextView burrowSpeed;
final Button incrementBurrowSpeed;
final Button decrementBurrowSpeed;
final TextView climbSpeed;
final Button incrementClimbSpeed;
final Button decrementClimbSpeed;
final TextView flySpeed;
final Button incrementFlySpeed;
final Button decrementFlySpeed;
final TextView swimSpeed;
final Button incrementSwimSpeed;
final Button decrementSwimSpeed;
final Stepper baseSpeed;
final Stepper burrowSpeed;
final Stepper climbSpeed;
final Stepper flySpeed;
final Stepper swimSpeed;
final SwitchCompat canHover;
final SwitchCompat hasCustomSpeed;
final EditText customSpeed;
ViewHolder(View root) {
baseSpeed = root.findViewById(R.id.baseSpeed);
incrementBaseSpeed = root.findViewById(R.id.baseSpeed_increment);
decrementBaseSpeed = root.findViewById(R.id.baseSpeed_decrement);
burrowSpeed = root.findViewById(R.id.burrowSpeed);
incrementBurrowSpeed = root.findViewById(R.id.burrowSpeed_increment);
decrementBurrowSpeed = root.findViewById(R.id.burrowSpeed_decrement);
climbSpeed = root.findViewById(R.id.climbSpeed);
incrementClimbSpeed = root.findViewById(R.id.climbSpeed_increment);
decrementClimbSpeed = root.findViewById(R.id.climbSpeed_decrement);
flySpeed = root.findViewById(R.id.flySpeed);
incrementFlySpeed = root.findViewById(R.id.flySpeed_increment);
decrementFlySpeed = root.findViewById(R.id.flySpeed_decrement);
swimSpeed = root.findViewById(R.id.swimSpeed);
incrementSwimSpeed = root.findViewById(R.id.swimSpeed_increment);
decrementSwimSpeed = root.findViewById(R.id.swimSpeed_decrement);
canHover = root.findViewById(R.id.canHover);
hasCustomSpeed = root.findViewById(R.id.hasCustomSpeed);
customSpeed = root.findViewById(R.id.customSpeed);