为什么 Provider Package 不更改背景图像?
Why isn't the Provider Package changing the background image?
我已将提供程序包添加到我有两个屏幕的应用程序中。当用户点击应用程序上的小图片时,它会更改另一个屏幕上的主背景图片。我在两个屏幕上都调用了 Provider 和 类,但它没有在 Positioned.fill.
中返回 'myValue'
需要更改背景图片的主页屏幕:
import 'package:flutter/material.dart';
import 'package:flutter_app_background/small_images.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
title: Text('Background Image', style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.bold),
),
iconTheme: IconThemeData(color: Colors.white),
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings, color: Colors.black,),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SmallImages()),
);
},
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Stack(
children: <Widget>
[
Positioned.fill(
child: GestureDetector(
child: Consumer<MyModel>(
builder: (context, myModel, child) {
return myModel.bgImage;
// return myValue;
},
),
),
),
],
),
);
}
}
class MyModel extends ChangeNotifier {
Image bgImage = Image.asset('images/background_image.jpeg', fit: BoxFit.fill);
}
用户点击小图像更改主页背景的小图像屏幕。
import 'package:flutter/material.dart';
import 'package:flutter_app_background/main.dart';
import 'package:provider/provider.dart';
class SmallImages extends StatefulWidget {
static int tappedGestureDetector = 1;
@override
_SmallImagesState createState() => _SmallImagesState();
}
class _SmallImagesState extends State<SmallImages> {
List<bool> isSelected;
void initState() {
isSelected = [true, false, false, false, false, false, false, false, false];
super.initState();
}
@override
Widget build(BuildContext context) {
final myModel = Provider.of<MyModel>(context,listen:true); //default for listen is `true`
return Scaffold(
appBar: AppBar(
title: Text('Small Image', style: TextStyle(
color: Colors.black, fontSize: 16, fontWeight: FontWeight.bold),
),
iconTheme: IconThemeData(color: Colors.white),
actions: <Widget>[
IconButton(
icon: Icon(Icons.arrow_left, color: Colors.black,),
onPressed: () {
Navigator.pop(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
},
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Material(
child: GestureDetector(
child: MaterialApp(
builder: (context, snapshot) {
return GridView.count(
crossAxisCount: 1,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 0.0,
crossAxisSpacing: 0.0,
children: [
GridView(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3,
childAspectRatio: MediaQuery
.of(context)
.size
.width /
(MediaQuery
.of(context)
.size
.height / 2),
),
children: [
GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 1;
});
myModel.bgImage = Image.asset('images/iceland_background.jpg');
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 1
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/nightsky_image.png',
),
),
),
Consumer<MyModel>(
builder: (context, myModel, child) {
return GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 2;
}); // <-- replaced 'tapped' and 'other'
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 2
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/own_image.png',
),
),
);
},
),
Consumer<MyModel>(
builder: (context, myModel, child) {
return GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 3;
}); // <-- replaced 'tapped' and 'other'
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 3
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/iceland_image.png',
),
),
);
},
),
].toList(),
),
],
);
}),
),
),
);
}
}
您应该使用提供商包装 material 应用程序:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
);
)
}
}
如果你想让它在 MyModel 发生变化时重建一些小部件,你应该像这样使用 ChangeNotifer 扩展 MyModel:
class MyModel extends ChangeNotifier{
final bgImage = //someimage
而不是 MaterialApp
周围的 Provider,您应该像这样使用 ChangeNotifierProvider
:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
);
)
}
}
之后,您应该像这样在小部件中包含提供程序:
@override
Widget build(BuildContext context) {
final mymodel = Provider.of<MyModel>(context); // injecting the provider
return Container ( .....
你可以像这样在容器内使用背景图片,
color:mymodel.bgImage
一旦您更改,mymodel.bgImage
小部件将自动重建。
如果您打算在 widget tree
中重建特定的 widget
,您可以在这种情况下删除此类注入 final mymodel = Provider.of<MyModel>(context);
并仅包装该特定的 widget
Consumer<MyModel>
像这样:
Container(
child:Consumer<MyModel>(
builder: (context, myModel, child) {
return Text("${myModel.text}"); // supposing that `text` is inside the `MyModel`
},
)
如果您不需要在 Container 下使用 child 和 context,您可以这样做:
child:Consumer<MyModel>(
builder: (_, myModel, _) {
更改 myModel.bgImage
的示例如下所示:
FlatButton(
onPressed: (val){
myModel.image = otherImage // changeing the value of my model while pressing on the button
}
)
在按下按钮时更改我的模型的值将重建任何注入 MyModel Provider
的小部件,并且 Provider listen
属性 设置为 true
,(听属性 默认设置为 true
)
listen
的例子属性:
final mymodel = Provider.of<MyModel>(context,listen:false) //default for listen is `true`
我已将提供程序包添加到我有两个屏幕的应用程序中。当用户点击应用程序上的小图片时,它会更改另一个屏幕上的主背景图片。我在两个屏幕上都调用了 Provider 和 类,但它没有在 Positioned.fill.
中返回 'myValue'需要更改背景图片的主页屏幕:
import 'package:flutter/material.dart';
import 'package:flutter_app_background/small_images.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
title: Text('Background Image', style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.bold),
),
iconTheme: IconThemeData(color: Colors.white),
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings, color: Colors.black,),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SmallImages()),
);
},
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Stack(
children: <Widget>
[
Positioned.fill(
child: GestureDetector(
child: Consumer<MyModel>(
builder: (context, myModel, child) {
return myModel.bgImage;
// return myValue;
},
),
),
),
],
),
);
}
}
class MyModel extends ChangeNotifier {
Image bgImage = Image.asset('images/background_image.jpeg', fit: BoxFit.fill);
}
用户点击小图像更改主页背景的小图像屏幕。
import 'package:flutter/material.dart';
import 'package:flutter_app_background/main.dart';
import 'package:provider/provider.dart';
class SmallImages extends StatefulWidget {
static int tappedGestureDetector = 1;
@override
_SmallImagesState createState() => _SmallImagesState();
}
class _SmallImagesState extends State<SmallImages> {
List<bool> isSelected;
void initState() {
isSelected = [true, false, false, false, false, false, false, false, false];
super.initState();
}
@override
Widget build(BuildContext context) {
final myModel = Provider.of<MyModel>(context,listen:true); //default for listen is `true`
return Scaffold(
appBar: AppBar(
title: Text('Small Image', style: TextStyle(
color: Colors.black, fontSize: 16, fontWeight: FontWeight.bold),
),
iconTheme: IconThemeData(color: Colors.white),
actions: <Widget>[
IconButton(
icon: Icon(Icons.arrow_left, color: Colors.black,),
onPressed: () {
Navigator.pop(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
},
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Material(
child: GestureDetector(
child: MaterialApp(
builder: (context, snapshot) {
return GridView.count(
crossAxisCount: 1,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 0.0,
crossAxisSpacing: 0.0,
children: [
GridView(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3,
childAspectRatio: MediaQuery
.of(context)
.size
.width /
(MediaQuery
.of(context)
.size
.height / 2),
),
children: [
GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 1;
});
myModel.bgImage = Image.asset('images/iceland_background.jpg');
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 1
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/nightsky_image.png',
),
),
),
Consumer<MyModel>(
builder: (context, myModel, child) {
return GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 2;
}); // <-- replaced 'tapped' and 'other'
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 2
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/own_image.png',
),
),
);
},
),
Consumer<MyModel>(
builder: (context, myModel, child) {
return GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 3;
}); // <-- replaced 'tapped' and 'other'
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 3
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/iceland_image.png',
),
),
);
},
),
].toList(),
),
],
);
}),
),
),
);
}
}
您应该使用提供商包装 material 应用程序:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
);
)
}
}
如果你想让它在 MyModel 发生变化时重建一些小部件,你应该像这样使用 ChangeNotifer 扩展 MyModel:
class MyModel extends ChangeNotifier{
final bgImage = //someimage
而不是 MaterialApp
周围的 Provider,您应该像这样使用 ChangeNotifierProvider
:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
);
)
}
}
之后,您应该像这样在小部件中包含提供程序:
@override
Widget build(BuildContext context) {
final mymodel = Provider.of<MyModel>(context); // injecting the provider
return Container ( .....
你可以像这样在容器内使用背景图片,
color:mymodel.bgImage
一旦您更改,mymodel.bgImage
小部件将自动重建。
如果您打算在 widget tree
中重建特定的 widget
,您可以在这种情况下删除此类注入 final mymodel = Provider.of<MyModel>(context);
并仅包装该特定的 widget
Consumer<MyModel>
像这样:
Container(
child:Consumer<MyModel>(
builder: (context, myModel, child) {
return Text("${myModel.text}"); // supposing that `text` is inside the `MyModel`
},
)
如果您不需要在 Container 下使用 child 和 context,您可以这样做:
child:Consumer<MyModel>(
builder: (_, myModel, _) {
更改 myModel.bgImage
的示例如下所示:
FlatButton(
onPressed: (val){
myModel.image = otherImage // changeing the value of my model while pressing on the button
}
)
在按下按钮时更改我的模型的值将重建任何注入 MyModel Provider
的小部件,并且 Provider listen
属性 设置为 true
,(听属性 默认设置为 true
)
listen
的例子属性:
final mymodel = Provider.of<MyModel>(context,listen:false) //default for listen is `true`