Cześć,
pisze swoją pierwszą appkę przy pomocy fluttera i natrafiłem na problem z popupem.
Mam na ekranie kalendarz po kliknięciu którego pojawia się popup, na nim user wybiera termin (2 pola select) po czym klika dalej, jest strzał do backendu, pobranie danych i pojawia się kolejny ekran (tzn. jeden Container jest ukrywany a kolejny pokazywany), tam znowu jakieś pola, znowu dalej i 3 ekran gdzie jest już podsumowanie i możliwość zakupu termin.
Niestety bardzo nie podoba mi się to co stworzyłem bo jest masa kodu, wszystko upchnięte jest w showDialog<T>,jakieś ify które ukrywają/pokazują poszczególne części popupu.
Wygląda i działa nie najgorzej ale zrobić tu jakieś poprawki to dramat.
Zna ktoś może jakiś lepszy sposób jak można użytkownika przeprowadzić przez taki proces?
Brzmi jakbyś potrzebował lepszego sposobu zarządzania stanem i nawigacją w Twojej aplikacji Flutter. Możesz rozważyć użycie narzędzi do zarządzania stanem, takich jak Provider, Riverpod lub Bloc, aby oddzielić logikę biznesową od interfejsu użytkownika. Ponadto, zamiast używać jednego dużego showDialog
, możesz rozważyć wykorzystanie narzędzi nawigacyjnych, takich jak Navigator, aby przemieszczać się między różnymi ekranami w Twojej aplikacji. Dzięki temu będziesz mógł łatwiej zarządzać i odseparować poszczególne części Twojej aplikacji.
Kolego może użyj PageView. Tylko zablokuj przechodzenie między stronami i rób to automatycznie po spełnieniu danego kroku
Cały czas kręcę się w kółko i nie mogę znaleźć rozwiązania, wklej tu kod może ktoś mnie naprowadzi jak to poprawić.
Klasa generująca tabelkę 5x5, każda komórka ma w sobie przycisk po kliknięciu którego pojawia się form:
import 'package:flutter/material.dart';
import 'popup_view.dart';
class TableWidget extends StatefulWidget {
@override
_TableWidgetState createState() => _TableWidgetState();
}
class _TableWidgetState extends State<TableWidget> {
int _currentPageIndex = 0;
void _updatePageIndex(int index) {
print('Updating page index: $index');
setState(() {
_currentPageIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Table(
border: TableBorder.all(),
children: List.generate(5, (rowIndex) {
return TableRow(
children: List.generate(5, (colIndex) {
return TableCell(
child: Center(
child: ElevatedButton(
onPressed: () {
showDialog(
context: context,
builder: (context) => PopupView(
rowIndex,
colIndex,
_currentPageIndex,
_updatePageIndex,
),
);
},
child: Text('Pokaż'),
),
),
);
}),
);
}),
);
}
}
oraz druga klasa pokazująca popup który składa się z 3 widoków:
import 'package:flutter/material.dart';
class PopupView extends StatefulWidget {
final int rowIndex;
final int colIndex;
final int currentPageIndex;
final Function(int) updatePageIndex;
PopupView(
this.rowIndex,
this.colIndex,
this.currentPageIndex,
this.updatePageIndex,
);
@override
_PopupViewState createState() => _PopupViewState();
}
class _PopupViewState extends State<PopupView> {
String? _firstValue;
String? _secondValue;
@override
Widget build(BuildContext context) {
return Dialog(
child: SizedBox(
height: 300,
width: 300,
child: PageView(
controller: PageController(initialPage: widget.currentPageIndex),
children: [
_buildFirstPage(),
_buildSecondPage(),
_buildSummaryPage(),
],
onPageChanged: (index) {
widget.updatePageIndex(index);
},
),
),
);
}
Widget _buildFirstPage() {
List<String> dropdownItems = [
'Wybierz wartość',
'Wartość 1',
'Wartość 2',
'Wartość 3'
];
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Wybrałeś komórkę: ${widget.rowIndex}, ${widget.colIndex}'),
SizedBox(height: 20),
DropdownButton<String>(
hint: Text('Wybierz wartość'),
value: _firstValue,
onChanged: (String? value) {
setState(() {
_firstValue = value;
});
},
items: dropdownItems.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value != 'Wybierz wartość' ? value : null,
child: Text(value),
);
}).toList(),
),
SizedBox(height: 20),
Text('Wybrałeś: ${_firstValue ?? 'brak'}'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
widget.updatePageIndex(1); // Ustawiamy indeks strony na 1
},
child: Text('Dalej'),
),
],
);
}
Widget _buildSecondPage() {
List<String> dropdownItems = [
'Wybierz wartość',
'Wartość A',
'Wartość B'
];
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Wybrałeś komórkę: ${widget.rowIndex}, ${widget.colIndex}'),
SizedBox(height: 20),
Text('Na poprzednim widoku wybrałeś: $_firstValue'),
SizedBox(height: 20),
DropdownButton<String>(
hint: Text('Wybierz wartość'),
value: _secondValue,
onChanged: (String? value) {
setState(() {
_secondValue = value;
});
},
items: dropdownItems.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value != 'Wybierz wartość' ? value : null,
child: Text(value),
);
}).toList(),
),
SizedBox(height: 20),
Text('Wybrałeś: ${_secondValue ?? 'brak'}'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
widget.updatePageIndex(2); // Ustawiamy indeks strony na 2
},
child: Text('Dalej'),
),
],
);
}
Widget _buildSummaryPage() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Wybrałeś komórkę: ${widget.rowIndex}, ${widget.colIndex}'),
SizedBox(height: 20),
Text('Na 1 widoku wybrałeś: $_firstValue'),
SizedBox(height: 20),
Text('Na 2 widoku wybrałeś: $_secondValue'),
],
);
}
}
kiedy klikam przycisk dowolny w tabeli pojawia się ładnie form:
kiedy z pola select wybieram wartość form ładnie się przeładowuje i pod pole widać wartość którą wybrałem.
Problem pojawia się kiedy klikam dalej bo wtedy nie przeskakuje mi na kolejny widok czyli _buildSecondPage(), nic się nie dzieje.
Jednak kiedy zamknę form i ponownie kliknę przycisk pokaż na tabelce form się już pojawia z kolejnym widokiem, ale już nie ma wartości którą wybrałem na poprzednim widoku:
Generalnie chciałbym dojść do takiego efektu, że za każdym razem jak klikam przycisk Pokaż to pojawia się nowy popup i zawsze ustawia się na pierwszym widoku z nieuzupełnionymi polami.
Jeśli na takim popupie klikam dalej ma się pojawić kolejny widok.
Wie ktoś jak można osiągnąć taki efekt?