flutter - 为什么提供程序包不更改背景图像?
问题描述
我已将提供程序包添加到我有两个屏幕的应用程序中。当用户单击应用程序上的小图像时,它会更改另一个屏幕上的主背景图像。我在两个屏幕上都调用了 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(),
),
],
);
}),
),
),
);
}
}
解决方案
您应该用提供者包装材料应用程序:
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
而不是周围的 ProviderMaterialApp
你应该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
在. widget tree
_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`
},
)
如果您不需要在容器下使用子项和上下文,您可以这样做:
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
并且 Providerlisten
属性设置为,(默认情况下true
,listen 属性设置为)true
属性示例listen
:
final mymodel = Provider.of<MyModel>(context,listen:false) //default for listen is `true`
推荐阅读
- shell - 在 Fish shell 中收到错误“cd: '/Users/x/Downloads/' is a rotten symlink”
- python - 斜线选项发送嵌入
- r - 如何在面板数据r中绘制滞后变量
- visual-studio-code - VSCode - 如何使用另一种编码缩小文件?
- javascript - 热计算逗号并将其分隔在一个数组中?
- php - 显示有关用户角色和帖子 ID 的内容
- cloudflare-workers - Cloudflare 工作人员的安全性和可见性
- excel - Excel VBA - 如果未选中框,则清除单元格
- javascript - 如何避免 setTimeout 被覆盖?
- java - 从 Android 手机设备访问 RaspberryPi (Linux)