Search code examples
flutterflutter-animation

Adjust Width from the Left Side of Container


Changing the width of a container defaults to resizing from the right side. The pseudocode below has an example where dx is a variable that can change. When it increases or decreases, the container will always grow or shrink from the right side. Is there a simple way to switch the direction so that the width will increase or decrease from the left side instead of the right side?

    Container( 
               width: dx,
               height:200
   )

Here is a dartpad gist that shows how the right side of the container's width changes when dragged. What I'm asking is if there is a quick and simple way to make the left side expand/contract without having to animate the position of the container: https://dartpad.dev/?id=ebbe57041bf950018fe5733674c68b20


Solution

  • I checked out your dartpad code. To achieve what you want, I suggest you put two empty Containers on either side of your handles and decrease their size when the handles are dragged (your center Container should also be inside an Expanded widget to take up all the allowed space). here is the example code:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          // Application name
          title: 'Flutter Stateful Clicker Counter',
          theme: ThemeData(
            // Application theme data, you can set the colors for the application as
            // you want
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Clicker Counter Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      final String title;
    
      const MyHomePage({Key? key, required this.title}) : super(key: key);
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      double? rightContainerWidth, leftContainerWidth;
    
      @override
      Widget build(BuildContext context) {
        rightContainerWidth ??= MediaQuery.of(context).size.width / 2 - 20;
        leftContainerWidth ??= MediaQuery.of(context).size.width / 2 - 20;
        return Scaffold(
          backgroundColor: Colors.white,
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Wrap(
              children: <Widget>[
                Row(mainAxisAlignment: MainAxisAlignment.center, children: [
                  // left handle
                  Container(
                    width: leftContainerWidth,
                  ),
                  GestureDetector(
                      onHorizontalDragUpdate: (DragUpdateDetails details) {
                        setState(() {
                          leftContainerWidth = details.globalPosition.dx;
                        });
                      },
                      child: Container(
                          decoration: BoxDecoration(
                              color: Colors.red,
                              borderRadius: BorderRadius.only(
                                topLeft: Radius.circular(20),
                                bottomLeft: Radius.circular(20),
                              )),
                          width: 10,
                          height: 200)),
    
                  Expanded(
                    child: Container(
                        //  padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
    
                        child: ClipRect(
                            child: Container(
                      //   width: _counter+0.2,
                      height: 200,
    
                      color: Colors.green,
                    ))),
                  ),
    
                  GestureDetector(
                      onHorizontalDragStart: (DragStartDetails details) {
                        print("st: ${details.localPosition.dx}");
                        // dx for start is the x offset of the mouse relative to the container
                        //   changeX = (_counter as double) - details.localPosition.dx.floor();
                      },
                      onHorizontalDragUpdate: (DragUpdateDetails details) {
                        setState(() {
                          // print(details.localPosition.dx);
                          rightContainerWidth = MediaQuery.of(context).size.width -
                              details.globalPosition.dx;
                        });
                      },
                      child: Container(
                          width: 10,
                          height: 200,
                          decoration: BoxDecoration(
                              color: Colors.blue,
                              borderRadius: BorderRadius.only(
                                topRight: Radius.circular(20),
                                bottomRight: Radius.circular(20),
                              )))),
                  Container(
                    width: rightContainerWidth,
                  ),
                ])
              ],
            ),
          ),
        );
      }
    }
    

    Caution: I did not add conditional statements to prevent overflows, make sure you also add them!