我创建了一个 flutter 小部件,它由几个组成应用栏和选项卡的条子组成,在其下方,我有 TabBarView。
1) 选项卡和主体 ScrollView 之间有过多的填充,但我不确定是什么元素导致了它。
2) 在 ListView 中滚动内容时,它显示在选项卡后面,我不确定我需要做什么来防止这种情况发生。
3)最后,您可以滚动直到 ListView 中没有更多可见项目,您将如何滚动类似于 html/css 溢出,它在内容末尾停止滚动?
这是我的看法
import 'package:flutter/material.dart';
import 'package:nssa/bloc/conference/bloc.dart';
class ConferencePage extends StatelessWidget {
final Conference conference;
ConferencePage(@required this.conference);
TabBar getTabBar(List<Zone> zones) {
return TabBar(
tabs: zones.map((zone) {
return new Tab(text: zone.type);
}).toList(growable: false)
);
}
TabBarView getTabBody(List<Zone> zones) {
return TabBarView(
children: zones.map((zone) {
return ListView(
children: zone.upcomingEvents().map((event) {
return new ListTile(title: Text(event.name));
}).toList(growable: false)
);
}).toList(growable: false)
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: this.conference.zones.length,
child: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 200.0,
floating: true,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text(
this.conference.name,
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
)
),
background: Hero(
tag: this.conference.name,
child: Image.network(
this.conference.image,
fit: BoxFit.cover,
)
)
),
),
SliverPersistentHeader(
delegate: _SliverAppBarDelegate(
this.getTabBar(this.conference.zones),
),
pinned: true,
),
];
},
body: this.getTabBody(this.conference.zones)
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.card_membership)
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate(this._tabBar);
final TabBar _tabBar;
@override
double get minExtent => _tabBar.preferredSize.height;
@override
double get maxExtent => _tabBar.preferredSize.height;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return new Container(
child: _tabBar,
);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的模型
import 'package:flutter/foundation.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import 'package:intl/intl.dart';
import 'dart:developer';
@immutable
class Zone extends Equatable {
final String type;
final List<String> divisions;
final List<Event> events;
final DateTime _now = DateTime.now();
Zone (
@required this.type,
@required this.divisions,
@required this.events,
);
@override
List<Object> get props => [type, /*divisions,*/ events];
Event currentEvent() {
return this.events.firstWhere((event) => event.startDate.isBefore(_now) && event.endDate.isAfter(_now), orElse: () => null);
}
List<Event> pastEvents() {
return this.events.where((event) => event.endDate.isBefore(_now)).toList(growable: false);
}
List<Event> upcomingEvents() {
return this.events.where((event) => event.startDate.isAfter(_now)).toList(growable: false);
}
factory Zone.fromJson(Map<String, dynamic> zoneJSON) {
List<String> divisions = (zoneJSON['divisions'] as List).map((division) {
return division.toString();
}).toList(growable: true);
List<Event> events = (zoneJSON['events'] as List).map((event) {
return new Event.fromJson(event);
}).toList(growable: true);
events.sort((a,b) => a.startDate.compareTo(b.startDate));
return Zone(
zoneJSON['type'],
divisions,
events,
);
}
}
@immutable
class Event extends Equatable {
final String name;
final String details;
final DateTime startDate;
final DateTime endDate;
final String image;
final String ticketURL;
Event (
@required this.name,
@required this.details,
@required this.startDate,
@required this.endDate,
@required this.image,
@required this.ticketURL,
);
@override
List<Object> get props => [name, startDate, endDate, details, image, ticketURL];
factory Event.fromJson(Map<String, dynamic> eventJSON) {
DateFormat dateFormat = DateFormat("yyyy-MM-dd");
return Event(
eventJSON['name'],
eventJSON['details'],
dateFormat.parse(eventJSON['startDate'].toString()),
dateFormat.parse(eventJSON['endDate'].toString()),
eventJSON['image'],
eventJSON['ticketURL']
);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 1
使用 NestedScrollView 时,您可能需要使用 SliverOverlapAbsorber 包裹 SliverAppBar,以避免主体内容在应用栏下方滚动。
另外,您最好将 TabBar 放在bottomSliverAppBar 中,就像官方示例一样。
请参阅此处的文档:https ://api.flutter.dev/flutter/widgets/NestedScrollView-class.html
| 归档时间: |
|
| 查看次数: |
1322 次 |
| 最近记录: |