skip to Main Content

I am using sockets in flutter. I want to show the progress in bottom sheet with Linear percentIndicator. Here’s my initSocket method:

initSocket(String livelapseId) {
socket = IO.io(Endpoints.baseUrl, <String, dynamic>{
  'autoConnect': true,
  'transports': ['websocket'],
});
// socket.connect();
socket!.onConnect((_) {
  print('Connection established');
  socket!.emit('joinRoom', "livelapse:$livelapseId");
  // socket!.on("livelapse:progress", (livelapseId, data, progress) => null);

  socket!.on('livelapse:progress', (data) {
    print("progress" + data.toString());
    print("operation" + data["operation"].toString());
    setState(() {
      _progressBar = double.parse(data["progress"].toString());

    });
    // progressTabCtx.updateItem(itemData._id, { text: operation, progress: progress });
  });

  socket!.on('livelapse:completed', (data) {
    print("completed" + data.toString());
    // progressTabCtx.updateItem(itemData._id, { text: operation, progress: progress });
  });
  socket!.on('livelapse:errored', (data) {
    print("errored" + data.toString());
    // progressTabCtx.updateItem(itemData._id, { text: operation, progress: progress });
  });
});
// socket!.destroy();
socket!.onDisconnect((_) => print('Connection Disconnection'));
socket!.onConnectError((err) => print(err));
socket!.onError((err) => print(err));

}

This is my code where i am calling initsocket and showbottomsheet. i want to show progressbar in bottom sheet: initSocket(res["_id"], calculateProgress); _showProgressBottomSheet(context, _progressBar);

Here’s my bottom sheet method:

_showProgressBottomSheet(context, double progress) {

return showModalBottomSheet(
  context: context,
  backgroundColor: Colors.transparent,
  builder: (context) => StatefulBuilder(
    
    builder: (BuildContext context, StateSetter setState) {
      return Container(
        padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 28.h),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.only(
              topLeft: Radius.circular(16.r), topRight: Radius.circular(16.r)),
          color: Colors.white,
        ),
        height: 288.h,
        width: MediaQuery.of(context).size.width,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Text(
                  'Generating LiveLapse',
                  style: TextStyle(
                      color: Helper.baseBlack,
                      fontSize: 18.sp,
                      fontWeight: FontWeight.w500),
                ),
              ],
            ),
            SizedBox(height: 20.h),
            Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                ListTile(
                  contentPadding: EdgeInsets.zero,
                  isThreeLine: true,
                  leading: Container(
                    padding:
                        EdgeInsets.symmetric(horizontal: 6.w, vertical: 6.h),
                    width: 32.w,
                    height: 32.h,
                    decoration: BoxDecoration(
                        color: Color.fromRGBO(229, 240, 255, 1),
                        borderRadius: BorderRadius.circular(32.r),
                        border: Border.all(
                            color: Color.fromRGBO(245, 249, 255, 1),
                            width: 4.w)),
                    child: SvgPicture.asset(
                      'assets/images/film.svg',
                    ),
                  ),
                  title: Text(
                    "Camera 2 - The Bridges.mp4",
                    style: TextStyle(
                        color: Helper.textColor700,
                        fontSize: 14,
                        fontWeight: FontWeight.w500),
                  ),
                  subtitle: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Text(
                          "Fetching images",
                          style: TextStyle(
                              color: Helper.textColor600,
                              fontSize: 14,
                              fontWeight: FontWeight.w400),
                        ),
                        SizedBox(height: 10.h),
                        Row(mainAxisSize: MainAxisSize.max,
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                         children: [
                          ClipRRect(
                            borderRadius: BorderRadius.circular(4.r),
                            child: LinearPercentIndicator(
                              width: 210.w,
                              fillColor: Helper.textColor300,
                              backgroundColor: Helper.textColor300,
                              progressColor: Helper.primary,
                              padding: EdgeInsets.zero,
                              curve: Curves.easeInOut,
                              barRadius: Radius.circular(4.r),
                              lineHeight: 8.h,
                              percent: _progressBar / 100
                            ),
                          ),
                          Text(
                            "${(_progressBar).toInt()}%",
                            style: TextStyle(
                                color: Helper.textColor700,
                                fontSize: 14,
                                fontWeight: FontWeight.w500),
                          )
                        ])
                      ]),
                  trailing: SvgPicture.asset(
                    'assets/images/checkbox_base.svg',
                  ),
                ),
                SizedBox(height: 20.h),
                Container(
                  height: 52.h,
                  width: double.infinity,
                  child: ElevatedButton(
                    child: Text(
                      "Close",
                      style: TextStyle(
                          color: Colors.white,
                          fontSize: 16,
                          fontWeight: FontWeight.w500),
                      // currentIndex == contents.length - 1 ? "Continue" : "Next"
                    ),
                    style: ButtonStyle(
                        backgroundColor:
                            MaterialStatePropertyAll(Helper.baseBlack),
                        shape: MaterialStateProperty.all(
                          RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(8.r),
                          ),
                        )),
                    onPressed: () {
                      context.pop();
                    },
                  ),
                ),
              ],
            ),
          ],
        ),
      );
    }
  ),
);

}

Progress bar is not moving if i use it outside of bottom sheet method (for example anywhere in screen it is working fine. socket connection and everything is working). bottom sheet is not updating the progress bar. I also used Stateful builder

2

Answers


  1. I’m not fully understand your problem, but I know a method for listening to sockets within different classes. It might be helpful to you.

    • First:

    Define variable over the main or somewhere (not in any class) and initialize variable

    late Socket socket; //define socket variable
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatefulWidget {
      const MyApp({super.key});
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
    
      @override
      void initState() {
        super.initState();
        _initSocket(yourStringVariable); //initialize your variable
      }
      ...
    }
    
    • Then:

    I am not defining a widget tree inside the function; instead, I prefer creating a widget in another place and calling it, making it work like a new page.

    import 'package:YOUR_PROJECT/YOUR_SOCKET_VARIABLE_FILE.dart'; //import the file where the socket variable is defined
    
    class YourBottomSheetClass extends StatefulWidget {
      const YourBottomSheetClass({super.key});
    
      @override
      State<YourBottomSheetClass> createState() => _YourBottomSheetClassState();
    }
    
    class _YourBottomSheetClassState extends State<YourBottomSheetClass> {
    
      @override
      void initState() {
        super.initState();
        socket.on('yourChannel',_yourFunc);
      }
    
      @override
      void dispose() {
        socket.off('yourChannel');
        super.dispose();
      }
    
      void _yourFunc(){
        ...
      }
    
      ...
    }
    
    • Then

    Change your bottom sheet function

    _showProgressBottomSheet(context, _progressBar){  // this is your bottomsheet function
       return showModalBottomSheet(context: context, builder: (context) {
          return YourBottomSheetClass();
        },);
    }
    
    • Finally

    call your function in anywhere page’s build method

    Widget build(BuildContext context) {
      return Container(
        ...
        ...
        child: ElevatedButton(onPressed: (){
          _showProgressBottomSheet(context,progress);
        });
      );
    }
    

    Hope it helps.

    Login or Signup to reply.
  2. In your stateful widget, define a StateSetter variable used to store the sheet state.

    class _YourWidgetState extends State<YourWidgetClass> {
    
      StateSetter? bottomSheetState; //add this line
    
      @override
      void initState() {
      ...
    

    Assign the bottomSheetState variable to the state given by the StatefulBuilder.

    return showModalBottomSheet(
      context: context,
      backgroundColor: Colors.transparent,
      builder: (context) => StatefulBuilder(
        builder: (BuildContext context, StateSetter modalState) {
    
        bottomSheetState = modalState; //add this line
    
        ...
    

    When you update the progress, call bottomSheetState instead of setState.

    socket!.on('livelapse:progress', (data) {
      print("progress" + data.toString());
      print("operation" + data["operation"].toString());
    
      if(bottomSheetState != null){
        bottomSheetState(() {
          _progressBar = double.parse(data["progress"].toString());
        });
      }
    
      // progressTabCtx.updateItem(itemData._id, { text: operation, progress: progress });
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search