mardi 31 décembre 2019

What is a good code design for button interaction similar to a radio button?

I would like to make an user interaction that works like radio button, hence only one item can be active in the list. Instead of a radio button graphics, I'd like to use the ListItem widget.

Hence, I'd like to:

  • ListItem A: On tap, 'activate' the list item.
  • ListItem B: On tap, 'deactivate' the current active and activate this ListItem.

What is the best algorithm architecture to do this?

I tried to use the architecture in the example below. The problem is that it does not track which list item is clicked, hence it change the 'state' of all the children of the parent at the same time.


//------------------------ ParentWidget --------------------------------

class ParentWidget extends StatefulWidget {
  @override
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Expanded (
            ListView.builder(
             itemCount: listOfBoxes.length,
             itemBuilder: (BuildContext context, int index) {
                 return TapboxB(
                     active: _active,
                     onChanged: _handleTapboxChanged,
                      ),
              }
            )
     )
  }
}

//------------------------- TapboxB ----------------------------------

class TapboxB extends StatelessWidget {
  TapboxB({Key key, this.active: false, @required this.onChanged})
      : super(key: key);

  final bool active;
  final ValueChanged<bool> onChanged;

  void _handleTap() {
    onChanged(!active);
  }

  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        child: Center(
          child: Text(
            active ? 'Active' : 'Inactive',
            style: TextStyle(fontSize: 32.0, color: Colors.white),
          ),
        ),
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: active ? Colors.lightGreen[700] : Colors.grey[600],
        ),
      ),
    );
  }
}```



Aucun commentaire:

Enregistrer un commentaire