Home > Back-end >  flutter update stateful widget form stateless widget
flutter update stateful widget form stateless widget

Time:11-13

i have 4 List and i want to change them by tapping on gesturedetector on tap event, but i receive an error. I tried call setState , but as i understood only stateful widget can do it. This lists already receive i just want to rebuild widget, i tried use it from state, but it also won't work.

error

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:vltest/Models/_request.dart';
import 'package:vltest/settings.dart';
import 'package:http/http.dart' as http;
import 'Models/_workers.dart';
import 'database.dart';

List<Requests> ActiveRequests = List.empty();
List<Requests> ClosedRequests = List.empty();
List<Requests> ActiveRequestsTO = List.empty();
List<Requests> ClosedRequestsTO = List.empty();

class RequestsPage extends StatefulWidget {
  const RequestsPage();

  @override
  _RequestsPageState createState() => _RequestsPageState();
}

class _RequestsPageState extends State<RequestsPage> {
  ScrollController controller = ScrollController();
  bool closeTopContainer = false;
  double topContainer = 0;

  List<Widget> itemsData = [];

  void getPostsData(List<Requests> list) {
    List<Requests> responseList = list;
    List<Widget> listItems = [];
    responseList.forEach((post) {
      listItems.add(Container(
          height: 150,
          margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
          decoration: BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(20.0)),
              color: Colors.white,
              boxShadow: [
                BoxShadow(color: Colors.black.withAlpha(100), blurRadius: 10.0),
              ]),
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text(
                      post.shopAddress,
                      style: const TextStyle(
                          fontSize: 15, fontWeight: FontWeight.bold),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    Text(
                      post.problemPart,
                      style: const TextStyle(
                          fontSize: 12,
                          color: Colors.red,
                          fontWeight: FontWeight.bold),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    Text(
                      post.serialNumber,
                      style: const TextStyle(
                          fontSize: 15,
                          color: Colors.black,
                          fontWeight: FontWeight.bold),
                    )
                  ],
                ),
                //requestPhoto(post)
              ],
            ),
          )));
    });
    setState(() {
      itemsData = listItems;
    });
  }

  void updatePostsData(List<Requests> list) {
    List<Requests> responseList = list;
    List<Widget> listItems = [];
    responseList.forEach((post) {
      GenerateRequestCards(listItems, post);
    });
  }

  void GenerateRequestCards(List<Widget> listItems, Requests post) {
    listItems.add(Container(
        height: 150,
        margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
        decoration: BoxDecoration(
            borderRadius: BorderRadius.all(Radius.circular(20.0)),
            color: Colors.white,
            boxShadow: [
              BoxShadow(color: Colors.black.withAlpha(100), blurRadius: 10.0),
            ]),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text(
                    post.shopAddress,
                    style: const TextStyle(
                        fontSize: 15, fontWeight: FontWeight.bold),
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  Text(
                    post.problemPart,
                    style: const TextStyle(
                        fontSize: 12,
                        color: Colors.red,
                        fontWeight: FontWeight.bold),
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  Text(
                    post.serialNumber,
                    style: const TextStyle(
                        fontSize: 15,
                        color: Colors.black,
                        fontWeight: FontWeight.bold),
                  )
                ],
              ),
              //requestPhoto(post)
            ],
          ),
        )));
    setState(() {
      itemsData = listItems;
    });
  }

  Image requestPhoto(Requests post) {
    if (post.imageUrl == "") {
      return Image.network(
        post.imageUrl,
        height: double.infinity,
      );
    } else {
      return Image.network(
        "https://i.ibb.co/TctYZfx/Logo-Main-3-1.jpg",
        height: double.infinity,
      );
    }
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => loadUserInfo().then((value) {
              setState(() {});
            }));

    controller.addListener(() {
      double value = controller.offset / 119;

      setState(() {
        topContainer = value;
        closeTopContainer = controller.offset > 50;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    final double categoryHeight = size.height * 0.30;
    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          elevation: 0,
          backgroundColor: Colors.white,
          leading: Icon(
            Icons.arrow_back,
            color: Colors.black,
          ),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.search, color: Colors.black),
              onPressed: () {},
            ),
            IconButton(
              icon: Icon(Icons.person, color: Colors.black),
              onPressed: () {},
            )
          ],
        ),
        body: Container(
          height: size.height,
          child: Column(
            children: <Widget>[
              const SizedBox(
                height: 10,
              ),
              AnimatedOpacity(
                duration: const Duration(milliseconds: 200),
                opacity: closeTopContainer ? 0 : 1,
                child: AnimatedContainer(
                  duration: const Duration(milliseconds: 200),
                  width: size.width,
                  alignment: Alignment.topCenter,
                  height: closeTopContainer ? 0 : categoryHeight,
                  child: CategoriesScroller(
                      ActiveRequests: ActiveRequests,
                      ClosedRequests: ClosedRequests,
                      ActiveRequestsTO: ActiveRequestsTO,
                      ClosedRequestsTO: ClosedRequestsTO),
                ),
              ),
              Expanded(
                  child: ListView.builder(
                      controller: controller,
                      itemCount: itemsData.length,
                      physics: BouncingScrollPhysics(),
                      itemBuilder: (context, index) {
                        double scale = 1.0;
                        if (topContainer > 0.5) {
                          scale = index   0.5 - topContainer;
                          if (scale < 0) {
                            scale = 0;
                          } else if (scale > 1) {
                            scale = 1;
                          }
                        }
                        return Opacity(
                          opacity: scale,
                          child: Transform(
                            transform: Matrix4.identity()..scale(scale, scale),
                            alignment: Alignment.bottomCenter,
                            child: Align(
                                heightFactor: 0.7,
                                alignment: Alignment.topCenter,
                                child: itemsData[index]),
                          ),
                        );
                      })),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> loadUserInfo() async {
    Workers workers = await DBProvider.db.getWorkerInfo();
    ActiveRequests = await getRequestsInfo(workers, "repair", "active");
    ClosedRequests = await getRequestsInfo(workers, "repair", "closed");
    ActiveRequestsTO = await getRequestsInfo(workers, "maintenance", "active");
    ClosedRequestsTO = await getRequestsInfo(workers, "maintenance", "closed");

    getPostsData(ActiveRequests);

    setState(() {});
  }

  Future<void> updateLoadersData() async {
    Workers workers = await DBProvider.db.getWorkerInfo();
    ActiveRequests = await getRequestsInfo(workers, "repair", "active");
    ClosedRequests = await getRequestsInfo(workers, "repair", "closed");
    ActiveRequestsTO = await getRequestsInfo(workers, "maintenance", "active");
    ClosedRequestsTO = await getRequestsInfo(workers, "maintenance", "closed");
    setState(() {});
  }

  Future<List<Requests>> getRequestsInfo(
      Workers workers, String type, String status) async {
    Map data = {
      'login': workers.login,
      'type': type,
      'status': status,
    };
    //encode Map to JSON
    var body = json.encode(data);

    final response = await http.post(
        Uri.parse(GlobalSettings.serverHTTP   'api/requests/list'),
        headers: {
          "Content-Type": "application/json",
          "Authorization": "Bearer ${workers.token}"
        },
        body: body);

    if (response.statusCode == 200) {
      Iterable l = json.decode(response.body);
      List<Requests> loaders =
          List<Requests>.from(l.map((model) => Requests.fromJson(model)));
      return loaders;
    } else {
      throw Exception('Failed to load album');
    }
  }

  List<T> map<T>(List list, Function handler) {
    List<T> result = [];
    for (var i = 0; i < list.length; i  ) {
      result.add(handler(i, list[i]));
    }

    return result;
  }
}

class CategoriesScroller extends StatelessWidget {
  const CategoriesScroller({
    Key? key,
    required this.ActiveRequests,
    required this.ClosedRequests,
    required this.ActiveRequestsTO,
    required this.ClosedRequestsTO,
  }) : super(key: key);

  final List<Requests> ActiveRequests;
  final List<Requests> ClosedRequests;
  final List<Requests> ActiveRequestsTO;
  final List<Requests> ClosedRequestsTO;

  @override
  Widget build(BuildContext context) {
    final double categoryHeight =
        MediaQuery.of(context).size.height * 0.30 - 50;

    return SingleChildScrollView(
      physics: BouncingScrollPhysics(),
      scrollDirection: Axis.horizontal,
      child: Container(
        margin: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
        child: FittedBox(
          fit: BoxFit.fill,
          alignment: Alignment.topCenter,
          child: Row(
            children: <Widget>[
              Container(
                width: 150,
                margin: EdgeInsets.only(right: 20),
                height: categoryHeight,
                decoration: BoxDecoration(
                    color: Colors.orange.shade400,
                    borderRadius: BorderRadius.all(Radius.circular(20.0))),
                child: Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: GestureDetector(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          "Active",
                          style: TextStyle(
                              fontSize: 18,
                              color: Colors.white,
                              fontWeight: FontWeight.bold),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text(
                          "Repair",
                          style: TextStyle(
                              fontSize: 15,
                              color: Colors.white,
                              fontWeight: FontWeight.bold),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text(
                          ActiveRequests.length.toString(),
                          style: TextStyle(fontSize: 16, color: Colors.white),
                        ),
                      ],
                    ),
                    onTap: () {
                      List<Widget> list = [];
                      ActiveRequests.forEach((element) {
                        _RequestsPageState()
                            .GenerateRequestCards(list, element);
                      });
                    },
                  ),
                ),
              ),
              Container(
                width: 150,
                margin: EdgeInsets.only(right: 20),
                height: categoryHeight,
                decoration: BoxDecoration(
                    color: Colors.orange.shade400,
                    borderRadius: BorderRadius.all(Radius.circular(20.0))),
                child: Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: GestureDetector(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          "Closed",
                          style: TextStyle(
                              fontSize: 18,
                              color: Colors.white,
                              fontWeight: FontWeight.bold),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text(
                          "Repair",
                          style: TextStyle(
                              fontSize: 15,
                              color: Colors.white,
                              fontWeight: FontWeight.bold),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text(
                          ClosedRequests.length.toString(),
                          style: TextStyle(fontSize: 16, color: Colors.white),
                        ),
                      ],
                    ),
                    onTap: () {
                      List<Widget> list = [];
                      ClosedRequests.forEach((element) {
                        _RequestsPageState()
                            .GenerateRequestCards(list, element);
                      });
                    },
                  ),
                ),
              ),
              Container(
                width: 150,
                margin: EdgeInsets.only(right: 20),
                height: categoryHeight,
                decoration: BoxDecoration(
                    color: Colors.orange.shade400,
                    borderRadius: BorderRadius.all(Radius.circular(20.0))),
                child: Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: GestureDetector(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          "Active",
                          style: TextStyle(
                              fontSize: 18,
                              color: Colors.white,
                              fontWeight: FontWeight.bold),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text(
                          "Maintenance",
                          style: TextStyle(
                              fontSize: 15,
                              color: Colors.white,
                              fontWeight: FontWeight.bold),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text(
                          ActiveRequestsTO.length.toString(),
                          style: TextStyle(fontSize: 16, color: Colors.white),
                        ),
                      ],
                    ),
                    onTap: () {
                      List<Widget> list = [];
                      ActiveRequestsTO.forEach((element) {
                        _RequestsPageState()
                            .GenerateRequestCards(list, element);
                      });
                    },
                  ),
                ),
              ),
              Container(
                width: 150,
                margin: EdgeInsets.only(right: 20),
                height: categoryHeight,
                decoration: BoxDecoration(
                    color: Colors.orange.shade400,
                    borderRadius: BorderRadius.all(Radius.circular(20.0))),
                child: Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: GestureDetector(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          "Closed",
                          style: TextStyle(
                              fontSize: 18,
                              color: Colors.white,
                              fontWeight: FontWeight.bold),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text(
                          "Maintenance",
                          style: TextStyle(
                              fontSize: 15,
                              color: Colors.white,
                              fontWeight: FontWeight.bold),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text(
                          ClosedRequestsTO.length.toString(),
                          style: TextStyle(fontSize: 16, color: Colors.white),
                        ),
                      ],
                    ),
                    onTap: () {
                      List<Widget> list = [];
                      ClosedRequestsTO.forEach((element) {
                        _RequestsPageState()
                            .GenerateRequestCards(list, element);
                      });
                    },
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Give me an advice please...

CodePudding user response:

Call setState after checking if it is mouted or not, like

 if (mounted) {
   setState(() {});
   }

CodePudding user response:

Sorry for long delay, honestly, i forgot about conversation, i solve problem by rewrite code , in statefull widget

  • Related