如何防止应用程序状态更改?

时间:2020-10-19 20:39:19

标签: flutter dart

我目前正在处理此应用程序,但我刚刚意识到,选中这些框并上下滚动时,它会自行取消选中。意味着应用程序的状态正在改变。

我将gridview.builder用于gridview,它工作得很好,除了以下事实:当我检查这些bo口时,上下滚动时,复选框本身未选中。请快速修复。谢谢。

请问我该如何解决?这是我的代码如下:


class GridViewPage extends StatefulWidget {
  @override
  _GridViewPageState createState() => _GridViewPageState();
}

class _GridViewPageState extends State<GridViewPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          SafeArea(
            child: Padding(
              padding: const EdgeInsets.only(top: 125.0),
              child: Product(),
            ),
          ),
          HeaderWiget(),
          Center(
              child: Container(
            width: MediaQuery.of(context).size.width,
            height: 64.0,
            decoration: BoxDecoration(
              color: Color(0XFF161F51).withOpacity(0.4),
            ),
            child: Center(
              child: Text(
                'Next',
                style: TextStyle(
                    color: Colors.white,
                    fontFamily: 'Work Sans',
                    fontSize: 22.0,
                    fontWeight: FontWeight.w500),
              ),
            ),
          ))
        ],
      ),
    );
  }
}

class HeaderWiget extends StatelessWidget {
  final Color colors = Color(0XFF161F51);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width,
      height: 128,
      decoration: BoxDecoration(
        color: colors,
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Column(
                children: [
                  Text(
                    'What do you do?',
                    style: TextStyle(
                      fontSize: 28.0,
                      color: Colors.white,
                    ),
                  ),
                  RichText(
                      text: TextSpan(
                    text: 'You can select multiple options',
                    style: TextStyle(
                      fontSize: 16.0,
                      color: Colors.white,
                    ),
                  )),
                ],
              ),
              SizedBox(
                width: 50.0,
              ),
              GestureDetector(
                  onTap: () {},
                  child: RichText(
                      text: TextSpan(
                    children: [
                      TextSpan(
                          text: 'SKIP',
                          style: TextStyle(
                            fontFamily: 'Work Sans',
                            fontWeight: FontWeight.w400,
                            fontSize: 18.0,
                            decorationColor: Colors.white,
                            decoration: TextDecoration.underline,
                          ))
                    ],
                  ))),
            ],
          ),
        ],
      ),
    );
  }
}



class Product extends StatefulWidget {
  @override
  _ProductState createState() => _ProductState();
}

class _ProductState extends State<Product> {
  final listItem = [
    {'Name': 'Hair & Beauty', 'image': 'assets/images/Rectangle15.png'},
    {'Name': 'Wedding planner', 'image': 'assets/images/Rectangle16.png'},
    {'Name': 'Bridal Attire', 'image': 'assets/images/Rectangle17.png'},
    {'Name': 'Catering_1', 'image': 'assets/images/Rectangle18.png'},
    {'Name': 'DJ', 'image': 'assets/images/Rectangle19.png'},
    {'Name': 'Florist', 'image': 'assets/images/Rectangle20.png'},
    {'Name': 'Jewelry', 'image': 'assets/images/Rectangle21.png'},
    {'Name': 'Props', 'image': 'assets/images/Rectangle22.png'},
    {'Name': 'Bridal_Attire', 'image': 'assets/images/Rectangle17.png'},
    {'Name': 'Catering', 'image': 'assets/images/Rectangle18.png'},
  ];

  @override
  Widget build(BuildContext context) {
    return Container(
      child: GridView.builder(
          itemCount: listItem.length,
          gridDelegate:
              SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          itemBuilder: (BuildContext context, int index) {
            return Container(
                padding: EdgeInsets.all(5.0),
                child: ProductApp(
                  businessName: listItem[index]['Name'],
                  businessImage: listItem[index]['image'],
                ));
          }),
    );
  }
}

class ProductApp extends StatefulWidget {
  final businessName;
  final businessImage;
  ProductApp({this.businessName, this.businessImage});
  @override
  _ProductAppState createState() => _ProductAppState();
}

class _ProductAppState extends State<ProductApp> {
  Color color;
  var isToggle = false;
  ColorFilter filterColor = ColorFilter.mode(Colors.grey, BlendMode.saturation);
  ColorFilter normalFilter;

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Hero(
          tag: widget.businessName,
          child: Material(
            child: InkWell(
              onTap: () {
                setState(() {
                  isToggle = isToggle ? false : true;
                });
              },
              child: GridTile(
                child: Container(
                    decoration: BoxDecoration(
                  image: DecorationImage(
                      image: ExactAssetImage(widget.businessImage),
                      fit: BoxFit.fitWidth,
                      colorFilter: isToggle ? normalFilter : filterColor),
                )),
                header: Container(
                  child: ListTile(
                    trailing: SelectedDot(
                        colors: isToggle
                            ? Colors.pink
                            : Colors.black.withOpacity(0.0)),
                    title: Text(
                      widget.businessName,
                      style: TextStyle(
                          fontWeight: FontWeight.w500,
                          color: Colors.white,
                          fontSize: 12.0),
                    ),
                  ),
                ),
              ),
            ),
          )),
    );
  }
}

enter image description here

1 个答案:

答案 0 :(得分:0)

您正在使用gridview.builder,它在滚动项目时对其性能进行了优化。它会自动删除并创建屏幕外或屏幕上的元素。在您的代码中,您将状态保存在ProductApp有状态窗口小部件中,但是对于在gridview.builder中进行构建的情况,它的有状态性没有任何意义。在您单击此“复选框”并向上或向下滚动后,这些窗口小部件才重新构建。

最好的解决方案是从组件中删除状态,并使用状态管理工具(例如Provider或Bloc程序包)。很快,您可以在小部件树中提升值的状态,以仅将state和onChange回调传递给gridview元素。

GridView.builder(
          itemCount: listItem.length,
          gridDelegate:
          SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          itemBuilder: (BuildContext context, int index) {
            return Container(
                padding: EdgeInsets.all(5.0),
                child: ProductApp(
                  isToggled: YourItemObject.isToggled,
                  onChange: YourItemObject.onChange,
                  businessName: YourItemObject.name,
                  businessImage: YourItemObject.image,
                ));
          })

这样,您的gridview.builder元素将仅接收值和更改值。但是,现在价值本身正在网格项目之外进行管理。