부모 위젯(seatList)의 상태를 자식 위젯(seatRow)에서 변경할 수 있도록 하게 하는 문제
Widget seatRow(int idx, bool isSelected) {
Widget seat = GestureDetector(
onTap: () {
// isSelected 상태를 변경할 로직을 작성하자
},
child: Container(
margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
width: 50,
height: 50,
decoration: BoxDecoration(
color: isSelected ? Colors.purple : Colors.grey[300]!,
borderRadius: BorderRadius.circular(8)),
),
);
return Row(
children: [seat, seat, Text((idx + 1).toString()), seat, seat],
);
}
List.generate(20, (col) => seatRow())
여기까지는 아주 단순하게, 여러개의 seatUI를 그리면 되겠다고 생각했다.
하지만 좌석의 column과 row를 상태로 저장해야 되고, 그 상태를 변경하는 함수를 seatRow에 넣어야된다고 생각을 했다.
3. seatPage를 statefulWidget으로 변경
class SeatPage extends StatefulWidget {
SeatPage({required this.departure, required this.arrival, super.key});
final String departure;
final String arrival;
State<SeatPage> createState() => _SeatPageState();
}
class _SeatPageState extends State<SeatPage> {
int? selectedCol;
String? selectedRow;
void onTapSeat(col, row) {
setState(() {
selectedCol = col;
selectedRow = row;
});
}
homePage로부터 받는 변수는 daparture, arrival
seatPage에서 관리하는 상태 변수는 selectedCol과 selectedRow로 잡았고,
onTapSeat라는 상태변경 함수를 seatRow에 전달하려고 했다.
결론 부분을 보면 알겠지만 이 검색결과는 틀렸다. widget으로만 전달하면 문제가 없다.
import 'package:flutter/material.dart';
class seatRow extends StatefulWidget {
seatRow(
{required this.col,
required this.onTapSeat,
this.selectedCol,
this.selectedRow,
super.key});
final int col;
int? selectedCol;
String? selectedRow;
Function onTapSeat;
State<seatRow> createState() => _seatRowState();
}
class _seatRowState extends State<seatRow> {
Widget seat(String row) {
return GestureDetector(
onTap: () {
// 상태 변화를 시킬수 있는 함수
widget.onTapSeat(widget.col + 1, row);
},
child: Container(
margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
width: 50,
height: 50,
decoration: BoxDecoration(
color: row == widget.selectedRow &&
widget.col + 1 == widget.selectedCol
? Colors.purple
: Colors.grey[300]!,
borderRadius: BorderRadius.circular(8)),
),
);
}
Widget build(Object context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
seat("A"),
seat("B"),
Container(
margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
width: 50,
height: 50,
alignment: Alignment.center,
child: Text((widget.col + 1).toString())),
seat("C"),
seat("D")
],
);
}
}
위와 같이 결론을 내리려고 하는데, state를 갖고 있는 위젯은 부모 위젯이고, 자식 위젯은 그것을 변경하기만 하는 것 뿐인데, 왜 자식 위젯이 statefulWidget이여야 되는 것인지 이해가 가지 않았다.
그래서 해당 위젯을 다시 statelessWidget으로 변경을 해주었는데...
import 'package:flutter/material.dart';
class SeatRow extends StatelessWidget {
SeatRow(
{required this.col,
required this.onTapSeat,
this.selectedCol,
this.selectedRow,
super.key});
final int col;
int? selectedCol;
String? selectedRow;
Function onTapSeat;
Widget seat(String row) {
return GestureDetector(
onTap: () {
// 상태 변화를 시킬수 있는 함수
onTapSeat(col + 1, row);
},
child: Container(
margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
width: 50,
height: 50,
decoration: BoxDecoration(
color: row == selectedRow && col + 1 == selectedCol
? Colors.purple
: Colors.grey[300]!,
borderRadius: BorderRadius.circular(8)),
),
);
}
Widget build(Object context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
seat("A"),
seat("B"),
Container(
margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
width: 50,
height: 50,
alignment: Alignment.center,
child: Text((col + 1).toString())),
seat("C"),
seat("D")
],
);
}
}
멀쩡하게 동작한다.
심플하게 state가 존재하는 위젯에서만 statefulWidget을 사용한다고 기억하면 될 것 같다.
아니였다.. 함수로 해도 전혀 문제가 없었다..! 내가 잘못 썼나보다