Flutter:如何在 listView 的最后一个和第一个索引上隐藏和显示按钮

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

我在 ListView 的顶部设置了两个按钮(左按钮和右按钮)。按钮用于单击时滚动。现在我想在索引为 0 时隐藏左键,在索引为最后时隐藏右键。更多解释清楚,左按钮将隐藏在第一个索引中,右键将隐藏在最后一个索引中。请帮助我。

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)

在您的状态中添加两个变量作为

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
........

然后在显示左右按钮的构建函数中添加 if 语句

@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(() {});
                              },
                            ),
                          ),
                        ),
                      ),
                      ...............

右键相同的代码。

您无法通过当前的代码结构来完成。要实现它,您必须像这样在 listView 中移动那些箭头按钮 Icons

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

我认为用 Flutter_Swiper 替换 ListView.builder 可能更容易,这会让您的生活更轻松。或者,也许您可​​以在 initState 中向 ScrollController 添加一个监听器,它处理两个布尔变量 leftButtonEnabledrightButtonEnabled 的值 并根据控制器的位置将它们设置为 true 或 false

编辑: 这是在您的代码中使用 Flutter swiper 的示例,我试图让它变得简单,同时添加多个可以帮助您的功能(例如 SwiperControl )我希望它能对您有所帮助。

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