feat(flutter): 重设计剧场与首页 Hero
This commit is contained in:
1 parent
678b976ce1
commit
73aef4e44e
19 files changed
+339
-312
No files matched your search
@@ -39,9 +39,7 @@ class FeedBannerCarousel extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
|
||||
final PageController _controller = PageController(
|
||||
viewportFraction: _viewportFraction,
|
||||
);
|
||||
late final PageController _controller;
|
||||
Timer? _timer;
|
||||
int _index = 0;
|
||||
bool _pressed = false;
|
||||
@@ -50,6 +48,9 @@ class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = PageController(
|
||||
viewportFraction: widget.dramaFor == null ? _viewportFraction : 1,
|
||||
);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _syncTimer());
|
||||
}
|
||||
|
||||
@@ -116,28 +117,43 @@ class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.banners.isEmpty) return const SizedBox.shrink();
|
||||
final height = widget.dramaFor == null
|
||||
? _carouselHeight
|
||||
: AppDimens.heroBannerHeight;
|
||||
final hero = widget.dramaFor != null;
|
||||
final height = hero ? AppDimens.heroBannerHeight : _carouselHeight;
|
||||
final pages = PageView.builder(
|
||||
controller: _controller,
|
||||
itemCount: widget.banners.length,
|
||||
onPageChanged: (value) => setState(() => _index = value),
|
||||
itemBuilder: (context, index) => _bannerCard(index),
|
||||
);
|
||||
return Listener(
|
||||
key: const Key('feed-banner-carousel'),
|
||||
onPointerDown: (_) => _pause(),
|
||||
onPointerUp: (_) => _resume(),
|
||||
onPointerCancel: (_) => _resume(),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: height,
|
||||
child: PageView.builder(
|
||||
controller: _controller,
|
||||
itemCount: widget.banners.length,
|
||||
onPageChanged: (value) => setState(() => _index = value),
|
||||
itemBuilder: (context, index) => _bannerCard(index),
|
||||
child: hero
|
||||
? SizedBox(
|
||||
height: height,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(child: pages),
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: AppDimens.spaceXs,
|
||||
child: SizedBox(
|
||||
height: _indicatorHeight,
|
||||
child: _indicator(context),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: height, child: pages),
|
||||
SizedBox(height: _indicatorHeight, child: _indicator(context)),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: _indicatorHeight, child: _indicator(context)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -146,7 +162,9 @@ class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
|
||||
final dramaId = banner.dramaId;
|
||||
final drama = widget.dramaFor?.call(banner);
|
||||
final card = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(AppDimens.authCardRadius),
|
||||
borderRadius: BorderRadius.circular(
|
||||
drama == null ? AppDimens.authCardRadius : AppDimens.heroBannerRadius,
|
||||
),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
@@ -158,7 +176,7 @@ class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
|
||||
end: Alignment.bottomCenter,
|
||||
colors: drama == null
|
||||
? const [Color(0x00000000), Color(0x8A0B0C10)]
|
||||
: const [Color(0x120B0C10), Color(0xE60B0C10)],
|
||||
: const [Color(0x00000000), Color(0xE6000000)],
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -166,7 +184,7 @@ class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
|
||||
Positioned(
|
||||
left: AppDimens.pageHorizontal,
|
||||
right: _copyRightGap,
|
||||
bottom: AppDimens.cardPadding,
|
||||
bottom: AppDimens.spaceXl + AppDimens.spaceSm,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -179,7 +197,7 @@ class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Outfit',
|
||||
color: AppColors.onSurface,
|
||||
fontSize: AppDimens.pageTitle,
|
||||
fontSize: AppDimens.heroTitle,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
@@ -190,24 +208,28 @@ class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
color: AppColors.muted,
|
||||
fontSize: AppDimens.caption,
|
||||
fontSize: AppDimens.heroSubtitle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (dramaId != null)
|
||||
if (dramaId != null && drama == null)
|
||||
const Positioned(right: 14, bottom: 14, child: _PlayMark()),
|
||||
],
|
||||
),
|
||||
);
|
||||
final page = Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
padding: EdgeInsets.symmetric(horizontal: drama == null ? 5 : 0),
|
||||
child: dramaId == null
|
||||
? card
|
||||
: Material(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(AppDimens.authCardRadius),
|
||||
borderRadius: BorderRadius.circular(
|
||||
drama == null
|
||||
? AppDimens.authCardRadius
|
||||
: AppDimens.heroBannerRadius,
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: InkWell(
|
||||
key: Key('feed-banner-$index'),
|
||||
|
||||
Reference in new issue
Block a user