Flutter(十一)——縮進相冊效果實現

界面設計

圖片輪播效果實現一般都用在相冊之中,所以我們的主界面應該是一個相冊App的樣式,假設我們的相冊是這個樣子的,如下圖所示(同樣也是最後代碼的實現效果):

相冊實現

其中,它有一個標題欄,上面僅僅寫了APP的名字叫:lyj圖片瀏覽器,接着下面是一個背景圖,圖中有一個我的相冊的文字提示,接着下面就是我們的網格樣式的所有圖片,那麼我們應該使用哪些組件呢?

肯定會有網格組件GridView,其次爲了效果好看我們使用了層疊組件Stack,所以這裏我們有了兩個滑動組件,那麼就需要使用CustonScrollView,而GridView也需要採用SliverGrid組件,App所有的界面控件弄清楚了,下面就該編寫代碼了。

代碼設計

首先,我們需要認識一個新的可以伸縮的頭部組件SliverPersistentHeader,藉着新項目認識一下其他組件還是有好處的,它有點類似與SliverAppBar,也是可以根據滾動的距離縮小高度。並且這個組件SliverPersistentHeader也有一個抽象類SliverPersistentHeaderDelegate,這裏我們需要實現該接口,代碼如下:

抽象類SliverPersistentHeaderDelegate實現

class MySliverPersistentHeaderDelegate implements SliverPersistentHeaderDelegate{
  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Stack(//類似於Java開發Android中FrameLayout控件
      fit: StackFit.expand,//大小與父組件一樣大
      children: <Widget>[
        Image.asset(
          'assets/timg.jpg',
          fit: BoxFit.cover,//充滿容器,可能會被截斷。
        ),
        Container(
          decoration: BoxDecoration(//裝飾器
            gradient: LinearGradient(//線性漸變
              colors: [
                Colors.transparent,
                Colors.black54
              ],
              stops: [0.5, 1.0],//漸變的取值
              //從上到下漸變
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              tileMode: TileMode.repeated,
            ),
          ),
        ),
        Positioned(
          //離左右下的邊距
          left: 16.0,
          right: 16.0,
          bottom: 16.0,
          child: Text(
            '我的相冊',
            style: TextStyle(fontSize: 28.0, color: Colors.white),
          ),
        ),
      ],
    );
  }
  //構造函數傳入:maxExtent表示header完全展開時的高度,minExtent表示header在收起時的最小高度
  MySliverPersistentHeaderDelegate({
    this.minExtent,
    this.maxExtent,
  });

  double maxExtent;
  double minExtent;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }

  @override
  // TODO: implement snapConfiguration
  FloatingHeaderSnapConfiguration get snapConfiguration => null;

  @override
  // TODO: implement stretchConfiguration
  OverScrollHeaderStretchConfiguration get stretchConfiguration => null;

}

MyHomePage

上面代碼註釋已經非常多了,這裏就不在贅述了,接着就是我們主界面MyHomePage的實現,具體的代碼如下:

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'lyj圖片瀏覽器',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'lyj圖片瀏覽器'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final int rowCount = 3;   // 每行顯示的圖片數
  final List<String> imagesList = [//用到的圖片
    'assets/1.jpg',
    'assets/2.jpg',
    'assets/3.jpg',
    'assets/4.jpg',
    'assets/5.jpg',
    'assets/6.jpg',
    'assets/7.jpg',
    'assets/8.jpg',
    'assets/9.jpg',
  ];

  Widget _scrollView(BuildContext context){
    return Container(
      child: CustomScrollView(
        slivers: <Widget>[
          SliverPersistentHeader(
            pinned: true,//是否可以展開
            delegate: MySliverPersistentHeaderDelegate(minExtent: 100,maxExtent: 200),
          ),
          SliverGrid(
            gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
              maxCrossAxisExtent: MediaQuery.of(context).size.width / rowCount,//屏幕寬度除每行個數,單個子Widget的水平最大寬度
              mainAxisSpacing: 0.0,//水平單個子Widget之間間距
              crossAxisSpacing: 0.0,//垂直單個子Widget之間間距
              childAspectRatio: 9.0/16,//寬高比
            ),
            delegate: SliverChildBuilderDelegate((BuildContext context,int index){
              return Container(
                alignment: Alignment.center,
                padding: EdgeInsets.only(top: 2,left: 2,bottom: 2,right: 2),//各填充2個空白像素
                child: Image.asset(imagesList[index%imagesList.length]),
              );
            },childCount: imagesList.length*3),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: new Text(widget.title),),
      body: _scrollView(context),
    );
  }
}

代碼很簡單,與前面博文講解多元素組件的GridView一樣實現的,當然這裏是把body中的組件全提取出來了,這樣看起來簡介一些。當然那些圖片需要配置到pubspec.yaml文件中:

flutter:
  assets:
     - assets/1.jpg
     - assets/2.jpg
     - assets/3.jpg
     - assets/4.jpg
     - assets/5.jpg
     - assets/6.jpg
     - assets/7.jpg
     - assets/8.jpg
     - assets/9.jpg
     - assets/timg.jpg

GitHub代碼下載地址:點擊下載

發佈了109 篇原創文章 · 獲贊 144 · 訪問量 105萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章