如何在 flutter 上创建图片库?

How to create an image gallery on flutter?

我有一个包含图像文件列表的 Set<String> 变量。在 Card 对象中,除了一些 Text 元素外,我想创建一个像这样的图像库:

Set<String> 中存储的图像数量是可变的。如果可能的话,我想在一个角落(右上角)显示当前图像数量和图像总数(例如 1/5)。

图片将从网络服务器中取出,我不知道将它们保存在缓存中是否更有效。我不想使用存储文件夹来保存图像。

如果可能的话,我会在一个 http 请求中撤回所有图像,以节省时间。

这里是变量:

Set<String> _photosList = {
'http://myhost.com/image01.jpg',
'http://myhost.com/image02.bmp',
'http://myhost.com/image03.png',
'http://myhost.com/image04.gif',
};

在实际开始编写代码之前,我希望您先了解一些内容。它们是:

  • PageView class,这将帮助您了解这个滚动的东西是如何像画廊视图一样工作的。此外,将告诉您 nextPagepreviousPage 如何与图标点击一起使用
  • PageController class 页面在 PageView
  • 中是如何工作的
  • Stack class,用于将箭头对齐到您的画廊顶部

现在让我们跳转到代码是如何工作的。 关注评论了解每部作品

  // this will keep track of the current page index
  int _pageIndex = 0;
  
  // this is your page controller, which controls the page transition
  final PageController _controller = new PageController();
  
  Set<String> _photosList = {
    'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcRqRwpDKN_zJr1C7pPeWcwOa36BtPm4HeLPgA&usqp=CAU',
    'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSgjZ8pw5WLIGMBibVi_g4CMlSE-EOvrLv7Ag&usqp=CAU',
    'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQUuMIENOhc1DmruZ6SwLc7JtrR6ZMBRAb3jQ&usqp=CAU',
    'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcRzasDrBHWV-84vxbmlX7MTuz3QHqtT8jtTuA&usqp=CAU'
  };

现在 UI 画廊视图。

请注意:此代码支持在视图中滑动功能。如果你想禁用它,只需在 Pageview.builder()

中添加这一行
physics:new NeverScrollableScrollPhysics()
         Container(
            // use MediaQuery always, it will always adjust the dimensions
            // according to different screens
            height: MediaQuery.of(context).size.height * 0.3,
            width: MediaQuery.of(context).size.width * 0.4,
            // here is your stack
            child: Stack(
              children: [
                // PageView.builder is just the part of PageView, read through
                // Documentation, and you will get to know
                PageView.builder(
                  controller: _controller,
                  // here you can remove swipe gesture. UNCOMMENT IT 
                  // physics:new NeverScrollableScrollPhysics()
                  onPageChanged: (index){ 
                    // with each change updating the index of our variable too
                    setState(() => _pageIndex = index);
                  },
                  itemCount: _photosList.length,
                  // building the view of our gallery
                  itemBuilder: (BuildContext context, int position){
                    return Align(
                      alignment: Alignment.topLeft,
                      child: Container(
                        decoration: BoxDecoration(
                          image: DecorationImage(
                            fit: BoxFit.cover,
                            image: NetworkImage(_photosList.elementAt(position))
                          )
                        )
                      )
                    );
                  }
                ),
                
                // this will come over the images, the icon buttons
                Positioned(
                  left: 0.0,
                  right: 0.0,
                  top: MediaQuery.of(context).size.height * 0.12,
                  child: Row(
                    mainAxisSize: MainAxisSize.min,
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      IconButton(
                        onPressed: (){
                          // checking if we are not on pos = 0
                          // then we can always go back else do nothing
                          if(_pageIndex != 0)
                            _controller.previousPage(duration: Duration(milliseconds: 200), curve: Curves.easeIn);
                        },
                        icon: Icon(Icons.arrow_back_ios, color: Colors.white, size: 28.0)
                      ),
                      IconButton(
                        onPressed: (){
                          // checking if we are not on pos = photosList.length - 1
                          // we calculate 0 to length-1
                          // then we can always go forward else do nothing
                          if(_pageIndex < _photosList.length-1)
                            _controller.nextPage(duration: Duration(milliseconds: 200), curve: Curves.easeIn);
                        },
                        icon: Icon(Icons.arrow_forward_ios, color: Colors.white, size: 28.0)
                      ),
                    ]
                  )
                )
              ]
            )
          )

结果

指针: 为了显示它们在角上的编号。只需使用代码中已有的两个变量

  • _pageIndex,持续更新页面变化
  • _photosList.length,它给出了图像的总数

做这样的事情,并在同一视图中使用 Container 显示它。

//_pageIndex + 1, cos it starts from 0 not 1, and goes up to 4 not 5
Text('${_pageIndex+1}/$_photosList.length')