3

I have a custom reaction bar like Facebook which open/close on click on, but i need to change it's size when click out side, or on list scroll in order to close it

any ideas for doing this?

for example the following code:

class TestClass extends StatefulWidget {
  const TestClass({Key? key}) : super(key: key);

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

class _TestClassState extends State<TestClass> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(body: ListView.builder(itemBuilder: (context,index){

      return Container(height: 300,width: 200,child: Column(children: [
        Text("On press test "),
        Text("On press text 2"),
        reactionsBar()
      ],),);
    }),);
  }
}
Mohamad Alzabibi
  • 166
  • 1
  • 14

3 Answers3

0

You can use gesturedetector Widget .when user click gesturedetector ,resize reactionsBar. and when user reactionsBar ,restor size reactionsBar.

  • I already implemented this case, but i want to close the reaction bar when clicking outside or scrolling the list since it's in a list of items – Mohamad Alzabibi Aug 26 '21 at 12:30
  • See this link https://medium.com/nonstopio/hide-or-show-app-bar-and-bottom-navigation-bar-while-scrolling-in-flutter-3994f78e52c0 – akram abdullah Aug 26 '21 at 22:37
  • Yeah I thought this way but i have to handle that in many places not just on scroll it's on click on any item in screen like app bar , bottom navigation bar , post content .. etc so it takes many efforts, I guess there should be something like focus lost or something similar – Mohamad Alzabibi Aug 27 '21 at 20:49
0

Use a FocusNode on the widget and add a listener to it, so that you can detect change on focus and execute your code accordingly. See this answer for more details.

Otherwise you might wrap your widget in a Focus widget, as follows:

Focus(
  child: TextFormField(...),
  onFocusChange: (hasFocus) {
    if(hasFocus) {
      // do stuff
    }
  },
)

Source

fulcus
  • 47
  • 1
  • 10
  • It seems like it's not working with any widget, just with the TextField – Mohamad Alzabibi Aug 30 '21 at 11:44
  • Check out [the code sample](https://api.flutter.dev/flutter/widgets/Focus-class.html), it works with any widget – fulcus Aug 30 '21 at 13:36
  • I've checked out the example actually it depends on onTap which i should put on top of each widget i might press on in the screen, which is the same problem that i'me looking to solve – Mohamad Alzabibi Aug 30 '21 at 17:15
0

Use Stack() and have a container that will fill the entire screen behind your reaction bar. Use GestureDetector to detect the tap on that container.

Stack(
    children: [
      GestureDetector(
        onTap: () {
          print("tapped outside");
        },
        child: Container(color: Colors.red),
      ),
     // put your reaction bar here
    ],
  ),

Another solution to allow user to click or drag on objects outside the reaction bar:

Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        onTapDown: (_details) {
          Rect tapRect = Rect.fromCircle(
              center: Offset(
                  _details.globalPosition.dx, _details.globalPosition.dy),
              radius: 1);
          RenderBox reactionBox =
              _keyReactionBar.currentContext?.findRenderObject() as RenderBox;

          final reactionBottomRight = Offset(
            reactionBox.localToGlobal(Offset.zero).dx + reactionBox.size.width,
            reactionBox.localToGlobal(Offset.zero).dy + reactionBox.size.height,
          );

          print(reactionBottomRight);

          Rect reactionRect = Rect.fromPoints(
              reactionBox.localToGlobal(Offset.zero), reactionBottomRight);
          if (!reactionRect.overlaps(tapRect)) {
            print("tapped outside reactionsBar");
          }
        },
        child: Column(
          children: [
            GestureDetector(
              onTap: () {
                print("hello");
              },
              child: SizedBox(
                width: 200,
                height: 200,
                child: Container(
                  color: Colors.red,
                ),
              ),
            ),
            GestureDetector(
              onTap: () {
                print("tapped on reactionsBar");
              },
              child: SizedBox(
                key: _keyReactionBar,
                width: 200,
                height: 200,
                child: Container(
                  color: Colors.blue,
                ),
              ),
            )
          ],
        ),
      ),
    );
  }

I'm wrapping the entire screen/body with GestureDetector and used onTapDown to get where the tap has been happened. Then, I will check if it is within the area of reaction bar or not.

Zan
  • 16
  • 4