mirror of
https://github.com/Team4388/RidgeScout.git
synced 2026-06-08 16:28:00 -06:00
Write ReorderableTableLayout
This commit is contained in:
@@ -2,8 +2,9 @@ package com.astatin3.scoutingapp2025.scoutingData;
|
||||
|
||||
import com.astatin3.scoutingapp2025.types.input.dropdownType;
|
||||
import com.astatin3.scoutingapp2025.types.input.inputType;
|
||||
import com.astatin3.scoutingapp2025.types.input.notesType;
|
||||
import com.astatin3.scoutingapp2025.types.input.textType;
|
||||
import com.astatin3.scoutingapp2025.types.input.sliderType;
|
||||
import com.astatin3.scoutingapp2025.types.input.textType;
|
||||
import com.astatin3.scoutingapp2025.utility.fileEditor;
|
||||
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
|
||||
import com.astatin3.scoutingapp2025.utility.ByteBuilder;
|
||||
@@ -19,27 +20,27 @@ public class fields {
|
||||
public static final inputType[][] default_match_fields = new inputType[][] {
|
||||
{
|
||||
new sliderType("How good is robot", 5, 1, 10),
|
||||
new notesType("notes", "<no-notes>"),
|
||||
new textType("notes", "<no-notes>"),
|
||||
},{
|
||||
new sliderType("How good is robot", 5, 1, 10),
|
||||
new sliderType("Test", 128, 64, 256),
|
||||
new notesType("notes", "<no-notes>"),
|
||||
new textType("notes", "<no-notes>"),
|
||||
},{
|
||||
new sliderType("How good is robot", 5, 5, 10),
|
||||
new sliderType("Test", 128, 64, 256),
|
||||
new dropdownType("test-dropdown", new String[]{"Test1", "test2", "Three"}, 1),
|
||||
new notesType("notes", "<no-notes>"),
|
||||
new textType("notes", "<no-notes>"),
|
||||
}
|
||||
};
|
||||
|
||||
public static final inputType[][] default_pit_fields = new inputType[][] {
|
||||
{
|
||||
new sliderType("How good is robot", 5, 0, 10),
|
||||
new notesType("notes", "<no-notes>"),
|
||||
new textType("notes", "<no-notes>"),
|
||||
},{
|
||||
new sliderType("How good is robot", 5, 0, 10),
|
||||
new sliderType("Test", 1, 0, 10),
|
||||
new notesType("notes", "<no-notes>"),
|
||||
new textType("notes", "<no-notes>"),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -107,7 +108,7 @@ public class fields {
|
||||
t = new dropdownType();
|
||||
break;
|
||||
case inputType.notesType:
|
||||
t = new notesType();
|
||||
t = new textType();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ public class dropdownType extends inputType {
|
||||
public dataType.valueTypes getValueType(){return dataType.valueTypes.NUM;}
|
||||
public Object get_fallback_value(){return 0;}
|
||||
public dropdownType(){};
|
||||
public String get_type_name(){return "Dropdown";}
|
||||
public dropdownType(String name, String[] text_options, int defaultSelIndex){
|
||||
super(name);
|
||||
this.text_options = text_options;
|
||||
|
||||
@@ -43,5 +43,6 @@ public abstract class inputType {
|
||||
public abstract dataType getViewValue();
|
||||
public abstract void add_individual_view(LinearLayout parent, dataType data);
|
||||
public abstract void add_compiled_view(LinearLayout parent, dataType[] data);
|
||||
public abstract String get_type_name();
|
||||
|
||||
}
|
||||
@@ -34,6 +34,7 @@ public class sliderType extends inputType {
|
||||
public dataType.valueTypes getValueType(){return dataType.valueTypes.NUM;}
|
||||
public Object get_fallback_value(){return 0;}
|
||||
public sliderType(){};
|
||||
public String get_type_name(){return "Slider";}
|
||||
public sliderType(String name, int defaultValue, int min, int max){
|
||||
super(name);
|
||||
this.default_value = defaultValue;
|
||||
|
||||
+4
-4
@@ -12,7 +12,6 @@ import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.astatin3.scoutingapp2025.types.data.dataType;
|
||||
import com.astatin3.scoutingapp2025.types.data.intType;
|
||||
import com.astatin3.scoutingapp2025.types.data.stringType;
|
||||
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
|
||||
import com.astatin3.scoutingapp2025.utility.ByteBuilder;
|
||||
@@ -20,16 +19,17 @@ import com.astatin3.scoutingapp2025.utility.ByteBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class notesType extends inputType {
|
||||
public class textType extends inputType {
|
||||
public int get_byte_id() {return notesType;}
|
||||
public inputTypes getInputType(){return inputTypes.NOTES_INPUT;}
|
||||
public dataType.valueTypes getValueType(){return dataType.valueTypes.STRING;}
|
||||
public Object get_fallback_value(){return "<no-notes>";}
|
||||
public notesType(){};
|
||||
public notesType(String name, String default_text){
|
||||
public textType(){}
|
||||
public textType(String name, String default_text){
|
||||
super(name);
|
||||
this.default_value = default_text;
|
||||
}
|
||||
public String get_type_name(){return "Text";}
|
||||
public byte[] encode() throws ByteBuilder.buildingException {
|
||||
ByteBuilder bb = new ByteBuilder();
|
||||
bb.addString(name);
|
||||
@@ -2,6 +2,7 @@ package com.astatin3.scoutingapp2025.ui.data;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
@@ -9,11 +10,15 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.astatin3.scoutingapp2025.databinding.FragmentDataBinding;
|
||||
import com.astatin3.scoutingapp2025.scoutingData.fields;
|
||||
import com.astatin3.scoutingapp2025.types.input.inputType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class fieldsView extends ConstraintLayout {
|
||||
public fieldsView(@NonNull Context context) {
|
||||
super(context);
|
||||
@@ -24,6 +29,7 @@ public class fieldsView extends ConstraintLayout {
|
||||
FragmentDataBinding binding;
|
||||
String filename;
|
||||
private static final int background_color = 0x5000ff00;
|
||||
private static final int unfocused_background_color = 0x2000ff00;
|
||||
|
||||
inputType[][] values;
|
||||
|
||||
@@ -32,10 +38,12 @@ public class fieldsView extends ConstraintLayout {
|
||||
|
||||
binding.fieldsSelectButtons.setVisibility(VISIBLE);
|
||||
binding.addButton.setVisibility(GONE);
|
||||
binding.fieldsArea.setReorderingEnabled(false);
|
||||
binding.fieldsArea.removeAllViews();
|
||||
binding.fieldsArea.setStretchAllColumns(true);
|
||||
binding.fieldsSelectButtons.bringToFront();
|
||||
|
||||
binding.fieldsArea.setStretchAllColumns(true);
|
||||
// binding.fieldsArea.setStretchAllColumns(true);
|
||||
|
||||
binding.matchScoutingButton.setOnClickListener(v -> {
|
||||
binding.fieldsSelectButtons.setVisibility(GONE);
|
||||
@@ -52,8 +60,37 @@ public class fieldsView extends ConstraintLayout {
|
||||
});
|
||||
}
|
||||
|
||||
private TextView createTextView(String text) {
|
||||
TextView textView = new TextView(getContext());
|
||||
textView.setText(text);
|
||||
textView.setPadding(10, 10, 10, 10);
|
||||
return textView;
|
||||
}
|
||||
|
||||
private void load_field_menu() {
|
||||
values = fields.load(filename);
|
||||
binding.fieldsArea.bringToFront();
|
||||
binding.fieldsArea.removeAllViews();
|
||||
binding.fieldsArea.setReorderingEnabled(false);
|
||||
if(values == null) return;
|
||||
|
||||
// List<TableRow> rows = new ArrayList<>();
|
||||
//
|
||||
//// Create and add rows
|
||||
// TableRow row1 = new TableRow(getContext());
|
||||
// row1.addView(createTextView("Cell 1,1"));
|
||||
// row1.addView(createTextView("Cell 1,2"));
|
||||
// rows.add(row1);
|
||||
//
|
||||
// TableRow row2 = new TableRow(getContext());
|
||||
// row2.addView(createTextView("Cell 2,1"));
|
||||
// row2.addView(createTextView("Cell 2,2"));
|
||||
// rows.add(row2);
|
||||
//
|
||||
//// Set the rows
|
||||
// binding.fieldsArea.setRows(rows);
|
||||
//
|
||||
//// Or add rows individually
|
||||
|
||||
for(int i = 0; i < values.length; i++){
|
||||
|
||||
@@ -66,12 +103,11 @@ public class fieldsView extends ConstraintLayout {
|
||||
rowParams.setMargins(20,20,20,20);
|
||||
tr.setLayoutParams(rowParams);
|
||||
tr.setPadding(20,20,20,20);
|
||||
binding.fieldsArea.addView(tr);
|
||||
|
||||
// tr.setMinimumWidth();
|
||||
tr.setBackgroundColor(background_color);
|
||||
|
||||
TextView tv = new TextView(getContext());
|
||||
tv.setText("v" + i);
|
||||
tv.setText("v" + i + "\n eee");
|
||||
tv.setTextSize(20);
|
||||
tr.addView(tv);
|
||||
|
||||
@@ -80,16 +116,64 @@ public class fieldsView extends ConstraintLayout {
|
||||
tv.setTextSize(16);
|
||||
tr.addView(tv);
|
||||
|
||||
binding.fieldsArea.addView(tr);
|
||||
|
||||
// frcTeam finalTeam = team;
|
||||
int fi = i;
|
||||
tr.setOnClickListener(v -> {
|
||||
// loadTeam(finalTeam, latestSettings.settings.get_compiled_mode());
|
||||
load_fields(values[fi]);
|
||||
display_fields(values[fi]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void load_fields(inputType[] version_values) {
|
||||
private void display_fields(inputType[] version_values) {
|
||||
binding.fieldsArea.removeAllViews();
|
||||
binding.fieldsArea.setReorderingEnabled(true);
|
||||
|
||||
// ArrayList<TableRow> rows = new ArrayList<>();
|
||||
|
||||
for(int i = 0; i < version_values.length; i++){
|
||||
TableRow tr = new TableRow(getContext());
|
||||
TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
|
||||
rowParams.setMargins(20,20,20,20);
|
||||
tr.setLayoutParams(rowParams);
|
||||
tr.setPadding(20,20,20,20);
|
||||
tr.setBackgroundColor(unfocused_background_color);
|
||||
|
||||
TextView tv = new TextView(getContext());
|
||||
tv.setText(version_values[i].get_type_name());
|
||||
tv.setTextSize(12);
|
||||
tr.addView(tv);
|
||||
|
||||
tv = new TextView(getContext());
|
||||
tv.setText(version_values[i].name);
|
||||
tv.setTextSize(20);
|
||||
tr.addView(tv);
|
||||
// rows.add(tr);
|
||||
// tr.addView(tv);
|
||||
binding.fieldsArea.addView(tr);
|
||||
tr.setOnClickListener(v -> {
|
||||
|
||||
trHighlight(tr);
|
||||
});
|
||||
}
|
||||
|
||||
// binding.fieldsArea.setSlidingEnabled(true);
|
||||
// binding.fieldsArea.setRows(rows);
|
||||
}
|
||||
|
||||
private void trHighlight(TableRow self){
|
||||
for(int i = 0; i < binding.teamsArea.getChildCount(); i++){
|
||||
TableRow child = (TableRow) binding.teamsArea.getChildAt(i);
|
||||
child.setBackgroundColor(unfocused_background_color);
|
||||
}
|
||||
|
||||
self.setBackgroundColor(background_color);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.astatin3.scoutingapp2025.utility;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ReorderableTableLayout extends TableLayout {
|
||||
private boolean reorderingEnabled = false;
|
||||
private int draggedRowIndex = -1;
|
||||
private float lastY;
|
||||
private List<View> originalRows;
|
||||
private int rowHeight;
|
||||
|
||||
public ReorderableTableLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ReorderableTableLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
originalRows = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (!reorderingEnabled) {
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
lastY = ev.getY();
|
||||
draggedRowIndex = getRowIndexAtY(lastY);
|
||||
if (draggedRowIndex != -1) {
|
||||
View draggedRow = getChildAt(draggedRowIndex);
|
||||
rowHeight = draggedRow.getHeight();
|
||||
saveOriginalOrder();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (!reorderingEnabled || draggedRowIndex == -1) {
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float currentY = event.getY();
|
||||
int targetIndex = getRowIndexAtY(currentY);
|
||||
if (targetIndex != -1 && targetIndex != draggedRowIndex) {
|
||||
updateRowOrder(draggedRowIndex, targetIndex);
|
||||
draggedRowIndex = targetIndex;
|
||||
}
|
||||
lastY = currentY;
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
draggedRowIndex = -1;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getRowIndexAtY(float y) {
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
View child = getChildAt(i);
|
||||
if (y >= child.getTop() && y <= child.getBottom()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void saveOriginalOrder() {
|
||||
originalRows.clear();
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
originalRows.add(getChildAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRowOrder(int fromIndex, int toIndex) {
|
||||
if (fromIndex < toIndex) {
|
||||
for (int i = fromIndex; i < toIndex; i++) {
|
||||
Collections.swap(originalRows, i, i + 1);
|
||||
}
|
||||
} else {
|
||||
for (int i = fromIndex; i > toIndex; i--) {
|
||||
Collections.swap(originalRows, i, i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
removeAllViewsInLayout();
|
||||
for (View view : originalRows) {
|
||||
addViewInLayout(view, -1, view.getLayoutParams(), true);
|
||||
}
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setReorderingEnabled(boolean enabled) {
|
||||
reorderingEnabled = enabled;
|
||||
}
|
||||
|
||||
public List<Integer> getReorderedIndexes() {
|
||||
List<Integer> reorderedIndexes = new ArrayList<>();
|
||||
for (View view : originalRows) {
|
||||
reorderedIndexes.add(indexOfChild(view));
|
||||
}
|
||||
return reorderedIndexes;
|
||||
}
|
||||
}
|
||||
@@ -204,12 +204,12 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TableLayout
|
||||
<com.astatin3.scoutingapp2025.utility.ReorderableTableLayout
|
||||
android:id="@+id/fieldsArea"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</TableLayout>
|
||||
</com.astatin3.scoutingapp2025.utility.ReorderableTableLayout>
|
||||
|
||||
<!-- <TableLayout-->
|
||||
<!-- android:id="@+id/searchTable"-->
|
||||
|
||||
Reference in New Issue
Block a user