Flutter: memompa AppBar & SliverAppBar

Flutter menggunakan AppBar yang terkenal untuk membuat toolbar, tetapi ketika kita membutuhkan toolbar dinamis yang menampilkan konten saat menggesek, kita menggunakan widget SliverAppBar yang sangat baik.


Kedua widget memungkinkan Anda untuk membuat aplikasi sedikit lebih indah, yang di Flutter, tanpa ragu, sangat sederhana.


Saya melihat banyak pertanyaan di StackOverflow dan di grup Facebook tentang bagaimana Anda dapat mengubah AppBar dan SliverAppBar dalam hal perilaku atau desain.


Mari kita lihat dua tugas.


Tugas 1


Kami ingin membuat AppBar yang tidak dipencet ke bagian atas layar, tetapi tidak seperti biasanya. Kami ingin menambahkan Drawer (menu samping), di mana AppBar akan merespons. Itu dia: AppBar kita sendiri   dengan dimensi yang kita butuhkan.


Masalahnya adalah, seperti yang kita tahu, AppBar memiliki ukuran default, dan kita tidak bisa mengubahnya. Setelah melihat kode sumber, kita melihat parameter appBar di Scaffold , kita melihat bahwa ia menerima widget seperti PreferredSizeWidget , sekarang kita melihat kode sumber AppBar dan mengetahui bahwa ini hanya StatefulWidget yang mengimplementasikan PreferredSizeWidget .



Intinya kecil: cukup buat widget kita sendiri yang mengimplementasikan PreferredSizeWidget .


Itu yang kita inginkan



Bagaimana Anda melakukannya sehingga ketika Anda mengklik tombol menu AppBar kami , menu samping terbuka.


Kita dapat melakukan ini dengan dua cara:


Menggunakan `AppBar`


Inilah bagaimana AppBar dapat mengontrol pembukaan bilah sisi di dalam Scaffold .


class Sample1 extends StatelessWidget { @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( drawer: Drawer(), appBar: MyCustomAppBar( height: 150, ), body: Center( child: FlutterLogo( size: MediaQuery.of(context).size.width / 2, ), ), ), ); } } class MyCustomAppBar extends StatelessWidget implements PreferredSizeWidget { final double height; const MyCustomAppBar({ Key key, @required this.height, }) : super(key: key); @override Widget build(BuildContext context) { return Column( children: [ Container( color: Colors.grey[300], child: Padding( padding: EdgeInsets.all(30), child: AppBar( title: Container( color: Colors.white, child: TextField( decoration: InputDecoration( hintText: "Search", contentPadding: EdgeInsets.all(10), ), ), ), actions: [ IconButton( icon: Icon(Icons.verified_user), onPressed: () => null, ), ], ) , ), ), ], ); } @override Size get preferredSize => Size.fromHeight(height); } 

Menggunakan widget khusus


Di sini kami memiliki lebih banyak fleksibilitas dan Anda dapat menggunakan GlobalKey seperti ScaffoldState atau InheritedWidget dari Scaffold , sehingga mendapatkan akses ke metode negara untuk membuka Drawer .


 import 'package:flutter/material.dart'; class Sample1 extends StatelessWidget { @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( drawer: Drawer(), appBar: MyCustomAppBar( height: 150, ), body: Center( child: FlutterLogo( size: MediaQuery.of(context).size.width / 2, ), ), ), ); } } class MyCustomAppBar extends StatelessWidget implements PreferredSizeWidget { final double height; const MyCustomAppBar({ Key key, @required this.height, }) : super(key: key); @override Widget build(BuildContext context) { return Column( children: [ Container( color: Colors.grey[300], child: Padding( padding: EdgeInsets.all(30), child: Container( color: Colors.red, padding: EdgeInsets.all(5), child: Row(children: [ IconButton( icon: Icon(Icons.menu), onPressed: () { Scaffold.of(context).openDrawer(); }, ), Expanded( child: Container( color: Colors.white, child: TextField( decoration: InputDecoration( hintText: "Search", contentPadding: EdgeInsets.all(10), ), ), ), ), IconButton( icon: Icon(Icons.verified_user), onPressed: () => null, ), ]), ), ), ), ], ); } @override Size get preferredSize => Size.fromHeight(height); } 

Hasil



Sederhana bukan? Mari kita lihat tugas kedua untuk SliverAppBar .


Tugas 2


Seperti yang kita ketahui, SliverAppBar berfungsi sebagai berikut:



Yang kami inginkan adalah memasukkan Kartu yang sudah terpasang ke dalam SliverAppBar kami, seperti yang ditunjukkan pada gambar berikut.



Tunggu, tetapi konten di dalam SliverAppBar dipangkas, sehingga tidak dapat melampaui apa yang harus dilakukan?



Tanpa panik, mari kita lihat kode sumber SliverAppBar dan, oh, mengejutkan, ini StatefulWidget menggunakan SliverPersistentHeader di dalam, itu rahasia keseluruhan.


Kami akan membuat SliverPersistentHeaderDelegate kita sendiri untuk menggunakan SliverPersistentHeader .


 class Sample2 extends StatelessWidget { @override Widget build(BuildContext context) { return SafeArea( child: Material( child: CustomScrollView( slivers: [ SliverPersistentHeader( delegate: MySliverAppBar(expandedHeight: 200), pinned: true, ), SliverList( delegate: SliverChildBuilderDelegate( (_, index) => ListTile( title: Text("Index: $index"), ), ), ) ], ), ), ); } } class MySliverAppBar extends SliverPersistentHeaderDelegate { final double expandedHeight; MySliverAppBar({@required this.expandedHeight}); @override Widget build( BuildContext context, double shrinkOffset, bool overlapsContent) { return Stack( fit: StackFit.expand, overflow: Overflow.visible, children: [ Image.network( "https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500", fit: BoxFit.cover, ), Center( child: Opacity( opacity: shrinkOffset / expandedHeight, child: Text( "MySliverAppBar", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 23, ), ), ), ), Positioned( top: expandedHeight / 2 - shrinkOffset, left: MediaQuery.of(context).size.width / 4, child: Opacity( opacity: (1 - shrinkOffset / expandedHeight), child: Card( elevation: 10, child: SizedBox( height: expandedHeight, width: MediaQuery.of(context).size.width / 2, child: FlutterLogo(), ), ), ), ), ], ); } @override double get maxExtent => expandedHeight; @override double get minExtent => kToolbarHeight; @override bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true; } 

Hasil



Selesai, kedua tugas diselesaikan.


Contohnya ada di repositori ini .


Kesimpulan


Seringkali kita putus asa ketika kita tidak menemukan properti widget, tetapi Anda hanya perlu melihat kode sumbernya untuk memahami bagaimana itu diterapkan dalam Flutter, sehingga menemukan bagaimana kita dapat mengimplementasikan widget kita sendiri.

Source: https://habr.com/ru/post/id456054/


All Articles