diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/components/AdvantagePicker.java b/app/src/main/java/com/majinnaibu/monstercards/ui/components/AdvantagePicker.java
new file mode 100644
index 0000000..0f341a6
--- /dev/null
+++ b/app/src/main/java/com/majinnaibu/monstercards/ui/components/AdvantagePicker.java
@@ -0,0 +1,98 @@
+package com.majinnaibu.monstercards.ui.components;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.google.android.material.radiobutton.MaterialRadioButton;
+import com.majinnaibu.monstercards.R;
+import com.majinnaibu.monstercards.data.enums.AdvantageType;
+
+@SuppressWarnings("unused")
+public class AdvantagePicker extends ConstraintLayout {
+ private final ViewHolder mHolder;
+ private OnValueChangedListener mOnValueChangedListener;
+ private AdvantageType mSelectedValue;
+
+ public AdvantagePicker(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+
+ mSelectedValue = AdvantageType.NONE;
+ mOnValueChangedListener = null;
+
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View root = inflater.inflate(R.layout.component_advantage_picker, this, true);
+
+ mHolder = new ViewHolder(root);
+
+ setValue(AdvantageType.NONE);
+ mHolder.group.setOnCheckedChangeListener((group, checkedId) -> {
+ if (R.id.advantage == checkedId) {
+ setValue(AdvantageType.ADVANTAGE);
+ } else if (R.id.disadvantage == checkedId) {
+ setValue(AdvantageType.DISADVANTAGE);
+ } else {
+ setValue(AdvantageType.NONE);
+ }
+ });
+ }
+
+ public AdvantagePicker(@NonNull Context context) {
+ this(context, null);
+ }
+
+ public AdvantageType getValue() {
+ return mSelectedValue;
+ }
+
+ public void setValue(AdvantageType value) {
+ if (mSelectedValue != value) {
+ mSelectedValue = value;
+ if (mOnValueChangedListener != null) {
+ mOnValueChangedListener.onValueChanged(mSelectedValue);
+ }
+ }
+ final int checkedId = mHolder.group.getCheckedRadioButtonId();
+ if (mSelectedValue == AdvantageType.ADVANTAGE) {
+ if (checkedId != R.id.advantage) {
+ mHolder.advantage.setChecked(true);
+ }
+ } else if (mSelectedValue == AdvantageType.DISADVANTAGE) {
+ if (checkedId != R.id.disadvantage) {
+ mHolder.disadvantage.setChecked(true);
+ }
+ } else {
+ if (checkedId != R.id.none) {
+ mHolder.none.setChecked(true);
+ }
+ }
+ }
+
+ public void setOnValueChangedListener(OnValueChangedListener listener) {
+ mOnValueChangedListener = listener;
+ }
+
+ public interface OnValueChangedListener {
+ void onValueChanged(AdvantageType value);
+ }
+
+ private static class ViewHolder {
+ final RadioGroup group;
+ final MaterialRadioButton none;
+ final MaterialRadioButton advantage;
+ final MaterialRadioButton disadvantage;
+
+ ViewHolder(View root) {
+ group = root.findViewById(R.id.group);
+ none = root.findViewById(R.id.none);
+ advantage = root.findViewById(R.id.advantage);
+ disadvantage = root.findViewById(R.id.disadvantage);
+ }
+ }
+}
diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/components/ProficiencyPicker.java b/app/src/main/java/com/majinnaibu/monstercards/ui/components/ProficiencyPicker.java
new file mode 100644
index 0000000..abba324
--- /dev/null
+++ b/app/src/main/java/com/majinnaibu/monstercards/ui/components/ProficiencyPicker.java
@@ -0,0 +1,98 @@
+package com.majinnaibu.monstercards.ui.components;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.google.android.material.radiobutton.MaterialRadioButton;
+import com.majinnaibu.monstercards.R;
+import com.majinnaibu.monstercards.data.enums.ProficiencyType;
+
+@SuppressWarnings("unused")
+public class ProficiencyPicker extends ConstraintLayout {
+ private final ViewHolder mHolder;
+ private OnValueChangedListener mOnValueChangedListener;
+ private ProficiencyType mSelectedValue;
+
+ public ProficiencyPicker(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+
+ mSelectedValue = ProficiencyType.NONE;
+ mOnValueChangedListener = null;
+
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View root = inflater.inflate(R.layout.component_proficiency_picker, this, true);
+
+ mHolder = new ViewHolder(root);
+
+ setValue(ProficiencyType.NONE);
+ mHolder.group.setOnCheckedChangeListener((group, checkedId) -> {
+ if (R.id.proficient == checkedId) {
+ setValue(ProficiencyType.PROFICIENT);
+ } else if (R.id.expertise == checkedId) {
+ setValue(ProficiencyType.EXPERTISE);
+ } else {
+ setValue(ProficiencyType.NONE);
+ }
+ });
+ }
+
+ public ProficiencyPicker(@NonNull Context context) {
+ this(context, null);
+ }
+
+ public ProficiencyType getValue() {
+ return mSelectedValue;
+ }
+
+ public void setValue(ProficiencyType value) {
+ if (mSelectedValue != value) {
+ mSelectedValue = value;
+ if (mOnValueChangedListener != null) {
+ mOnValueChangedListener.onValueChanged(mSelectedValue);
+ }
+ }
+ final int checkedId = mHolder.group.getCheckedRadioButtonId();
+ if (mSelectedValue == ProficiencyType.PROFICIENT) {
+ if (checkedId != R.id.proficient) {
+ mHolder.proficient.setChecked(true);
+ }
+ } else if (mSelectedValue == ProficiencyType.EXPERTISE) {
+ if (checkedId != R.id.expertise) {
+ mHolder.expertise.setChecked(true);
+ }
+ } else {
+ if (checkedId != R.id.none) {
+ mHolder.none.setChecked(true);
+ }
+ }
+ }
+
+ public void setOnValueChangedListener(OnValueChangedListener listener) {
+ mOnValueChangedListener = listener;
+ }
+
+ public interface OnValueChangedListener {
+ void onValueChanged(ProficiencyType value);
+ }
+
+ private static class ViewHolder {
+ final RadioGroup group;
+ final MaterialRadioButton none;
+ final MaterialRadioButton proficient;
+ final MaterialRadioButton expertise;
+
+ ViewHolder(View root) {
+ group = root.findViewById(R.id.group);
+ none = root.findViewById(R.id.none);
+ proficient = root.findViewById(R.id.proficient);
+ expertise = root.findViewById(R.id.expertise);
+ }
+ }
+}
diff --git a/app/src/main/res/layout/component_advantage_picker.xml b/app/src/main/res/layout/component_advantage_picker.xml
new file mode 100644
index 0000000..a3ee953
--- /dev/null
+++ b/app/src/main/res/layout/component_advantage_picker.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/component_proficiency_picker.xml b/app/src/main/res/layout/component_proficiency_picker.xml
new file mode 100644
index 0000000..bda8251
--- /dev/null
+++ b/app/src/main/res/layout/component_proficiency_picker.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7932fdb..52485b3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -12,6 +12,10 @@
Ability Scores
Abilities
Actions
+ Advantage
+ Advantage
+ Disadvantage
+ None
Alignment
Armor
Base Speed
@@ -42,6 +46,10 @@
Legendary Actions
Natural Armor Bonus
Name
+ Proficiency
+ Expertise
+ None
+ Proficient
Reactions
Regional Actions
Saving Throws