From 1df7928da1f0304d8ac7a82217e2d152fceefcff Mon Sep 17 00:00:00 2001 From: Michael Mikovsky <77305074+Astatin3@users.noreply.github.com> Date: Sun, 16 Feb 2025 23:31:27 -0700 Subject: [PATCH 1/9] New background, stuff with dropdowns --- app/build.gradle.kts | 1 + .../ridgescout/ui/CustomSpinner.java | 80 +++ .../ui/CustomSpinnerOptionsAdapter.java | 56 ++ .../ui/settings/settingsFragment.java | 517 ++++++++++++++++-- .../ridgescout/utility/settingsManager.java | 10 +- app/src/main/res/drawable/background.png | Bin 0 -> 570 bytes .../main/res/drawable/background_repeat.xml | 4 + app/src/main/res/layout/activity_main.xml | 14 +- app/src/main/res/layout/fragment_transfer.xml | 10 +- .../main/res/layout/view_custom_spinner.xml | 25 + .../res/layout/view_custom_spinner_option.xml | 19 + app/src/main/res/values/themes.xml | 10 + gradle/libs.versions.toml | 2 + 13 files changed, 675 insertions(+), 73 deletions(-) create mode 100644 app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinner.java create mode 100644 app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinnerOptionsAdapter.java create mode 100644 app/src/main/res/drawable/background.png create mode 100644 app/src/main/res/drawable/background_repeat.xml create mode 100644 app/src/main/res/layout/view_custom_spinner.xml create mode 100644 app/src/main/res/layout/view_custom_spinner_option.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1ca5e10..9e39054 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -56,6 +56,7 @@ dependencies { implementation(libs.appcompat) implementation(libs.material) + implementation(libs.material3) implementation(libs.constraintlayout) implementation(libs.lifecycle.livedata.ktx) implementation(libs.lifecycle.viewmodel.ktx) diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinner.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinner.java new file mode 100644 index 0000000..ae17044 --- /dev/null +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinner.java @@ -0,0 +1,80 @@ +package com.ridgebotics.ridgescout.ui; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.MaterialToolbar; +import com.ridgebotics.ridgescout.R; + +import java.util.ArrayList; +import java.util.List; + +public class CustomSpinner extends DialogFragment { + private List options; + private OnOptionSelectedListener listener; + private RecyclerView recyclerView; + private CustomSpinnerOptionsAdapter adapter; + + public interface OnOptionSelectedListener { + void onOptionSelected(String option); + } + + public static CustomSpinner newInstance(ArrayList options) { + CustomSpinner dialog = new CustomSpinner(); + Bundle args = new Bundle(); + args.putStringArrayList("options", options); + dialog.setArguments(args); + return dialog; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(DialogFragment.STYLE_NORMAL, R.style.FullScreenDialogStyle); + if (getArguments() != null) { + options = getArguments().getStringArrayList("options"); + } + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.view_custom_spinner, container, false); + + // Setup toolbar + MaterialToolbar toolbar = view.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(v -> dismiss()); + toolbar.setTitle("Select an Option"); + + // Setup RecyclerView + recyclerView = view.findViewById(R.id.recyclerView); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + adapter = new CustomSpinnerOptionsAdapter(options, option -> { + if (listener != null) { + listener.onOptionSelected(option); + } + dismiss(); + }); + recyclerView.setAdapter(adapter); + + return view; + } + + public void setOnOptionSelectedListener(OnOptionSelectedListener listener) { + this.listener = listener; + } + + + +} + diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinnerOptionsAdapter.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinnerOptionsAdapter.java new file mode 100644 index 0000000..5cffbb1 --- /dev/null +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinnerOptionsAdapter.java @@ -0,0 +1,56 @@ +package com.ridgebotics.ridgescout.ui; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.ridgebotics.ridgescout.R; + +import java.util.List; + +public class CustomSpinnerOptionsAdapter extends RecyclerView.Adapter { + private List options; + private OnItemClickListener listener; + + public interface OnItemClickListener { + void onItemClick(String option); + } + + public CustomSpinnerOptionsAdapter(List options, OnItemClickListener listener) { + this.options = options; + this.listener = listener; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.view_custom_spinner_option, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + String option = options.get(position); + holder.textView.setText(option); + holder.itemView.setOnClickListener(v -> listener.onItemClick(option)); + } + + @Override + public int getItemCount() { + return options.size(); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + TextView textView; + + ViewHolder(View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.textView); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/settings/settingsFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/settings/settingsFragment.java index 7671f18..84392be 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/settings/settingsFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/settings/settingsFragment.java @@ -6,7 +6,6 @@ import static com.ridgebotics.ridgescout.utility.settingsManager.FTPEnabled; import static com.ridgebotics.ridgescout.utility.settingsManager.FTPSendMetaFiles; import static com.ridgebotics.ridgescout.utility.settingsManager.FTPServer; import static com.ridgebotics.ridgescout.utility.settingsManager.SelEVCodeKey; -import static com.ridgebotics.ridgescout.utility.settingsManager.TeamNumKey; import static com.ridgebotics.ridgescout.utility.settingsManager.UnameKey; import static com.ridgebotics.ridgescout.utility.settingsManager.WifiModeKey; import static com.ridgebotics.ridgescout.utility.settingsManager.defaults; @@ -14,18 +13,25 @@ import static com.ridgebotics.ridgescout.utility.settingsManager.getEditor; import static com.ridgebotics.ridgescout.utility.settingsManager.prefs; import android.app.AlertDialog; +import android.content.Context; +import android.health.connect.datatypes.units.Power; import android.os.Bundle; import android.text.Editable; +import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; +import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; +import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TableRow; import android.widget.TextView; @@ -33,10 +39,17 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import com.google.android.material.card.MaterialCardView; +import com.google.android.material.checkbox.MaterialCheckBox; import com.google.android.material.divider.MaterialDivider; +import com.google.android.material.textfield.MaterialAutoCompleteTextView; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; import com.ridgebotics.ridgescout.databinding.FragmentSettingsBinding; import com.ridgebotics.ridgescout.types.data.intType; +import com.ridgebotics.ridgescout.ui.CustomSpinner; import com.ridgebotics.ridgescout.utility.fileEditor; import com.ridgebotics.ridgescout.utility.settingsManager; @@ -47,9 +60,11 @@ import com.skydoves.powerspinner.PowerSpinnerView; import com.skydoves.powerspinner.SpinnerGravity; import org.checkerframework.checker.units.qual.C; +import org.w3c.dom.Text; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.stream.Stream; @@ -137,64 +152,136 @@ public class settingsFragment extends Fragment { return concatArrays(heading, new View[]{et}); } - private PowerSpinnerView addDropdownEdit(String name, String[] options, String key){ - PowerSpinnerView dropdown = new PowerSpinnerView(getContext()); + private TextInputLayout addDropdownEdit(String name, String[] options, String key){ - List iconSpinnerItems = new ArrayList<>(); - for(int i = 0; i < options.length; i++){ - iconSpinnerItems.add(new IconSpinnerItem(options[i])); - } - IconSpinnerAdapter iconSpinnerAdapter = new IconSpinnerAdapter(dropdown); + int padding = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + 16, + getResources().getDisplayMetrics() + ); - dropdown.setGravity(Gravity.CENTER); + // Create TextInputLayout + TextInputLayout textInputLayout = new TextInputLayout(getContext(), null, + com.google.android.material.R.style.Widget_MaterialComponents_TextInputLayout_OutlinedBox_ExposedDropdownMenu); + LinearLayout.LayoutParams inputLayoutParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ); + textInputLayout.setLayoutParams(inputLayoutParams); + textInputLayout.setHint("Select an item"); - dropdown.setSpinnerAdapter(iconSpinnerAdapter); - dropdown.setItems(iconSpinnerItems); - dropdown.setHint("Unselected"); + // Create MaterialAutoCompleteTextView + MaterialAutoCompleteTextView dropdownText = new MaterialAutoCompleteTextView(getContext()); + TextInputLayout.LayoutParams dropdownParams = new TextInputLayout.LayoutParams( + TextInputLayout.LayoutParams.MATCH_PARENT, + TextInputLayout.LayoutParams.WRAP_CONTENT + ); + dropdownText.setLayoutParams(dropdownParams); + dropdownText.setInputType(InputType.TYPE_NULL); - dropdown.setPadding(10,20,10,20); - dropdown.setBackgroundColor(0xf0000000); - dropdown.setTextColor(0xff00ff00); - dropdown.setTextSize(14.5f); - dropdown.setArrowGravity(SpinnerGravity.END); - dropdown.setArrowPadding(8); - dropdown.setSpinnerPopupElevation(14); + textInputLayout.addView(dropdownText); - return dropdown; + + // Create item layout programmatically + TextView itemView = new TextView(getContext()); + LinearLayout.LayoutParams itemParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ); + itemView.setLayoutParams(itemParams); + itemView.setPadding(10, padding, padding, padding); + itemView.setMaxLines(1); + itemView.setEllipsize(TextUtils.TruncateAt.END); + itemView.setTextAppearance(com.google.android.material.R.style.TextAppearance_MaterialComponents_Subtitle1); + + // Create and set adapter + ArrayAdapter adapter = new ArrayAdapter( + getContext(), + android.R.layout.simple_dropdown_item_1line, + options + ) { + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + TextView textView = (TextView) super.getView(position, convertView, parent); + // Apply the same styling as our programmatic item layout + textView.setPadding(padding, padding, padding, padding); + textView.setMaxLines(1); + textView.setEllipsize(TextUtils.TruncateAt.END); + textView.setTextAppearance(com.google.android.material.R.style.TextAppearance_MaterialComponents_Subtitle1); + return textView; + } + }; + + +// +// +// +// +// + +// PowerSpinnerView dropdown = new PowerSpinnerView(getContext()); +// +// List iconSpinnerItems = new ArrayList<>(); +// for(int i = 0; i < options.length; i++){ +// iconSpinnerItems.add(new IconSpinnerItem(options[i])); +// } +// IconSpinnerAdapter iconSpinnerAdapter = new IconSpinnerAdapter(dropdown); +// +// dropdown.setGravity(Gravity.CENTER); +// +// dropdown.setSpinnerAdapter(iconSpinnerAdapter); +// dropdown.setItems(iconSpinnerItems); +// dropdown.setHint("Unselected"); +// +// dropdown.setPadding(10,20,10,20); +// dropdown.setBackgroundColor(0xf0000000); +// dropdown.setTextColor(0xff00ff00); +// dropdown.setTextSize(14.5f); +// dropdown.setArrowGravity(SpinnerGravity.END); +// dropdown.setArrowPadding(8); +// dropdown.setSpinnerPopupElevation(14); + + return textInputLayout; } private View[] addDropdownByString(String name, String[] options, String key){ View[] heading = createHeading(name); - PowerSpinnerView dropdown = addDropdownEdit(name, options, key); + TextInputLayout dropdown = addDropdownEdit(name, options, key); int index = Arrays.asList(options).indexOf(prefs.getString(key, (String) defaults.get(key))); System.out.println(index); - if(options.length != 0 && index != -1){ - dropdown.selectItemByIndex(index); - } - dropdown.setOnSpinnerItemSelectedListener( - (OnSpinnerItemSelectedListener) - (oldIndex, oldItem, newIndex, newItem) -> getEditor().putString(key, newItem.getText().toString()).apply() - ); +// dropdown.setOnSpinnerItemSelectedListener( +// (OnSpinnerItemSelectedListener) +// (oldIndex, oldItem, newIndex, newItem) -> getEditor().putString(key, newItem.getText().toString()).apply() +// ); return concatArrays(heading, new View[]{dropdown}); } - private View[] addDropdownByIndex(String name, String[] options, String key){ + private View[] addDropdownByIndex(String name, String[] options, String key){ View[] heading = createHeading(name); - PowerSpinnerView dropdown = addDropdownEdit(name, options, key); + TextInputLayout dropdown = addDropdownEdit(name, options, key); int index = prefs.getInt(key, (Integer) defaults.get(key)); - if(dropdown.length() != 0 && index != -1){ - dropdown.selectItemByIndex(index); - } - - dropdown.setOnSpinnerItemSelectedListener( - (OnSpinnerItemSelectedListener) - (oldIndex, oldItem, newIndex, newItem) -> getEditor().putInt(key, newIndex).apply() - ); +// if(dropdown.length() != 0 && index != -1){ +// dropdown.selectItemByIndex(index); +// } +// +// dropdown.setOnSpinnerItemSelectedListener( +// (OnSpinnerItemSelectedListener) +// (oldIndex, oldItem, newIndex, newItem) -> getEditor().putInt(key, newIndex).apply() +// ); return concatArrays(heading, new View[]{dropdown}); } @@ -234,20 +321,36 @@ public class settingsFragment extends Fragment { String[] alliance_pos_list = new String[]{"red-1", "red-2", "red-3", "blue-1", "blue-2", "blue-3"}; - addViews(addStringEdit("Username", UnameKey)); - addViews(addDropdownByString("Event Code", fileEditor.getEventList().toArray(new String[0]), SelEVCodeKey)); - addViews(addDropdownByString("Alliance Position", alliance_pos_list, AllyPosKey)); - addViews(addNumberEdit("Team Number", TeamNumKey)); + SettingsManager manager = new SettingsManager(getContext()); + + manager.addItem(new StringSettingsItem( + UnameKey, + "Username", + "" + )); + manager.addItem(new DropdownSettingsItem(SelEVCodeKey, "Event Code", "", fileEditor.getEventList().toArray(new String[0]))); + manager.addItem(new DropdownSettingsItem(AllyPosKey, "Alliance Pos", "", alliance_pos_list)); + + + + binding.SettingsTable.addView(manager.getSettingsView()); + +// addViews(addStringEdit("Username", UnameKey)); +// addViews(addDropdownByString("Event Code", fileEditor.getEventList().toArray(new String[0]), SelEVCodeKey)); +// addViews(addDropdownByString("Alliance Position", alliance_pos_list, AllyPosKey)); +// addViews(addNumberEdit("Team Number", TeamNumKey)); +// +// View[] FTPDependency = concatArrays( +// addCheckbox("Send Meta Files", FTPSendMetaFiles, new View[]{}), +// addStringEdit("FTP Server", FTPServer) +// ); +// +// View[] WifiDependency = addCheckbox("FTP Enabled", FTPEnabled, FTPDependency); +// addViews(addCheckbox("Wifi Mode", WifiModeKey, concatArrays(FTPDependency, WifiDependency))); +// addViews(WifiDependency); +// addViews(FTPDependency); - View[] FTPDependency = concatArrays( - addCheckbox("Send Meta Files", FTPSendMetaFiles, new View[]{}), - addStringEdit("FTP Server", FTPServer) - ); - View[] WifiDependency = addCheckbox("FTP Enabled", FTPEnabled, FTPDependency); - addViews(addCheckbox("Wifi Mode", WifiModeKey, concatArrays(FTPDependency, WifiDependency))); - addViews(WifiDependency); - addViews(FTPDependency); return root; } @@ -258,4 +361,318 @@ public class settingsFragment extends Fragment { super.onDestroyView(); binding = null; } + + + + + + + + + + + + + + + public abstract class SettingsItem { + private String key; + private String title; + private String description; + private T defaultValue; + private boolean enabled = true; + + public SettingsItem(String key, String title, String description, T defaultValue) { + this.key = key; + this.title = title; + this.description = description; + this.defaultValue = defaultValue; + } + + public abstract View createView(Context context); + public abstract T getValue(); + + public String getKey() { return key; } + public String getTitle() { return title; } + public String getDescription() { return description; } + public T getDefaultValue() { return defaultValue; } + public void setEnabled(boolean enabled) { this.enabled = enabled; } + public boolean isEnabled() { return enabled; } + } + + public class StringSettingsItem extends SettingsItem { + public StringSettingsItem(String key, String title, String description) { + super(key, title, description, prefs.getString(key, (String) defaults.get(key))); + } + + @Override + public View createView(Context context) { + TextInputLayout textInputLayout = new TextInputLayout(context); + textInputLayout.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + )); + + TextInputEditText editText = new TextInputEditText(context); + editText.setText(getValue()); + editText.setEnabled(isEnabled()); + + editText.addTextChangedListener(new TextWatcher() { + @Override + public void afterTextChanged(Editable s) { + getEditor().putString(getKey(), s.toString()).apply(); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + }); + + textInputLayout.addView(editText); + return textInputLayout; + } + + @Override + public String getValue() { + return prefs.getString(getKey(), (String) defaults.get(getKey())); + } + } + + public class NumberSettingsItem extends SettingsItem { + private int min; + private int max; + + public NumberSettingsItem(String key, String title, String description, int min, int max) { + super(key, title, description, prefs.getInt(key, (int) defaults.get(key))); + this.min = min; + this.max = max; + } + + @Override + public View createView(Context context) { + TextInputLayout textInputLayout = new TextInputLayout(context); + TextInputEditText editText = new TextInputEditText(context); + + editText.setInputType(InputType.TYPE_CLASS_NUMBER); + editText.setText(getValue()); + editText.setEnabled(isEnabled()); + + editText.addTextChangedListener(new TextWatcher() { + @Override + public void afterTextChanged(Editable s) { + try { + int value = Integer.parseInt(s.toString()); + if (value >= min && value <= max) { + getEditor().putInt(getKey(), value).apply(); + } + } catch (NumberFormatException e) { + editText.setText(String.valueOf(getDefaultValue())); + } + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + }); + + textInputLayout.addView(editText); + return textInputLayout; + } + + @Override + public Integer getValue() { + return prefs.getInt(getKey(), (int) defaults.get(getKey())); + } + } + + public class DropdownSettingsItem extends SettingsItem { + private String[] options; + + public DropdownSettingsItem(String key, String title, String description, String[] options) { + super(key, title, description, prefs.getString(key, (String) defaults.get(key))); + this.options = options; + } + + @Override + public View createView(Context context) { + TextInputLayout textInputLayout = new TextInputLayout(context); + textInputLayout.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + )); + textInputLayout.setHint("Select " + getTitle()); + + + + TextView dropdown = new TextView(getContext()); + + dropdown.setTextSize(24); + dropdown.setText(getValue()); + + ArrayList optionsList = new ArrayList(); + for(int i = 0; i < options.length; i++) + optionsList.add(options[i]); + + CustomSpinner dialog = CustomSpinner.newInstance(optionsList); + + dialog.setOnOptionSelectedListener(option -> { + getEditor().putString(getKey(), option).apply(); + dropdown.setText(option); + }); + + dropdown.setOnClickListener(v -> { + dialog.show(getActivity().getSupportFragmentManager(), getTitle()); + }); + +// List iconSpinnerItems = new ArrayList<>(); +// for(int i = 0; i < options.length; i++){ +// iconSpinnerItems.add(new IconSpinnerItem(options[i])); +// } +// IconSpinnerAdapter iconSpinnerAdapter = new IconSpinnerAdapter(dropdown); +// dropdown.setSpinnerAdapter(iconSpinnerAdapter); +// +// dropdown.setEnabled(isEnabled()); +// +// ArrayAdapter adapter = new ArrayAdapter<>( +// context, +// android.R.layout.simple_spinner_dropdown_item, +// options +// ); +// adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); +// +// int index = Arrays.asList(options).indexOf(getValue()); +// +// if(dropdown.length() != 0 && index != -1){ +// dropdown.selectItemByIndex(index); +// } +// +// dropdown.setOnSpinnerItemSelectedListener( +// (OnSpinnerItemSelectedListener) +// (oldIndex, oldItem, newIndex, newItem) -> getEditor().putString(getKey(), newItem.getText().toString()).apply()); +// +// dropdown.setPadding(10,20,10,20); +// dropdown.setBackgroundColor(0xf0000000); +// dropdown.setTextColor(0xff00ff00); +// dropdown.setTextSize(14.5f); +// dropdown.setArrowGravity(SpinnerGravity.END); +// dropdown.setArrowPadding(8); +// dropdown.setSpinnerPopupElevation(14); + + +// spinner.setAdapter(adapter); + + // Set initial selection +// String currentValue = getValue(); +// for (int i = 0; i < options.length; i++) { +// if (options[i].equals(currentValue)) { +// spinner.setSelection(i); +// break; +// } +// } +// spinner.setText(getValue()); +// spinner.setTextSize(24); + + +// spinner.addOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { +// @Override +// public void onItemSelected(AdapterView parent, View view, int position, long id) { +// settings.put(getKey(), options[position]); +// } +// +// @Override +// public void onNothingSelected(AdapterView parent) { +// settings.put(getKey(), getDefaultValue()); +// } +// }); + + textInputLayout.addView(dropdown); + return textInputLayout; + } + + @Override + public String getValue() { + return prefs.getString(getKey(), (String) defaults.get(getKey())); + } + } + + public class CheckboxSettingsItem extends SettingsItem { + private List> controlledItems; + + public CheckboxSettingsItem(String key, String title, String description, SettingsItem... controlledItems) { + super(key, title, description, prefs.getBoolean(key, (Boolean) defaults.get(key))); + this.controlledItems = Arrays.asList(controlledItems); + } + + @Override + public View createView(Context context) { + MaterialCheckBox checkBox = new MaterialCheckBox(context); + checkBox.setText(getTitle()); + checkBox.setChecked(getValue()); + + checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> { + getEditor().putBoolean(getKey(), isChecked).apply(); + for (SettingsItem item : controlledItems) { + item.setEnabled(isChecked); + } + }); + + return checkBox; + } + + @Override + public Boolean getValue() { + return prefs.getBoolean(getKey(), (Boolean) defaults.get(getKey())); + } + } + + public class SettingsManager { + private Context context; + private HashMap settings; + private List> items; + private LinearLayout container; + + public SettingsManager(Context context) { + this.context = context; + this.items = new ArrayList<>(); + this.container = new LinearLayout(context); + this.container.setOrientation(LinearLayout.VERTICAL); + this.container.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + )); + } + + public void addItem(SettingsItem item) { + items.add(item); + + MaterialCardView card = new MaterialCardView(context); + LinearLayout itemContainer = new LinearLayout(context); + itemContainer.setOrientation(LinearLayout.VERTICAL); + itemContainer.setPadding(32, 16, 32, 16); + + TextView titleView = new TextView(context); + titleView.setText(item.getTitle()); + titleView.setTextAppearance(com.google.android.material.R.style.TextAppearance_MaterialComponents_Subtitle1); + + TextView descriptionView = new TextView(context); + descriptionView.setText(item.getDescription()); + descriptionView.setTextAppearance(com.google.android.material.R.style.TextAppearance_MaterialComponents_Body2); + + itemContainer.addView(titleView); + itemContainer.addView(descriptionView); + itemContainer.addView(item.createView(context)); + + card.addView(itemContainer); + container.addView(card); + } + + public View getSettingsView() { + return container; + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/ridgebotics/ridgescout/utility/settingsManager.java b/app/src/main/java/com/ridgebotics/ridgescout/utility/settingsManager.java index 6a9b365..50b2883 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/utility/settingsManager.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/utility/settingsManager.java @@ -13,8 +13,8 @@ public class settingsManager { public static final String UnameKey = "username"; public static final String SelEVCodeKey = "selected_event_code"; + public static final String YearNumKey = "year_num"; public static final String WifiModeKey = "wifi_mode"; - public static final String TeamNumKey = "team_num"; public static final String MatchNumKey = "match_num"; public static final String AllyPosKey = "alliance_pos"; public static final String DataModeKey = "data_view_mode"; @@ -30,7 +30,7 @@ public class settingsManager { hm.put(UnameKey, "Username"); hm.put(SelEVCodeKey, "unset"); hm.put(WifiModeKey, false); - hm.put(TeamNumKey, 4388); + hm.put(YearNumKey, 2025); hm.put(MatchNumKey, 0); hm.put(AllyPosKey, "red-1"); hm.put(DataModeKey, 0); @@ -52,7 +52,7 @@ public class settingsManager { getEditor() .putString(SelEVCodeKey,(String) defaults.get( SelEVCodeKey)).apply(); getEditor().putBoolean(WifiModeKey, (boolean) defaults.get( WifiModeKey )).apply(); - getEditor() .putInt(TeamNumKey, (int) defaults.get( TeamNumKey )).apply(); + getEditor() .putInt(YearNumKey, (int) defaults.get( YearNumKey )).apply(); getEditor() .putInt(MatchNumKey, (int) defaults.get( MatchNumKey )).apply(); getEditor() .putString(AllyPosKey, (String) defaults.get( AllyPosKey )).apply(); getEditor() .putInt(DataModeKey, (int) defaults.get( DataModeKey )).apply(); @@ -74,8 +74,8 @@ public class settingsManager { public static boolean getWifiMode(){return prefs.getBoolean( WifiModeKey, (boolean) defaults.get(WifiModeKey));} public static void setWifiMode(boolean bool){getEditor().putBoolean( WifiModeKey,bool).apply();} - public static int getTeamNum(){return prefs.getInt( TeamNumKey, (int) defaults.get(TeamNumKey));} - public static void setTeamNum(int num){ getEditor().putInt( TeamNumKey,num).apply();} + public static int getYearNum(){return prefs.getInt( YearNumKey, (int) defaults.get(YearNumKey));} + public static void setYearNum(int num){ getEditor().putInt( YearNumKey,num).apply();} public static int getMatchNum(){return prefs.getInt( MatchNumKey, (int) defaults.get(MatchNumKey));} public static void setMatchNum(int num){ getEditor().putInt( MatchNumKey,num).apply();} diff --git a/app/src/main/res/drawable/background.png b/app/src/main/res/drawable/background.png new file mode 100644 index 0000000000000000000000000000000000000000..3ba6d818e126ebe77f227374c6613da5345b7eb7 GIT binary patch literal 570 zcmV-A0>%A_P)$ViOO{T6*^iZTE3DR_!BBV!ihu@Kq4s+iESL4$DMoUv8y># zZ7u1Pr?Xfro)w(l`B7EX@BM!NGMP+vZ5C=W%jNR9dmeVXU8mpgKdn})s?AbOrwfC@ z;Ds^~x-cG(f0c^xcLhpC=)N9GMCiW%C=KBPfU*!i1fU#*{{m13!lwY_kMJb`c_Ul} zK)wi91CS@eO#tMFa5DgTA>0K(J_vUMkO#s;0HlxbFaT*I)B-@d2(P^70f-x+5dh*vXbgZj5gG;H65((-JgwL3 ze$ze9X&ivJ2)$mfv)OEhZ6UM*Ks*So0T2g5s{ou3hQncN2(1IaXf$dKAqoK6Lx=`| zj}hkcc~FF?0Jub`swyZ#bO1Dq5G4T3Aw&y6GYC-w5FR0V0Ky_90YEr}WB>?*kQ4y* zBP0hvy$DGHP#;3F0Mvt!GysnyBoDx22w4DdKSDMD+=q}A0JkG#2f%FzSpsl9Lbd>0 zhmbV@Un67>z~=}>0B}M$9*^Johd@C9Fr7|+yhead>F4u*0FZ#u + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index bc2b7a6..c8a1e7b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,21 +4,9 @@ xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" + android:background="@drawable/background_repeat" android:layout_height="match_parent"> - - -