Files
packages.dart/deprecated/cupertino_controllers/lib/master_detail_controller/controller.dart
T
2026-01-15 14:38:46 -08:00

139 lines
3.8 KiB
Dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
typedef ItemWidgetBuilder = Widget Function(
BuildContext context, dynamic item, bool tablet);
typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);
class CupertinoMasterDetailController extends StatelessWidget {
final ItemWidgetBuilder detailBuilder;
final IndexedWidgetBuilder itemBuilder;
final Widget? onNull, onEmpty;
final PreferredSizeWidget? appBar;
final dynamic selectedItem;
final ValueChanged<dynamic> itemSelected;
final List<dynamic> items;
CupertinoMasterDetailController({
required this.detailBuilder,
required this.selectedItem,
required this.itemSelected,
required this.itemBuilder,
required this.items,
this.appBar,
this.onNull,
this.onEmpty,
});
Widget _buildMobileLayout(BuildContext context) {
return Scaffold(
body: CupertinoPageScaffold(
child: CustomScrollView(
semanticChildCount: items.length,
slivers: <Widget>[
CupertinoSliverNavigationBar(
largeTitle: Text("Presidents"),
),
_ItemListing(
onEmpty: onEmpty,
onNull: onNull,
itemBuilder: itemBuilder,
items: items,
selectedItem: selectedItem,
itemSelectedCallback: (item) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => detailBuilder(context, item, false)),
);
},
),
])));
}
Widget _buildTabletLayout(BuildContext context) {
return OrientationBuilder(builder: (context, orientation) {
return Row(
children: <Widget>[
Flexible(
flex: orientation == Orientation.landscape ? 1 : 2,
child: Scaffold(
appBar: appBar,
body: CustomScrollView(slivers: [
_ItemListing(
onEmpty: onEmpty,
onNull: onNull,
itemBuilder: itemBuilder,
items: items,
selectedItem: selectedItem,
itemSelectedCallback: itemSelected,
),
])),
),
Container(
width: 1.0,
color: Colors.grey[300],
),
Flexible(
flex: 3,
child: detailBuilder(context, selectedItem, true),
),
],
);
});
}
@override
Widget build(BuildContext context) {
var shortestSide = MediaQuery.of(context).size.shortestSide;
final bool useMobileLayout = shortestSide < 600;
if (useMobileLayout) {
return _buildMobileLayout(context);
}
return _buildTabletLayout(context);
}
}
class _ItemListing extends StatelessWidget {
_ItemListing({
required this.itemSelectedCallback,
this.selectedItem,
this.itemBuilder,
this.items,
this.onNull,
this.onEmpty,
});
final ValueChanged<dynamic> itemSelectedCallback;
final dynamic selectedItem;
final IndexedWidgetBuilder? itemBuilder;
final List<dynamic>? items;
final Widget? onNull, onEmpty;
@override
Widget build(BuildContext context) {
if (items == null) {
return onNull ?? Center(child: CircularProgressIndicator());
}
if (items!.isEmpty) {
return onEmpty ?? Center(child: Text("No Items Found"));
}
return SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
final _child = itemBuilder!(context, index);
return GestureDetector(
onTap: () => itemSelectedCallback(items![index]),
child: _child,
);
},
childCount: items!.length,
),
);
}
}