Search code examples
flutterlistviewdartbuttonhide

Flutter : how to hide and show button on last and first index in listView


i set two buttons(left and right Button) on top of ListView. buttons work for scrolling on click. now i want to hide the left button when index is 0 and the right button when index is last. more explain to clear, the left button will be hidden in first index and the right button will be hidden in last index. please help me.

class ScrollingLeftAndRightButtonHide extends StatefulWidget {
@override
_ScrolllingOnClickButtonState createState() =>
  _ScrolllingOnClickButtonState();}

class _ScrolllingOnClickButtonState
extends State<ScrollingLeftAndRightButtonHide> {

final _controller = ScrollController();
var _width = 100.0;

@override
Widget build(BuildContext context) {

var sizeDevice = MediaQuery.of(context).size;
this._width = sizeDevice.width;

var recentIndexIncrease = 0;
var recentIndexDecrease = 0;

return MaterialApp(
  debugShowCheckedModeBanner: false,
  home: Scaffold(
    body: Column(
      children: <Widget>[
        Expanded(
            flex: 1,
            child: Container(
              color: Colors.green,
            )),
        Expanded(
            flex: 2,
            child: Row(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(left: 8.0),
                  child: ClipOval(
                    child: Material(
                      color: Colors.blue, // button color
                      child: InkWell(
                        splashColor: Colors.red, // inkwell color
                        child: SizedBox(
                            width: 56,
                            height: 56,
                            child: Icon(Icons.arrow_back)),

                        onTap: () {
                          var recentIndexDecreaseMinus =
                              recentIndexDecrease--;

                          _animateToIndex(recentIndexDecrease);
                        },
                      ),
                    ),
                  ),
                ),
                Expanded(
                    flex: 2,
                    child: Container(
                      color: Colors.transparent,
                    )),
                Padding(
                  padding: const EdgeInsets.only(right: 8),
                  child: ClipOval(
                    child: Material(
                      color: Colors.blue, // button color
                      child: InkWell(
                        splashColor: Colors.red, // inkwell color
                        child: SizedBox(
                            width: 56,
                            height: 56,
                            child: Icon(Icons.arrow_forward)),
                        onTap: () {
                          _animateToIndex(recentIndexIncrease);
                        },
                      ),
                    ),
                  ),
                ),
              ],
            )),
        Expanded(
          flex: 16,
          child: Container(
            // height: 400,
            child: ListView.builder(
                controller: _controller,
                scrollDirection: Axis.horizontal,
                physics: PageScrollPhysics(),
                itemCount: word_data.drink.length,
                itemBuilder: (BuildContext context, int index) {
                  recentIndexIncrease = index;
                  recentIndexDecrease = index;
                  var wordDataReplace = word_data.drink[index]
                      .replaceAll(" ", "_")
                      .toLowerCase();

                  return Container(
                    child: Column(
                      children: <Widget>[
                        Expanded(
                            flex: 6,
                            child: GestureDetector(
                              child: Container(
                                color: Colors.purple,
                                child: Padding(
                                  padding: const EdgeInsets.all(10.0),
                                  child: Image.asset(
                                    "asset/drink_images/" +
                                        wordDataReplace +
                                        ".png",
                                    fit: BoxFit.contain,
                                  ),
                                ),
                              ),
                            )),
                      ],
                    ),
                    width: sizeDevice.width,
                  );
                }),
            color: Colors.yellow,
          ),
        ),
      ],
    ),
  ),
);
}

 _animateToIndex(i) => _controller.animateTo(_width * i,
  duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
}

this image of (ListView with top two Button)


Solution

  • I think it might be easier for you to replace ListView.builder by a Flutter_Swiper it will make your life a lot easier. Or maybe you can add a listner to your ScrollController in the initState where it handles the value of two Boolean variables leftButtonEnabled and rightButtonEnabled and set them to true or false depending on the position of the Controller

    EDIT : here's an example of using Flutter swiper in your code, I tried to make it simple and in the same time adding multiple features that can help you ( like SwiperControl ) I hope it helps you a little bit.

    void main() {
      runApp(
        MaterialApp(
          debugShowCheckedModeBanner: false,
          home: ScrollingLeftAndRightButtonHide(),
        ),
      );
    }
    
    class ScrollingLeftAndRightButtonHide extends StatefulWidget {
      @override
      _ScrolllingOnClickButtonState createState() =>
          _ScrolllingOnClickButtonState();
    }
    
    class _ScrolllingOnClickButtonState
        extends State<ScrollingLeftAndRightButtonHide> {
      SwiperController _controller = SwiperController();
      SwiperControl _control = SwiperControl(color: Colors.white);
    
      double get _width => MediaQuery.of(context).size.width;
      double get _height => MediaQuery.of(context).size.height;
    
      bool inFirstPage = true;
      bool inLastPage = false;
    
      List<String> word_data = [
        "First",
        "Second",
        "Third",
        "Fourth",
        "Fifth",
        "Sixth",
        "Last",
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: SafeArea(
            child: Column(
              children: <Widget>[
                Container(
                  color: Colors.white,
                  child: Row(
                children: <Widget>[
                      if (!inFirstPage)
                    IconButton(
                          color: Colors.indigoAccent,
                      onPressed: () {
                        _controller.previous();
                      },
                      icon: Icon(Icons.arrow_back),
                    ),
                  Spacer(),
                  if (!inLastPage)
                    IconButton(
                      color: Colors.indigoAccent,
                      onPressed: () {
                        _controller.next();
                      },
                      icon: Icon(Icons.arrow_forward),
                    ),
                ],
              ),
            ),
            Expanded(
              child: Container(
                color: Colors.white,
                child: Swiper(
                  controller: _controller,
                  control: _control,
                  loop: false,
                  scrollDirection: Axis.horizontal,
                  itemCount: word_data.length,
                  onIndexChanged: (value) {
                    if (value == word_data.length - 1)
                      setState(() {
                        inLastPage = true;
                      });
                    else if (value == 0)
                      setState(() {
                        inFirstPage = true;
                      });
                        else {
                          setState(() {
                            inFirstPage = false;
                            inLastPage = false;
                          });
                        }
                      },
                      itemBuilder: (BuildContext context, int index) {
                        return Container(
                          child: Column(
                            children: <Widget>[
                              Expanded(
                                child: GestureDetector(
                                      child: Container(
                                    width: _width,
                                    alignment: Alignment.center,
                                    color: Colors.indigoAccent,
                                    child: Text(word_data[index]),
                                  ),
                                ),
                              ),
                            ],
                          ),
                        );
                      },
                    ),
                  ),
                ),
              ],
            ),
          ),    
        );
      }
    }