1

I have a ListView.builder() method that builds out multiple cards which contains an image, some text, and a slider for each card. The problem is, whenever I move a slider they are all moving together and so is the value.

double _sliderValue = 0.0;

final List<String> cardList = [
    'assets/food.jpg',
    'assets/food.jpg',
    'assets/food.jpg',
  ];

void _setValue(double value) {
    setState(() {
      _sliderValue = value;
    });
  }

  Widget _buildFoodCard(BuildContext context, int index) {
    return Container(
      height: 350,
      child: Card(
        clipBehavior: Clip.antiAlias,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10.0),
        ),
        child: Column(
          children: <Widget>[
            ClipRRect(
              borderRadius: BorderRadius.circular(10.0),
              child: Image.asset(
                cardList[index],
                fit: BoxFit.cover,
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(top: 15.0),
              child: Text(
                '${_sliderValue.round()}' + ' ITEMS',
                style: TextStyle(color: Colors.white, fontSize: 15.0),
              ),
            ),
            SliderTheme(
              data: SliderTheme.of(context).copyWith(
                  thumbColor: Colors.white,
                  thumbShape: RoundSliderThumbShape(enabledThumbRadius: 10.0),
                  activeTrackColor: Color(0xff3ADEA7),
                  inactiveTrackColor: Colors.grey,
                  overlayColor: Colors.transparent,
                  trackHeight: 1.0),
              child: Slider(
                value: _sliderValue,
                onChanged: _setValue,
                min: 0.0,
                max: 150.0,
                divisions: 30,
              ),
            ),
          ],
        ),
        color: Colors.transparent,
        elevation: 0.0,
        margin: EdgeInsets.all(10.0),
      ),
    );
  }

  Widget _buildCardList() {
    return ListView.builder(
      shrinkWrap: true,
      physics: NeverScrollableScrollPhysics(),
      itemBuilder: _builFoodCard,
      itemCount: cardList.length,
    );
  }

SCREENSHOT

What can I do to make it so that each slider and value move/increment individually?

Tony
  • 77
  • 3
  • 12

1 Answers1

2

You implement a state for each card with slider with its own slider state.

Widget _buildCardList() {
  return ListView.builder(
    shrinkWrap: true,
    physics: NeverScrollableScrollPhysics(),
    itemBuilder: (BuildContext context, int index) =>
        MyWidgetSlider(cardList[index]),
    itemCount: cardList.length,
  );
}

class MyWidgetSlider extends StatefulWidget {
  final String data;
  MyWidgetSlider(this.data) : super();

  _MyWidgetSliderState createState() => _MyWidgetSliderState();
}

class _MyWidgetSliderState extends State<MyWidgetSlider> {
  double _sliderValue;
  @override
  void initState() {
    super.initState();
    _sliderValue = 0.0;
  }

  void _setValue(double value) {
    setState(() {
      _sliderValue = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 350,
      child: Card(
        clipBehavior: Clip.antiAlias,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10.0),
        ),
        child: Column(
          children: <Widget>[
            ClipRRect(
              borderRadius: BorderRadius.circular(10.0),
              child: Image.asset(
                this.widget.data,
                fit: BoxFit.cover,
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(top: 15.0),
              child: Text(
                '${_sliderValue.round()}' + ' ITEMS',
                style: TextStyle(color: Colors.white, fontSize: 15.0),
              ),
            ),
            SliderTheme(
              data: SliderTheme.of(context).copyWith(
                  thumbColor: Colors.white,
                  thumbShape: RoundSliderThumbShape(enabledThumbRadius: 10.0),
                  activeTrackColor: Color(0xff3ADEA7),
                  inactiveTrackColor: Colors.grey,
                  overlayColor: Colors.transparent,
                  trackHeight: 1.0),
              child: Slider(
                value: _sliderValue,
                onChanged: _setValue,
                min: 0.0,
                max: 150.0,
                divisions: 30,
              ),
            ),
          ],
        ),
        color: Colors.transparent,
        elevation: 0.0,
        margin: EdgeInsets.all(10.0),
      ),
    );
  }
}
xIsra
  • 867
  • 10
  • 21
  • 1
    Thank you very much, I need to learn more about state management to get a better understanding of this nex time. – Tony Jun 30 '19 at 20:38
  • @xlsra If I move the slider now and the value changes, how can I have it save the same value if I were to go to a different tab then come back? – Tony Jun 30 '19 at 20:56
  • You can set your state in an upper order to your Tab widget, or use https://stackoverflow.com/questions/49087703/preserving-state-between-tab-view-pages – xIsra Jun 30 '19 at 21:08
  • @xIsra is there any way to use these sliders with a dependency like http://jsfiddle.net/ankr/L8reK/ – Amit Kumar Pawar Feb 20 '20 at 12:19
  • @AmitKumarPawar Search for any dependency you like here: https://pub.dev/ – xIsra Feb 20 '20 at 17:20