目次
1.カウント コンストラクター セット SliverGrid
2. エクステント コンストラクター セット SliverGrid
3. デフォルトのコンストラクターは SliverGrid を設定します
序文
Flutter の Sliver は、ウィジェットのスクロールに関連するいくつかのウィジェットです。アプリの開発過程では、商品情報の一覧表示や、最新の相場を更新するための株価のプルダウンなど、随所にスクロールの活用が見られます。要約すると、表示されるコンテンツの長さが現在の画面の表示範囲を超える場合、スクロール コンポーネントを使用します。最も一般的なものは、ListView と GridView です。ほとんどの場合、一般的な ListView と GridView で基本的にユーザーのニーズを満たすことができますが、複雑なアニメーションを実装する場合は、Sliver コンポーネントが役立ちます。たとえば、次のアニメーション効果では、Slivers を使用して簡単に実現できます。
今日の記事は、主に Sliver の使用方法の説明と分析です。
1.スライバーについて
開発中、ListView や GridView などのほとんどのスクロール可能なビューは、実際には Sliver を使用して実装されます。ListView の定義などのソース コードを調べてください。下のスクリーンショットは ListView の定義からのものです。
図 3. ListView の定義
GridView も次のとおりです。
図 4. GridView の定義
Sliver の公式説明によると、Sliver は低レベルのインターフェイスと見なすことができ、Sliver を使用すると、スクロール領域をより細かく制御して、さまざまな効果を実現できます。Slivers のビューは必要に応じて構築およびレンダリングされるため、スクロール可能な領域に多くのビューがある場合、Slivers は特に効率的です。
Flutter のすべてのスライバー コンポーネントは CustomScrollView で使用され、スライバー コンポーネントは CustomScrollView のサブコントロールとして使用されます。一般的に使用される Sliver は、SliverList、SliverGridView、SliverAppBar です。以下にその使い方を詳しく紹介します。
二、SliverList
SliverList にはデリゲートの必須パラメーターがあります。デリゲートには、SliverChildListDelegate と SliverChildBuilderDelegate の 2 種類があります。違いは、子コントロールを一度に作成するかどうかです。
簡単な例を使用して、2 つのデリゲートの違いを確認できます。
1.SliverChildListDelegate
たとえば、SliverList を使用して、次のレンダリングのように、異なる色の 3 つの (またはその他の数の) コンテナーを表示したいと考えています。
図 5. シンプルな SliverList
これは、次のコードで実行できます。
class SliverForListPage extends StatefulWidget {
const SliverForListPage({Key? key}) : super(key: key);
@override
State<SliverForListPage> createState() => _SliverForListPageState();
}
class _SliverForListPageState extends State<SliverForListPage> {
Color getRandomColor({int r = 255, int g = 255, int b = 255, a = 255}) {
if (r == 0 || g == 0 || b == 0) return Colors.black;
if (a == 0) return Colors.white;
return Color.fromARGB(
a,
r != 255 ? r : math.Random.secure().nextInt(r),
g != 255 ? g : math.Random.secure().nextInt(g),
b != 255 ? b : math.Random.secure().nextInt(b),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sliver用法',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 12),),
),
body: CustomScrollView(
slivers: [
SliverList(delegate: SliverChildListDelegate([
Container(color: getRandomColor(),height: 150,),
Container(color: getRandomColor(),height: 150,),
Container(color: getRandomColor(),height: 150,),
])),
],
),
);
}
}
上記のコードでは、外側のレイヤーが CustomScrollView を使用して SliverList をラップしています。Row と Column を使用したことがある場合は、2 つの使用法が似ていることがわかります.違いは、Column と Row に表示される子コントロールの配列名が children と呼ばれるのに対して、Slivers シリーズ コンポーネントは slivers を使用して表示するコントロールの配列を表します。SliverChildListDelegate は Container を 1 回作成するため、ここでコントロールを作成する SliverList の効率は高くありません。
2.SliverChildBuilderDelegate
表示するコントロールが多数ある場合は、SliverChildBuilderDelegate を使用してコントロールのリストを効率的に作成できます。次のコードを使用して無限リストを作成できます。コントロールが表示されている場合にのみ作成されるため、非常に効率的です。
class SliverForListPage extends StatefulWidget {
const SliverForListPage({Key? key}) : super(key: key);
@override
State<SliverForListPage> createState() => _SliverForListPageState();
}
class _SliverForListPageState extends State<SliverForListPage> {
Color getRandomColor({int r = 255, int g = 255, int b = 255, a = 255}) {
if (r == 0 || g == 0 || b == 0) return Colors.black;
if (a == 0) return Colors.white;
return Color.fromARGB(
a,
r != 255 ? r : math.Random.secure().nextInt(r),
g != 255 ? g : math.Random.secure().nextInt(g),
b != 255 ? b : math.Random.secure().nextInt(b),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sliver用法',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 12),),
),
body: CustomScrollView(
slivers: [
SliverList(delegate: SliverChildBuilderDelegate((context, index) => Container(color: getRandomColor(),height: 150,))),
],
),
);
}
}
図 6. 遅延読み込みによる SliverList の作成
3.スライバーグリッド
SliverGridView は、SliverList と同様に、デリゲートを表示または使用してリストを指定できます。SliverGridView を構成するには、次の 3 つの方法があります。
1.カウント コンストラクター セット SliverGrid
以下のコードを使用して、異なる色の 100 個のコンテナのリストを作成できます。
class SliverForGridViewPage extends StatefulWidget {
const SliverForGridViewPage({Key? key}) : super(key: key);
@override
State<SliverForGridViewPage> createState() => _SliverForGridViewPageState();
}
class _SliverForGridViewPageState extends State<SliverForGridViewPage> {
Color getRandomColor({int r = 255, int g = 255, int b = 255, a = 255}) {
if (r == 0 || g == 0 || b == 0) return Colors.black;
if (a == 0) return Colors.white;
return Color.fromARGB(
a,
r != 255 ? r : math.Random.secure().nextInt(r),
g != 255 ? g : math.Random.secure().nextInt(g),
b != 255 ? b : math.Random.secure().nextInt(b),
);
}
List<Widget> generateWidgetList(){
List<Widget> list = [];
for(var i = 0;i<100;i++){
Container container = Container(
color: getRandomColor(),
height: 150,
);
list.add(container);
}
return list;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('SliverGrid.extent',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 12),),
),
body: CustomScrollView(
slivers: [
SliverGrid.extent(maxCrossAxisExtent: 100,children: generateWidgetList(),),
],
),
);
}
}
図 7. SliverGrid を実装するカウント コンストラクター
2. エクステント コンストラクター セット SliverGrid
次のコードを使用して、異なる色の 100 個のコンテナーを作成できます。その効果を図 8 に示します。
class SliverForGridViewPage extends StatefulWidget {
const SliverForGridViewPage({Key? key}) : super(key: key);
@override
State<SliverForGridViewPage> createState() => _SliverForGridViewPageState();
}
class _SliverForGridViewPageState extends State<SliverForGridViewPage> {
Color getRandomColor({int r = 255, int g = 255, int b = 255, a = 255}) {
if (r == 0 || g == 0 || b == 0) return Colors.black;
if (a == 0) return Colors.white;
return Color.fromARGB(
a,
r != 255 ? r : math.Random.secure().nextInt(r),
g != 255 ? g : math.Random.secure().nextInt(g),
b != 255 ? b : math.Random.secure().nextInt(b),
);
}
List<Widget> generateWidgetList(){
List<Widget> list = [];
for(var i = 0;i<100;i++){
Container container = Container(
color: getRandomColor(),
height: 150,
);
list.add(container);
}
return list;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('SliverGrid.extent',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 12),),
),
body: CustomScrollView(
slivers: [
//这里构建了无限滚动的不同容器
SliverGrid.extent(maxCrossAxisExtent: 100,children: generateWidgetList(),),
],
),
);
}
}
図 8. SliverGrid を実装するカウント コンストラクター
3. デフォルトのコンストラクターは SliverGrid を設定します
以下のコードを使用して、図 9 に示す無効なスクロール SliverGrid グリッド ビューを作成できます。
class SliverForGridViewPage extends StatefulWidget {
const SliverForGridViewPage({Key? key}) : super(key: key);
@override
State<SliverForGridViewPage> createState() => _SliverForGridViewPageState();
}
class _SliverForGridViewPageState extends State<SliverForGridViewPage> {
Color getRandomColor({int r = 255, int g = 255, int b = 255, a = 255}) {
if (r == 0 || g == 0 || b == 0) return Colors.black;
if (a == 0) return Colors.white;
return Color.fromARGB(
a,
r != 255 ? r : math.Random.secure().nextInt(r),
g != 255 ? g : math.Random.secure().nextInt(g),
b != 255 ? b : math.Random.secure().nextInt(b),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('SliverGrid.extent',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 12),),
),
body: CustomScrollView(
slivers: [
//这里构建了无限滚动的不同容器
SliverGrid(gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4), delegate: SliverChildBuilderDelegate((context, index) => Container(
color: getRandomColor(),
height: 150,
))),
],
),
);
}
}
図 9. SliverGrid を指定するカウント コンストラクター
4.SliverAppBar
ここでは、記事の冒頭で実現した AppBar のアニメーション効果を実現する方法を見ていきます。
上記の無限スクロール コンテナー リストを例にとると、AppBar の代わりに SliverAppBar を使用し、flexibleSpace パラメーターと ExpandedHeight パラメーターを同時に設定して、記事の冒頭の効果を実現します。コードは次のとおりです。
class SliverForListPage extends StatefulWidget {
const SliverForListPage({Key? key}) : super(key: key);
@override
State<SliverForListPage> createState() => _SliverForListPageState();
}
class _SliverForListPageState extends State<SliverForListPage> {
Color getRandomColor({int r = 255, int g = 255, int b = 255, a = 255}) {
if (r == 0 || g == 0 || b == 0) return Colors.black;
if (a == 0) return Colors.white;
return Color.fromARGB(
a,
r != 255 ? r : math.Random.secure().nextInt(r),
g != 255 ? g : math.Random.secure().nextInt(g),
b != 255 ? b : math.Random.secure().nextInt(b),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
title: const Text('SliverList',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 12),),
backgroundColor: Colors.blue,
flexibleSpace: FlexibleSpaceBar(
background: Image.asset('images/header.jpeg',fit: BoxFit.cover,),
),
),
SliverList(delegate: SliverChildBuilderDelegate((context, index) => Container(color: getRandomColor(),height: 150,))),
],
),
);
}
}
得られる効果は次のとおりです。
図 10. SliverApp 効果
この時点で、SliverAppBar が下のリストに沿ってスクロールすることがわかります。プルダウン時、expandedHeight パラメーターを超えると SliverAppBar が表示され、上方向にスライドすると、SliverAppBar が消えるまでリストに沿ってスライドします。
いくつかのパラメーターを設定して、AppBar アニメーション効果をカスタマイズすることもできます。
浮動パラメーターを true に設定したときの変更を確認します (図 11)。時間を下にスクロールすると、リストの一番上にない場合は SliverAppBar も表示されることがわかりました。
図 11. SliverAppBar
snap パラメーターと float パラメーターを同時に true に設定すると、下にスクロールすると、SliverAppBar が自動的に表示に戻ります (図 12)。
図 13. SliverAppBar
もちろん、必要に応じてさまざまなパラメーターを設定して、独自の AppBar アニメーション効果を実現できます。
この記事を読んだ後、SliverList、SliverGrid、および SliverAppBar を組み合わせて、記事の冒頭でグループ化効果を実現する方法を検討することもできます。幸運を!