为什么我的ListView.builder在Flutter中使用setState后没有更新?

huangapple go评论110阅读模式
英文:

Why is my listview.builder not updating with setstate in flutter

问题

    class _ProjectDrawerState extends State<ProjectDrawer> {
  

    @override
      Widget build(BuildContext context) {
        double height = MediaQuery.of(context).size.height;
        double width = MediaQuery.of(context).size.width;
        bool showMore = false;
        print('ls Length --- ${widget.ls.length}');
        void toggleShowMore()
        {
          print('Inside toggleshowMore original value --- $showMore');
          setState(() {
            showMore = !showMore;
          });
          print('Inside toggleshowMOre updated value --- $showMore');
        }
        return Scaffold(
            body: SafeArea(
          child: Container(
            margin: EdgeInsets.only(
                left: 0.04 * width,
                right: 0.04 * width,
                top: 0.14 * height,
                bottom: 0.1 * height),
            decoration: BoxDecoration(
              color: const Color(0xffefefef),
              borderRadius: BorderRadius.circular(0.037 * width),
            ),
            child:  SingleChildScrollView(
                  child: IntrinsicHeight(
                    child: ResponsiveRowColumnItem(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: [
                          Container(
                            height: /*showMore ? (widget.ls.length * height * 0.025) :*/ height * 0.25,
                                      child: ListView.builder(
                                        physics:
                                            const AlwaysScrollableScrollPhysics(),
                                        itemCount: showMore ? widget.ls.length : 4,
                                        itemBuilder:
                                            (BuildContext context, int index) {
                                          print('ShowMore value inside ListView.builder  --- $showMore');
                                          return SingleChildScrollView(
                                            child: ListTile(
                                              dense: true,
                                              title: Row(
                                                children: [
                                                  SizedBox(
                                                    width: width * 0.0255,
                                                  ),
                                                  Image.asset(
                                                      'assets/logo.png',
                                                      width: 24,
                                                      height: 24),
                                                  Text(
                                                    '        ${widget.ls[index]}',
                                                    textAlign: TextAlign.center,
                                                    style: const TextStyle(
                                                        color: Colors.black,
                                                        fontFamily: 'Roboto',
                                                        fontSize: 18,
                                                        letterSpacing: 0,
                                                        fontWeight:
                                                            FontWeight.normal,
                                                        height: 1),
                                                  ),
                                                ],
                                              ),
                                            ),
                                          );
                                        },
                                      ),
                                    ),
                          MaterialButton(
                            onPressed: toggleShowMore,
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              crossAxisAlignment: CrossAxisAlignment.center,
                              children: [
                                SizedBox(
                                  width: width * 0.22,
                                  child: const Divider(
                                      color: Color(0xffbdbdbd),
                                      thickness: 1.5,
                                      height: 0.05),
                                ),
                                Text(
                                  showMore ? 'See Less' : 'See more',
                                  style: const TextStyle(
                                    fontFamily: 'Roboto',
                                    fontSize: 18,
                                    fontWeight: FontWeight.w600,
                                    color: Color(0xff000000),
                                  ),
                                ),
                                Icon(
                                  showMore ? Icons.arrow_drop_up_sharp : Icons.arrow_drop_down_sharp,
                                  color: Colors.black,
                                  size: 40,
                                ),
                                SizedBox(
                                  width: width * 0.2,
                                  child: const Divider(
                                      color: Color(0xffbdbdbd),
                                      thickness: 1.5,
                                      height: 0.05),
                            ),
                          ],
                        ),
                      ),
                    ],
                ),
              ),
            )),
        ),
      ));
  }
}
英文:
class _ProjectDrawerState extends State<ProjectDrawer> {
@override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
bool showMore = false;
print('ls Length --- ${widget.ls.length}');
void toggleShowMore()
{
print('Inside toggleshowMore original value --- $showMore');
setState(() {
showMore = !showMore;
});
print('Inside toggleshowMOre updated value --- $showMore');
}
return Scaffold(
body: SafeArea(
child: Container(
margin: EdgeInsets.only(
left: 0.04 * width,
right: 0.04 * width,
top: 0.14 * height,
bottom: 0.1 * height),
decoration: BoxDecoration(
color: const Color(0xffefefef),
borderRadius: BorderRadius.circular(0.037 * width),
),
child:  SingleChildScrollView(
child: IntrinsicHeight(
child: ResponsiveRowColumnItem(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: /*showMore ? (widget.ls.length * height * 0.025) :*/ height * 0.25,
child: ListView.builder(
physics:
const AlwaysScrollableScrollPhysics(),
itemCount: showMore ? widget.ls.length : 4,
itemBuilder:
(BuildContext context, int index) {
print('ShowMore value inside ListView.builder  --- $showMore');
return SingleChildScrollView(
child: ListTile(
dense: true,
title: Row(
children: [
SizedBox(
width: width * 0.0255,
),
Image.asset(
'assets/logo.png',
width: 24,
height: 24),
Text(
'        ${widget.ls[index]}',
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.black,
fontFamily: 'Roboto',
fontSize: 18,
letterSpacing: 0,
fontWeight:
FontWeight.normal,
height: 1),
),
],
),
),
);
},
),
),
MaterialButton(
onPressed: toggleShowMore,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: width * 0.22,
child: const Divider(
color: Color(0xffbdbdbd),
thickness: 1.5,
height: 0.05),
),
Text(
showMore ? 'See Less' : 'See more',
style: const TextStyle(
fontFamily: 'Roboto',
fontSize: 18,
fontWeight: FontWeight.w600,
color: Color(0xff000000),
),
),
Icon(
showMore ? Icons.arrow_drop_up_sharp : Icons.arrow_drop_down_sharp,
color: Colors.black,
size: 40,
),
SizedBox(
width: width * 0.2,
child: const Divider(
color: Color(0xffbdbdbd),
thickness: 1.5,
height: 0.05),
),
],
),
),
],
),
),
)),
),
));

}
}

I added print statements for debugging, inside setState showMore updates to true. But why does setstate not update showmore value to true inside listview.builder and print all items inside list ls? It only prints 4 items by default, but after clicking setstate no change occurs, more elements are not rendered as it's expected to.

答案1

得分: 2

将变量和函数移出build方法

    bool showMore = false;
    print('ls Length --- ${widget.ls.length}');
    void toggleShowMore()
    {
      print('Inside toggleshowMore original value --- $showMore');
      setState(() {
        showMore = !showMore;
      });
      print('Inside toggleshowMOre updated value --- $showMore');
    }

@override
Widget build(BuildContext context) {
    double height = MediaQuery.of(context).size.height;
    double width = MediaQuery.of(context).size.width;
    return Scaffold(
   .....

调用setState意味着我们重新执行这个方法:Widget build(BuildContext context)

如果你将变量放在里面,那么值会重置为你声明的初始值

英文:

move your variable and function outside build method

    bool showMore = false;
print('ls Length --- ${widget.ls.length}');
void toggleShowMore()
{
print('Inside toggleshowMore original value --- $showMore');
setState(() {
showMore = !showMore;
});
print('Inside toggleshowMOre updated value --- $showMore');
}
@override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return Scaffold(
.....

by calling setState it means we re-execute this method : Widget build(BuildContext context).

if you put your variable inside it, then the value will be reset to the initial value that you declare

huangapple
  • 本文由 发表于 2023年4月11日 15:06:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75983240.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定