Замораживание первых двух столбцов данных в флаттер-дротике
Я создал dataTable, в котором хочу зафиксировать первый столбец и сделать остальные прокручиваемыми по горизонтали, а также всю таблицу по вертикали. Я хотел использовать две таблицы данных, но, поскольку у меня много динамических данных, я хочу использовать только одну таблицу данных.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
import 'package:tsa/model/rounds/allrounds.dart';
import 'package:tsa/model/rounds/allrounds_list.dart';
import 'package:tsa/notifiers/allroundsNotifier.dart';
import 'package:tsa/pages/loginpage.dart';
import 'package:horizontal_data_table/horizontal_data_table.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, Key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class User {
String firstName;
String lastName;
User({required this.firstName, required this.lastName});
static List<User> getUsers() {
return <User>[
User(firstName: "Paul", lastName: "Mark"),
User(firstName: "Paul", lastName: "X"),
User(firstName: "Owen", lastName: "__"),
User(firstName: "Paul", lastName: "DNS"),
User(firstName: "Paul", lastName: "r"),
];
}
}
class _MyHomePageState extends State<MyHomePage> {
List<User> selectedUser = [];
List<User> users = [];
var roundlist = <dynamic>[];
var id = "";
var fname = "";
var lname = "";
var best_5 = 0;
var best_all = 0;
var position_after_3 = 0;
var position_after_5 = 0;
var position_final = 0;
var r_1 = 0;
var r_2 = 0;
var r_3 = 0;
var r_4 = 0;
var r_5 = 0;
final Map<String, IconData> symbolIconMapping = {
"wrong": Icons.close,
"dash": Icons.line_axis,
"DNS": Icons.dns,
};
List<DataRow> rows = [];
List<DataColumn> columns = [];
List list_of_data = [];
List<String> selectedDropdownValue = [
'Event 1',
'Event 2',
'Event 3',
'Event 4',
'Event 5',
'Event 6',
];
String selectedCount = "Event 1";
getColumns() {
for (int i = 0; i < dataColumns.length; i++) {
columns.add(
// DataColumn(label: dataColumns[i]),
DataColumn(
label: SizedBox(
width: 100, // Adjust the width as needed
child: Text(
dataColumns[i],
textAlign: TextAlign.center,
softWrap: true, // Allow text to wrap to the next line
),
),
),
);
}
}
List<dynamic> specialCells = [
'best_3',
'best_5',
'best_all',
'position_after_3',
'position_after_5',
'position_final',
];
List<dynamic> dataCells = [
'r_1',
'r_2',
'r_3',
'r_4',
'r_5',
'r_6',
'best_3',
'best_5',
'best_all',
'position_after_3',
'position_after_5',
'position_final',
];
List<dynamic> dataColumns = [
"ID",
"NAME",
"FIRST",
"SECOND",
"THIRD",
"BEST OF THREE TRIALS",
"POSITION AFTER THREE TRAILS",
"FOURTH",
"FIFTH",
"BEST OF FIVE TRIALS",
"POSITION AFTER FIVE TRIALS",
"SIXTH",
"BEST OF ALL TRIALS",
"FINAL POSITION"
];
List value = [];
TextEditingController dropdownController = TextEditingController();
// void arrayInit(AllroundsNotifier allroundsNotifier){
// var myInt = roundlist;
// var i = int.parse(myInt.toString());
// list_of_data.add({
// "id" : allroundsNotifier.mainAllrounds.data.
// "fname" : allroundsNotifier.mainAllrounds.data[i].fname[0];
// });
// }
late AllRoundsList mainAllrounds;
bool isCalled = false;
@override
void initState() {
users = User.getUsers();
getColumns();
selectedUser = List.from(users);
super.initState();
}
Future<AllroundsNotifier> fetchAllData(
AllroundsNotifier allroundsNotifier) async {
String URL =
"https://admin.trackblazerssportsacademy.com/score/score-panel-app";
Map data = {};
var body = json.encode(data);
print(isCalled);
try {
if (!isCalled) {
http.Response response = await http.get(
Uri.parse(
URL,
),
);
if (response.statusCode == 200) {
var result = jsonDecode(response.body);
mainAllrounds = AllRoundsList.fromJson(result);
allroundsNotifier.setData(mainAllrounds);
// roundlist = result['data'];
print(mainAllrounds.data.length);
}
rows.clear();
for (int i = 0; i < mainAllrounds.data.length; i++) {
Map<String, String> concatenatedValues = {};
for (String cell in dataCells) {
final cellValue = mainAllrounds.data[i].toJson()[cell];
concatenatedValues[cell] = '$cellValue';
}
rows.add(DataRow(cells: [
DataCell(
Column(
children: [
Padding(
padding: const EdgeInsets.all(15.0),
child: Text(mainAllrounds.data[i].id.toString())),
],
),
),
DataCell(
Column(
children: [
Padding(
padding: const EdgeInsets.all(15.0),
child: Text(
"${mainAllrounds.data[i].fname} ${mainAllrounds.data[i].lname}",
),
),
],
),
),
for (String cell in dataCells)
DataCell(
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
initialValue: concatenatedValues[cell] ?? '',
onChanged: (newValue) {},
decoration: const InputDecoration(
border: OutlineInputBorder(), // Add a border
contentPadding: EdgeInsets.all(8.0), // Add padding
),
),
),
),
const SizedBox(width: 5),
Expanded(
child: DropdownButton<User>(
value: selectedUser.isNotEmpty &&
i >= 0 &&
i < selectedUser.length
? selectedUser[i]
: null,
onChanged: (newUser) {
setState(() {
if (i >= 0 && i < selectedUser.length) {
selectedUser[i] = newUser!;
}
});
},
items: users.map<DropdownMenuItem<User>>((User value) {
return DropdownMenuItem<User>(
value: value,
child: Text(value.lastName),
);
}).toList(),
),
),
],
)
// // Column(
// // children: [
// // Text(concatenatedValues[cell] ?? ''),
// // SizedBox(
// //
// // )
// // ],
// // ),
// ),
)]));
}
} else {
print("already called");
}
} catch (e) {
print("Error fetching data: $e");
}
return allroundsNotifier;
}
void _logout() {
// You can use Navigator to pop the current page and navigate to the login page.
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) =>
const LoginPage(), // Replace with your login page widget
),
);
}
@override
Widget build(BuildContext context) {
AllroundsNotifier allroundsNotifier =
Provider.of<AllroundsNotifier>(context, listen: false);
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: const Text("Score Table"),
actions: [
IconButton(
icon: const Icon(Icons
.logout), // Use the logout icon or any other icon you prefer
onPressed: _logout,
),
],
),
body: FutureBuilder(
future: fetchAllData(allroundsNotifier),
builder: (context, snapshot) {
if (snapshot.hasData) {
return SingleChildScrollView(
child: Column(
children: [
const Padding(padding: EdgeInsets.symmetric(vertical: 4)),
Container(
padding: const EdgeInsets.symmetric(
vertical: 4,
horizontal: 50), // Adjust the padding as needed
decoration: BoxDecoration(
border: Border.all(
color: Colors.orange
.shade600, // Set your desired border color here
width: 2.0, // Adjust the border width as needed
),
borderRadius: BorderRadius.circular(
10.0), // Adjust the border radius for rounded corners
),
child: DropdownButton<String>(
underline: Container(
// To remove the default underline
color: Colors.lightBlue.shade50,
),
isExpanded: true,
elevation: 0,
value: selectedCount,
items: selectedDropdownValue.map((e) {
return DropdownMenuItem(
value: e,
child: Text(e),
);
}).toList(),
onChanged: (value) {
setState(() {
selectedCount = value.toString();
});
},
),
),
const SizedBox(height: 30),
Row(
children: [
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
headingRowColor:
MaterialStateColor.resolveWith(
(states) => Colors.orange),
dataRowColor: MaterialStateColor.resolveWith(
(states) => Colors.orange.shade100),
border: TableBorder.all(),
columns: columns,
rows: rows),
),
),
//
],
),
],
),
);
}
return const Center(child: CircularProgressIndicator());
}), // You can replace this with your desired content
),
);
}
}
Я попытался обернуть другие ячейки горизонтальной прокруткой, но приложение вылетает.