Emma Scarlett
Emma Scarlett

Reputation: 47

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)

Upvotes: 1

Views: 3411

Answers (3)

Bensal
Bensal

Reputation: 4120

You cannot do it through your current structure of code. To achieve it you will have to move those arrow button Icons inside of the listView like this:

return  ListView.builder(
  scrollDirection: Axis.horizontal,
  physics: PageScrollPhysics(),
  itemCount: 5,
  itemBuilder: (BuildContext context, int index) {
  recentIndexIncrease = index;
  recentIndexDecrease = index;
  var wordDataReplace = word_data.drink[index].replaceAll(" ", "_").toLowerCase();

  return Column(
    children: <Widget>[
      Row(
        children: [
          //Left arrow is the button indicating left arrow
          if (index != 0) LeftArrow,
          //Rightarrow is the button indicating right arrow
          if (index != 4) RightArrow
        ],
      ),
      Expanded(
        child: GestureDetector(
          child: Container(
            color: Colors.purple,
            padding: const EdgeInsets.all(10.0),
            child: Image.asset("asset/drink_images/" +
                                wordDataReplace +
                                ".png",
              fit: BoxFit.contain,
            ),
          ),
      )),
    ],
  );
});

Upvotes: 0

Oussama Belabbas
Oussama Belabbas

Reputation: 196

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]),
                              ),
                            ),
                          ),
                        ],
                      ),
                    );
                  },
                ),
              ),
            ),
          ],
        ),
      ),    
    );
  }
}

Upvotes: 0

Taha Malik
Taha Malik

Reputation: 2391

Add two variables in your state as

class _ScrolllingOnClickButtonState
      extends State<ScrollingLeftAndRightButtonHide> {
    bool leftEnabled = false; //this is initial visibility of left button
    bool rightEnabled = true; //this is initial visibility of right button
........

Then in your build function where you are displaying left and right button add if statement

@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(
        .............
              if(leftEnabled)
                  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);
                                if (index == 0) { //Your logic to detect start of the list.
                                  leftEnabled = false; //if it is the start make left invisible
                                }
                                if(list.size > 1)
                                    rightEnabled = true; //whenever left button is pressed and your data has more than 1 element make right visible
                                setState(() {});
                              },
                            ),
                          ),
                        ),
                      ),
                      ...............

Same code for the right button.

Upvotes: 0

Related Questions