Write ReorderableTableLayout

This commit is contained in:
Astatin3
2024-07-23 12:27:45 -06:00
parent 5be19880d4
commit fe92d4e27b
8 changed files with 252 additions and 19 deletions
@@ -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;
@@ -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;
}
}
+2 -2
View File
@@ -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"-->