Cory Allen
Cory Allen

Reputation: 159

GestureDetector fires all containers...how to fire just one?

I have a gesture detector that fires all containers and I just want to fire one at a time. How would I go about doing that? Right now they are all turning green and I just want to turn one of them green.

Is it the fact that I'm calling it multiple times in the same way in my _HomePageState class?

I thought the new keyword would have taken care of that so I tried that.

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new HomePage()
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  State createState() => new _HomePageState(); 
}

class _HomePageState extends State<HomePage> {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.all(20),
              ),
              Container(
                height: MediaQuery.of(context).size.height * 0.3,
                width: MediaQuery.of(context).size.width * 0.95,
                color: Theme.of(context).primaryColorLight,
              ),
              Padding(
                padding: EdgeInsets.all(5),
              ),
              Container(
                width: MediaQuery.of(context).size.width * .97,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: <Widget>[
                    heroes(context),
                    heroes(context),
                    heroes(context),
                    heroes(context),
                    heroes(context),
                    heroes(context),
                  ],
                ),
              ),
              Container(
                height: MediaQuery.of(context).size.height * 0.56,
                width: MediaQuery.of(context).size.width * .97,
                child: ListView(
                  scrollDirection: Axis.vertical,
                  children: <Widget>[
                    list(context),
                    list(context),
                    list(context),
                    list(context),
                    list(context),
                    list(context),
                    list(context),
                  ],
                ),
              ),
            ]
          ),
        )
      );
  }

  Color _color = Colors.blue;  

  Widget heroes(BuildContext context) {
    return new GestureDetector(
        onTap: () {
          setState( () {
            _color = Colors.green; 
          });
        },
        child: new Container(
          height: MediaQuery.of(context).size.height * 0.05,
          width: MediaQuery.of(context).size.width * 0.12,
          color: _color,
        )
      );
  }

  Widget list(BuildContext context) {
    return Padding(
          padding: EdgeInsets.all(5),
          child: Container(
            height: MediaQuery.of(context).size.height * 0.07,
            width: MediaQuery.of(context).size.width * (0.12*8),
            color: Theme.of(context).primaryColorDark
          )
    );
  }

}

enter image description here

Upvotes: 0

Views: 106

Answers (1)

Bassam
Bassam

Reputation: 507

Read the comments to understand how it works. It is really simple.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new HomePage()
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  State createState() => new _HomePageState(); 
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.all(20),
              ),
              Container(
                height: MediaQuery.of(context).size.height * 0.3,
                width: MediaQuery.of(context).size.width * 0.95,
                color: Theme.of(context).primaryColorLight,
              ),
              Padding(
                padding: EdgeInsets.all(5),
              ),
              Container(
                width: MediaQuery.of(context).size.width * .97,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: <Widget>[
                    // 1) Give each widget a number
                    heroes(context, 0),
                    heroes(context, 1),
                    heroes(context, 2),
                    heroes(context, 3),
                    heroes(context, 4),
                    heroes(context, 5),
                  ],
                ),
              ),
              Container(
                height: MediaQuery.of(context).size.height * 0.56,
                width: MediaQuery.of(context).size.width * .97,
                child: ListView(
                  scrollDirection: Axis.vertical,
                  children: <Widget>[
                    list(context),
                    list(context),
                    list(context),
                    list(context),
                    list(context),
                    list(context),
                    list(context),
                  ],
                ),
              ),
            ]
          ),
        )
      );
  }

  // 2) This is important. It saves the current index.
  var selectedIndex;

  // 3) Add `index` as a parameter
  Widget heroes(BuildContext context, index) {
    return new GestureDetector(
        onTap: () {
          setState( () {
            // 4) After each tap the index of the widget is saved as `selectedIndex`
            selectedIndex = index;
          });
        },
        child: new Container(
          height: MediaQuery.of(context).size.height * 0.05,
          width: MediaQuery.of(context).size.width * 0.12,
          // 5) It compares the current selectedIndex with the index of the widget. If both have the same number, the color will be green. Otherwise it will be blue.
          color: selectedIndex == index? Colors.green : Colors.blue,
        )
      );
  }

  Widget list(BuildContext context) {
    return Padding(
          padding: EdgeInsets.all(5),
          child: Container(
            height: MediaQuery.of(context).size.height * 0.07,
            width: MediaQuery.of(context).size.width * (0.12*8),
            color: Theme.of(context).primaryColorDark
          )
    );
  }
}

enter image description here

Upvotes: 1

Related Questions