У меня проблема с моим приложением...
Я хочу передать виджету на других страницах только два «двойных» аргумента, когда пользователь использует ElevatedButton, и восстановить аргументы для установки координат в Картах.
Я пробовал все способы сделать это, прочитав документ на Flutter.dev, но ничего из того, что я получаю, не равно Null...
Основной дротик:
import 'package:flutter/material.dart';
import 'package:booki3/route/route.dart' as route;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}): super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Booking',
theme: ThemeData(
primarySwatch: Colors.blue,
),
onGenerateRoute: route.controller,
initialRoute: route.home,
);
}
}
Главная.дротик:
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:booki3/views/maps.dart';
import 'package:booki3/route/route.dart' as route;
const dgreen = Color(0xFF54D3C2);
class HomePage extends StatelessWidget {
const HomePage({Key? key}): super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const MyAppBar(),
body: SingleChildScrollView(
child: Column(
children: [
const SearchSection(),
HotelSection(),
],
),
));
}
}
class Data {
double coordx = 45.20;
double coordy = 20.50;
}
class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
const MyAppBar({Key? key}): super(key: key);
@override
Size get preferredSize => const Size.fromHeight(50);
@override
Widget build(BuildContext context) {
return AppBar(
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.grey[800],
size: 20,
),
onPressed: null,
),
title: Text(
'Explore',
style: GoogleFonts.nunito(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.w800,
),
),
centerTitle: true,
actions: [
IconButton(
icon: Icon(
Icons.favorite_outline_rounded,
color: Colors.grey[800],
size: 20,
),
onPressed: null,
),
IconButton(
icon: Icon(
Icons.place,
color: Colors.grey[800],
size: 20,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MyMaps(data: Data),
),
);
},
),
],
backgroundColor: Colors.white,
);
}
}
Карты.дарт:
В строке 25 я ставлю случайные значения, потому что иначе страница не откроется... В конце я хочу поставить значения Data. Но пока не могу их вернуть.
import 'package:booki3/views/home.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class MyMaps extends StatefulWidget {
const MyMaps({Key? key, required data}): super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyMaps> {
late GoogleMapController mapController;
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
@override
Widget build(BuildContext context) {
final data = ModalRoute.of(context)!.settings.arguments as Data;
debugPrint(data.toString());
LatLng _center = const LatLng(25.32, 2.5); // <= Two 'double' of Data..
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Maps Sample App'),
backgroundColor: Colors.green[700],
),
body: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 11.0,
),
),
),
);
}
}
Маршрут.дарт:
import 'package:flutter/material.dart';
import 'package:booki3/views/home.dart';
import 'package:booki3/views/maps.dart';
const String home = "home";
const String maps = "maps";
Route<dynamic> controller(RouteSettings settings) {
switch (settings.name) {
case home:
return MaterialPageRoute(builder: (context) => const HomePage());
case maps:
return MaterialPageRoute(
builder: (context) => const MyMaps(
data: Data,
),
settings: const RouteSettings(
arguments: Data,
),
);
default:
throw ('This route name not exist');
}
}
С решением Daniel у меня есть это сообщение об ошибке:
Сообщение об ошибке
Новый дом.дарт:
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:booki3/views/maps.dart';
import 'package:booki3/route/route.dart' as route;
const dgreen = Color(0xFF54D3C2);
class HomePage extends StatelessWidget {
const HomePage({Key? key}): super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const MyAppBar(),
body: SingleChildScrollView(
child: Column(
children: [
const SearchSection(),
HotelSection(),
],
),
));
}
}
class Data {
double coordx = 45.20;
double coordy = 20.50;
@override
String toString() => 'Data(coordx: $coordx, coordy: $coordy)'; // just to prin
}
class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
const MyAppBar({Key? key}): super(key: key);
@override
Size get preferredSize => const Size.fromHeight(50);
@override
Widget build(BuildContext context) {
return AppBar(
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.grey[800],
size: 20,
),
onPressed: null,
),
title: Text(
'Explore',
style: GoogleFonts.nunito(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.w800,
),
),
centerTitle: true,
actions: [
IconButton(
icon: Icon(
Icons.favorite_outline_rounded,
color: Colors.grey[800],
size: 20,
),
onPressed: null,
),
IconButton(
icon: Icon(
Icons.place,
color: Colors.grey[800],
size: 20,
),
onPressed: () {
Navigator.of(context).pushNamed(
route.maps,
arguments: Data,
);
},
),
],
backgroundColor: Colors.white,
);
}
}
Новый маршрут.dart:
import 'package:flutter/material.dart';
import 'package:booki3/views/home.dart';
import 'package:booki3/views/maps.dart';
const String home = "home";
const String maps = "maps";
Route<dynamic> controller(RouteSettings settings) {
final args = settings.arguments; // get the arguments here
switch (settings.name) {
case home:
return MaterialPageRoute(builder: (context) => const HomePage());
case maps:
return MaterialPageRoute(
builder: (context) => MyMaps(
data: args as Data,
),
);
default:
throw ('This route name not exist');
}
}
Новые карты.dart:
import 'package:booki3/views/home.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class MyMaps extends StatefulWidget {
const MyMaps({
Key? key,
required this.data,
}): super(key: key);
final Data data;
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyMaps> {
late GoogleMapController mapController;
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
@override
Widget build(BuildContext context) {
final data = widget.data;
debugPrint(data.toString());
LatLng _center = LatLng(data.coordx, data.coordy);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Maps Sample App'),
backgroundColor: Colors.green[700],
),
body: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 11.0,
),
),
),
);
}
}
Заранее благодарю вас за вашу помощь, потому что я больше не знаю, что делать.. Я чувствую, что перепробовал все..
Люблю тебя;)
Решение проблемы
Ok, let's go step by step, in the Data class I only put the toString so that when you print it the values are displayed (nothing revealing).
The problem comes when you want to send ALL the class to the page Maps which is not possible (in this case), what you have to send is an instance of that class, therefore we create it.
On the other hand you will use pushNamed since you yourself are telling it that they are called "home", or "maps" in the routes, so we are going to use them, not to create another MaterialPageRoute if they are already in your routes, you got it?
Home:
class Data {
double coordx = 45.20;
double coordy = 20.50;
@override
String toString() => 'Data(coordx: $coordx, coordy: $coordy)'; // just to print
}
class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
const MyAppBar({Key? key}): super(key: key);
@override
Size get preferredSize => const Size.fromHeight(50);
@override
Widget build(BuildContext context) {
final newData = Data(); // new instance creation
return AppBar(
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.grey[800],
size: 20,
),
onPressed: null,
),
title: const Text(
'Explore',
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.w800,
),
),
centerTitle: true,
actions: [
IconButton(
icon: Icon(
Icons.favorite_outline_rounded,
color: Colors.grey[800],
size: 20,
),
onPressed: null,
),
IconButton(
icon: Icon(
Icons.place,
color: Colors.grey[800],
size: 20,
),
onPressed: () {
Navigator.of(context).pushNamed( // using pushNamed not push
"maps",
arguments: newData, // send the instance
);
},
),
],
backgroundColor: Colors.white,
);
}
}
Routes:
Route<dynamic> controller(RouteSettings settings) {
final args = settings.arguments; // get the arguments here
switch (settings.name) {
case home:
return MaterialPageRoute(builder: (context) => const HomePage());
case maps:
return MaterialPageRoute(
builder: (context) => MyMaps( // we delete the settings and pass directly in the MyMaps
data: args as Data,
),
);
default:
throw ('This route name not exist');
}
}
Наконец, когда экземпляр создан, затем отправлен аргументами на маршруты и, наконец, прибыл сюда, чтобы получить этот экземпляр, мы просто добавляем конечную переменную и в его конструктор.
И осталось только вставить его в свой LatLng!:D
Карты:
class MyMaps extends StatefulWidget {
const MyMaps({
Key? key,
required this.data, // here in constructor
}): super(key: key);
final Data data; // final variable
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyMaps> {
late GoogleMapController mapController;
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
@override
Widget build(BuildContext context) {
final data = widget.data; // get the data that comes
debugPrint(data.toString());
LatLng _center = LatLng(
data.coordx,
data.coordy,
); // voila!
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Maps Sample App'),
backgroundColor: Colors.green[700],
),
body: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 11.0,
),
),
),
);
}
}
Комментариев нет:
Отправить комментарий