颤振小部件中的可见性没有改变
Posted
技术标签:
【中文标题】颤振小部件中的可见性没有改变【英文标题】:Visibility is not changing in a flutter widget 【发布时间】:2021-07-19 20:02:05 【问题描述】:每当我尝试更改可见性状态时,setState 不起作用,尽管在控制台中打印了消息已得到纠正。这是我的浮动操作按钮,周围有几个小部件。问题是每当我单击它时,isVisible 属性应该已更改为 false 并且它应该是不可见的,但不会发生。 “按下的撤消”打印在控制台中。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:maya/screens/profile.dart';
import 'package:maya/screens/screen.dart';
import 'package:maya/screens/settings.dart';
import 'package:avatar_glow/avatar_glow.dart';
import 'package:tcard/tcard.dart';
import 'package:glass_kit/glass_kit.dart';
import 'package:fluttertoast/fluttertoast.dart';
class MainPage extends StatefulWidget
@override
_MainPageState createState() => _MainPageState();
class _MainPageState extends State<MainPage>
double likeBtnWidth = 75;
double dislikeBtnWidth = 75;
TCardController _controller = TCardController();
int cardNumber;
bool isVisible; //here is the declaration
Widget _layoutDetails()
@override
Orientation orientation = MediaQuery.of(context).orientation;
setState(()
likeBtnWidth = 150;
dislikeBtnWidth = 150;
);
List<String> images = [
'assets/images/girls/girl1.png',
'assets/images/girls/girl2.png',
'assets/images/girls/girl3.png',
'assets/images/girls/girl4.png',
'assets/images/girls/girl5.png',
'assets/images/girls/girl6.png',
];
List<String> personalDetails = [
'Prakriti Regmi%20%Lets read Murakami together.%Chabahil (1 mi away)',
'Dristi Sigdel%19%Belle áme%Sundhara (2 mi away)',
'Prajita Upreti%19%Here to make friends.%Makalbari (2.3 mi away)',
'Sugandhi C.%21%Not looking for any drama.%Bhaktapur (7 mi away)',
"Pawana Shrestha%20%Why am I here for?%Attarkhel",
"Tanuja Shrestha%21%Hi there! ♐︎%Dakshin Dhoka"
];
List<Widget> cards = List.generate(
images.length < personalDetails.length
? images.length
: personalDetails.length,
(int index)
return GlassContainer.frostedGlass(
height: 800,
width: 800,
child: Padding(
padding: const EdgeInsets.fromLTRB(30, 20, 30, 0),
child: Container(
child: Stack(
children: [
Column(
children: [
SizedBox(
height: 20,
),
Center(child: _picture(images[index])),
SizedBox(
height: 30,
),
_bio(personalDetails[index].split("%")),
SizedBox(
height: 10,
),
_likeUnlikeButtons()
],
),
Positioned(
left: 0,
bottom: 15,
child: SizedBox(
width: 30,
child: Visibility(
visible: isVisible,
child: FloatingActionButton(
onPressed: ()
setState(()
isVisible = false; //this is the problamatic part.
print("pressed undo");
);
,
child: Text("helllllo"),
)
replacement: Container(),
),
),
),
],
),
)),
);
// );
,
);
return SizedBox(
width: double.infinity,
height: double.infinity,
child: TCard(
controller: _controller,
onForward: (index, info)
if (info.direction == SwipDirection.Right)
Fluttertoast.showToast(
msg: "Liked",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForiosWeb: 1,
backgroundColor: Colors.yellow,
textColor: Colors.black,
fontSize: 16.0);
setState(()
isFirstCard = false;
);
,
onBack: (index, info)
// _controller.forward(SwipDirection);
// print(index);
,
onEnd: ()
_controller.reset();
,
size: Size(double.infinity, double.infinity),
cards: cards,
),
);
);
@override
Widget build(BuildContext context)
return _layoutDetails();
),
);
【问题讨论】:
【参考方案1】:您可以尝试将 _layoutDetails() Widget 树中的值放入
@override
Widget build(BuildContext context)
这样每次调用 setState 函数时,它都会重新构建小部件树。
像这样:
@override
Widget build(BuildContext context)
return ListView.builder(
itemCount: personalDetails.length,
itemBuilder: (context, index)
return GlassContainer.frostedGlass(
height: 800,
width: 800,
child: Padding(
padding: const EdgeInsets.fromLTRB(30, 20, 30, 0),
child: Container(
child: Stack(
children: [
Column(
children: [
SizedBox(
height: 20,
),
Center(child: _picture(images[index])),
SizedBox(
height: 30,
),
_bio(personalDetails[index].split("%")),
SizedBox(
height: 10,
),
_likeUnlikeButtons()
],
),
Positioned(
left: 0,
bottom: 15,
child: SizedBox(
width: 30,
child: Visibility(
visible: isVisible,
child: FloatingActionButton(
onPressed: ()
setState(()
isVisible = false; //this is the problamatic part.
print("pressed undo");
);
,
child: Text("helllllo"),
)
replacement: Container(),
),
),
),
],
),
)),
);
,);
您可以在函数 _layoutDetails 之外声明 List,以便构建方法可以访问它。
/// Populate data for list.
List<String> personalDetails = [
'Prakriti Regmi%20%Lets read Murakami together.%Chabahil (1 mi away)',
'Dristi Sigdel%19%Belle áme%Sundhara (2 mi away)',
'Prajita Upreti%19%Here to make friends.%Makalbari (2.3 mi away)',
'Sugandhi C.%21%Not looking for any drama.%Bhaktapur (7 mi away)',
"Pawana Shrestha%20%Why am I here for?%Attarkhel",
"Tanuja Shrestha%21%Hi there! ♐︎%Dakshin Dhoka"
];
List<String> images = [
'assets/images/girls/girl1.png',
'assets/images/girls/girl2.png',
'assets/images/girls/girl3.png',
'assets/images/girls/girl4.png',
'assets/images/girls/girl5.png',
'assets/images/girls/girl6.png',
];
【讨论】:
没有帮助。 :( 你怎么能说它没有帮助呢?首先,为什么要在方法中提取 Widget Tree? 我的意思是说,构建器的列表视图弄乱了我的整个用户界面,并将方向更改为垂直,忽略了大多数属性。 构建器只是根据您的 _layoutDetails 方法中的内容构建 Widget 树配置。如果它在 _layoutDetails 中有效,那么您期望的格式或 ui 设计也必须反映在构建器中。【参考方案2】:我个人使用 Provider 进行状态管理,但这是我演示使用 setState 更改值的最快方法。在我看来,您正在尝试更新方法内部的状态,而不是更新正在显示的构建上下文内部的状态。由于 setState 是在 build 方法之外调用的,所以 build 方法不知道要使用新值进行重建。
import 'package:flutter/material.dart';
void main()
runApp(MaterialApp(
home: MainPage(),
));
class MainPage extends StatefulWidget
@override
_MainPageState createState() => _MainPageState();
class _MainPageState extends State<MainPage>
Color go = Colors.green;
Color stop = Colors.red;
// the variable we are tracking the state of
bool stackIsGo;
// custom widget that takes a bool as input
Widget _moreWidgets(bool changeColor)
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: changeColor ? Colors.greenAccent : Colors.deepPurple,
height: 44,
width: 44,
),
],
);
@override
Widget build(BuildContext context)
// the variable the build context is going to build with.
// since stackIsGo hasn't been given a value yet, and we can't // initialize a null value, if stackIsGo is null we assign
// true to changeVisibility.
bool changeVisibility = stackIsGo ?? true;
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Center(
child: Stack(
children: [
Container(
height: 44,
width: 44,
//
color: changeVisibility ? go : stop,
),
Positioned.fill(
child: Visibility(
//
visible: !changeVisibility,
replacement: SizedBox.shrink(),
child: Icon(Icons.warning_rounded),
),
),
],
),
),
FloatingActionButton(
child: Icon(Icons.visibility),
onPressed: ()
setState(()
// by using setState inside of the build method,
// we trigger a widget rebuild with the new value.
if (stackIsGo == null) stackIsGo = true;
stackIsGo = !stackIsGo;
);
,
),
_moreWidgets(changeVisibility),
],
),
);
【讨论】:
但如果我这样做,浮动操作按钮中将无法识别该变量。我将如何获取它?以上是关于颤振小部件中的可见性没有改变的主要内容,如果未能解决你的问题,请参考以下文章