![](/img/trans.png)
[英]How to pass image picker file from one page to another in flutter dart?
[英]Pass data from one page to another in Flutter
我知道有很多這樣的問題,但我是 Flutter 的新手,我還沒有找到適合我需求的帖子,或者我只是想錯了。
我基本上有settings.dart
和home.dart
。 現在,我想做的是基於米_isMetresChecked
或英尺_isFeetChecked
的復選框值,更改主屏幕上的單位,但不要立即切換到主屏幕,允許用戶繼續配置設置(最終還有更多內容要添加),當他們返回主屏幕時,它會更新。 我嘗試使用類SettingsData
作為合並所有配置的一種方式,然后通過Navigator
傳遞它,但盡管我沒有成功,但它不會讓我允許用戶停留在“設置”頁面上。
那么如何在不切換視圖的情況下在視圖之間傳遞數據呢?
家.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'applicationbar.dart';
import 'navigationdrawer.dart';
import 'bluetooth.dart';
class LuggageFollowerMain extends StatefulWidget {
@override
_LuggageFollowerMainState createState() => _LuggageFollowerMainState();
}
class _LuggageFollowerMainState extends State<LuggageFollowerMain> {
String _string = '0m'; //so if _isFeetChecked is true in settings.dart this is '0ft'
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[900],
appBar: ApplicationBar(title: 'Luggage Follower'),
drawer: NavigationDrawer(),
body:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: Text('Luggage Status', style: Theme.of(context).textTheme.body2),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: Text('Paired', style: Theme.of(context).textTheme.body1),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 20,horizontal: 0),
child: Divider(height: 3.0, color: Colors.pinkAccent, indent: 150, endIndent: 150),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: Text('Distance to Luggage', style: Theme.of(context).textTheme.body2),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: Text(_string, style: Theme.of(context).textTheme.body1), //dynamic text here
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: LuggageFollow(),
),
],
),
);
}
}
設置.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audio_cache.dart';
import 'applicationbar.dart';
import 'navigationdrawer.dart';
class SettingsData {
bool feet;
bool metres;
SettingsData({this.feet, this.metres});
}
class Settings extends StatefulWidget {
@override
_SettingsState createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
static bool _isFeetChecked = false;
static bool _isMetersChecked = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: ApplicationBar(title: 'Settings'),
drawer: NavigationDrawer(),
body: Column(
//crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 20),
child: Text('Distance Units')
),
Divider(
height: 3.0,
color: Colors.pink,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 0),
child: CheckboxListTile(
title: Text('Distance in feet', style: Theme.of(context).textTheme.body1),
value: _isFeetChecked,
onChanged: (bool value) {
setState(() {
_isFeetChecked = value; _isMetersChecked = !value;});
},
checkColor: Colors.white,
activeColor: Colors.pink,
subtitle: Text('1 foot ~ 0.3 metres',style: Theme.of(context).textTheme.display2),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 0),
child: CheckboxListTile(
title: Text('Distance in metres', style: Theme.of(context).textTheme.body1),
value: _isMetersChecked,
onChanged: (bool value) {
setState(() { _isMetersChecked = value; _isFeetChecked = !value;updateData();});
},
checkColor: Colors.white,
activeColor: Colors.pink,
subtitle: Text('1 metre ~ 3 feet',style: Theme.of(context).textTheme.display2),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 30.0,horizontal: 20),
child: Text('Notifications')
),
Divider(
height: 3.0,
color: Colors.pink,
),
),
),
],
),
);
}
}
我知道有很多這樣的問題,但是我對Flutter還是陌生的,我還沒有找到適合我需求的帖子,或者我只是在想錯了。
我基本上有settings.dart
和home.dart
。 現在,我要基於米_isMetresChecked
或英尺_isFeetChecked
的復選框值,在主屏幕上更改單位,但不要立即切換到主屏幕,允許用戶繼續配置設置(最終還有更多內容要添加),然后當他們返回主屏幕時,它就會更新。 我嘗試使用SettingsData
類作為合並所有配置,然后通過Navigator
傳遞它的一種方法,但是盡管我沒有成功,但不允許我讓用戶停留在“ Settings”頁面上。
那么,如何在視圖之間傳遞數據而又不切換視圖?
飛鏢
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'applicationbar.dart';
import 'navigationdrawer.dart';
import 'bluetooth.dart';
class LuggageFollowerMain extends StatefulWidget {
@override
_LuggageFollowerMainState createState() => _LuggageFollowerMainState();
}
class _LuggageFollowerMainState extends State<LuggageFollowerMain> {
String _string = '0m'; //so if _isFeetChecked is true in settings.dart this is '0ft'
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[900],
appBar: ApplicationBar(title: 'Luggage Follower'),
drawer: NavigationDrawer(),
body:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: Text('Luggage Status', style: Theme.of(context).textTheme.body2),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: Text('Paired', style: Theme.of(context).textTheme.body1),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 20,horizontal: 0),
child: Divider(height: 3.0, color: Colors.pinkAccent, indent: 150, endIndent: 150),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: Text('Distance to Luggage', style: Theme.of(context).textTheme.body2),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: Text(_string, style: Theme.of(context).textTheme.body1), //dynamic text here
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
child: LuggageFollow(),
),
],
),
);
}
}
settings.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audio_cache.dart';
import 'applicationbar.dart';
import 'navigationdrawer.dart';
class SettingsData {
bool feet;
bool metres;
SettingsData({this.feet, this.metres});
}
class Settings extends StatefulWidget {
@override
_SettingsState createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
static bool _isFeetChecked = false;
static bool _isMetersChecked = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: ApplicationBar(title: 'Settings'),
drawer: NavigationDrawer(),
body: Column(
//crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 20),
child: Text('Distance Units')
),
Divider(
height: 3.0,
color: Colors.pink,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 0),
child: CheckboxListTile(
title: Text('Distance in feet', style: Theme.of(context).textTheme.body1),
value: _isFeetChecked,
onChanged: (bool value) {
setState(() {
_isFeetChecked = value; _isMetersChecked = !value;});
},
checkColor: Colors.white,
activeColor: Colors.pink,
subtitle: Text('1 foot ~ 0.3 metres',style: Theme.of(context).textTheme.display2),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 0),
child: CheckboxListTile(
title: Text('Distance in metres', style: Theme.of(context).textTheme.body1),
value: _isMetersChecked,
onChanged: (bool value) {
setState(() { _isMetersChecked = value; _isFeetChecked = !value;updateData();});
},
checkColor: Colors.white,
activeColor: Colors.pink,
subtitle: Text('1 metre ~ 3 feet',style: Theme.of(context).textTheme.display2),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 30.0,horizontal: 20),
child: Text('Notifications')
),
Divider(
height: 3.0,
color: Colors.pink,
),
),
),
],
),
);
}
}
因此,首先您只需要 1 個布爾值即可進行測量。 它要么是英尺,要么是米。 所以這簡化了一些事情。 這是一個使用回調函數設置父小部件中狀態更改的示例。 這只是可以完成的許多方法中的一種,可能還有其他您可能更喜歡的方法。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LuggageFollowerMain(),
);
}
}
class Settings extends StatefulWidget {
//Static references to our parent widget varibles
final bool isM;
final changeMeeters;
Settings(bool isM, changeMeeters(bool meeters)):
this.isM = isM,
this.changeMeeters = changeMeeters
;
@override
_SettingsState createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
@override
void initState() {
super.initState();
//set our varible state to be that of the parent screen
//isMeeters is a local var to Settings and is changeable.
//isM is a static and can't be changed. isM was passed in
//from our home screen. We need a changeable var or the
//checkboxes won't update correctly. Thats why we need
//isMeeters (lol bad spelling). When the settings screen
//first loads we use initState to take the value of
//isM(from our home screen) and copy it into isMeeters
//as it's initial value before it is built and shown
//to the user for the first time.
isMeeters = widget.isM;
}
//our varible to use for our check boxes
var isMeeters;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 20),
child: Text('Distance Units')),
Divider(
height: 3.0,
color: Colors.pink,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 0),
child: CheckboxListTile(
title: Text('Distance in feet',
style: Theme.of(context).textTheme.body1),
//use the local var change when tapped
value: isMeeters,
onChanged: (bool value) {
setState(() {
isMeeters = true;
});
//call back to the parent widget so it can be updated
widget.changeMeeters(true);
},
checkColor: Colors.white,
activeColor: Colors.pink,
subtitle: Text('1 foot ~ 0.3 metres',
style: Theme.of(context).textTheme.display2),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 0),
child: CheckboxListTile(
title: Text('Distance in metres',
style: Theme.of(context).textTheme.body1),
//use the local var change when tapped. Use ! to invert the bool. This way only one is needed.
value: !isMeeters,
onChanged: (bool value) {
setState(() {
isMeeters = false;
});
//call back to the parent widget so it can be updated
widget.changeMeeters(false);
},
checkColor: Colors.white,
activeColor: Colors.pink,
subtitle: Text('1 metre ~ 3 feet',
style: Theme.of(context).textTheme.display2),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 30.0, horizontal: 20),
child: Text('Notifications')),
Divider(
height: 3.0,
color: Colors.pink,
),
],
),
);
}
}
class LuggageFollowerMain extends StatefulWidget {
@override
_LuggageFollowerMainState createState() => _LuggageFollowerMainState();
}
class _LuggageFollowerMainState extends State<LuggageFollowerMain> {
//store the distance as a number not a string
double distance = 0.0;
//store the measurement type setting
bool isMeeters = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Settings(isMeeters, (newMeeters){
//when we get our callback from settings we set the change to the home screen var here
setState(() {
isMeeters = newMeeters;
});
})),
);
},
),
backgroundColor: Colors.grey[900],
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 0),
child: Text('Luggage Status',
style: Theme.of(context).textTheme.body2),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 0),
child: Text('Paired', style: Theme.of(context).textTheme.body1),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 0),
child: Divider(
height: 3.0,
color: Colors.pinkAccent,
indent: 150,
endIndent: 150),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 0),
child: Text('Distance to Luggage',
style: Theme.of(context).textTheme.body2),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 0),
//use the new number var and change it's suffix m or f depending on what our setting is.
child: Text(distance.toString() + (isMeeters ? "m" : "f"),
style: Theme.of(context).textTheme.body1), //dynamic text here
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 0),
),
],
),
);
}
}
要將數據從一個頁面傳遞到另一個頁面,您可以使用向命名路由傳遞參數。
下面是通過參數的方式在設置頁面之間傳遞布爾值的最小示例。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
routes: {
"home": (BuildContext homeContext) => HomePage(),
"settings": (BuildContext settingsContext) => SettingsPage(),
},
initialRoute: "home",
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool _isMetersAccordingToHomePage = false;
void _updateIsMetersAccordingToHomePage(bool _value) {
setState(() {
_isMetersAccordingToHomePage = _value ?? _isMetersAccordingToHomePage;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Home Page")),
body: Column(
children: <Widget>[
Text("Is Displayed in meters? $_isMetersAccordingToHomePage"),
RaisedButton(
onPressed: () {
// This is the important part
Navigator.of(context)
.pushNamed(
"settings",
// we are passing a value to the settings page
arguments: _isMetersAccordingToHomePage,
)
// and then, when we `pop` from the settings page,
// we will get back an updated value
.then(
(_isMetersAccordingToSettingsPage) {
_updateIsMetersAccordingToHomePage(
_isMetersAccordingToSettingsPage);
},
);
},
child: Text("Go to Settings Page"),
),
],
),
);
}
}
class SettingsPage extends StatefulWidget {
@override
_SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
bool _isMetersAccordingToSettingsPage;
void _updateIsMetersAccordingToSettingsPage(bool _value) {
setState(() {
_isMetersAccordingToSettingsPage = _value;
});
}
@override
Widget build(BuildContext context) {
bool _isMetersAccordingToHomePage =
ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text("Setting Page"),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop<bool>(_isMetersAccordingToSettingsPage);
},
),
),
body: Column(
children: <Widget>[
CheckboxListTile(
value: _isMetersAccordingToSettingsPage ??
_isMetersAccordingToHomePage ??
false,
onChanged: _updateIsMetersAccordingToSettingsPage,
title: Text("Display in meters?"),
),
],
),
);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.