Skip to content

Instantly share code, notes, and snippets.

@Ryan4CN
Last active May 8, 2023 02:27
Show Gist options
  • Save Ryan4CN/76f01918396675807ddf76fd26c26599 to your computer and use it in GitHub Desktop.
Save Ryan4CN/76f01918396675807ddf76fd26c26599 to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
import 'package:gistaff/page/song_list.dart';
class StartPage extends StatefulWidget {
final List<PageConfig> pages;
const StartPage({Key? key, required this.pages}) : super(key: key);
@override
_StartPageState createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
final PageController _pageController = PageController(initialPage: 0);
int _currentPage = 0;
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
physics: const ClampingScrollPhysics(),
controller: _pageController,
onPageChanged: (int page) {
setState(() {
_currentPage = page;
});
},
children: widget.pages
.map((page) => _buildPage(
page,
widget.pages.indexOf(page),
))
.toList(),
),
);
}
Widget _buildPage(PageConfig pageConfig, int pageIndex) {
final isLastPage = widget.pages.last == pageConfig;
return Container(
color: pageConfig.backgroundColor,
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: LayoutBuilder(
builder: (context, constraints) {
return SizedBox(
width: constraints.maxWidth * 0.8,
height: constraints.maxHeight * 0.5,
child: Image.asset(
pageConfig.imagePath,
fit: BoxFit.contain,
),
);
},
),
),
const SizedBox(height: 20),
Text(
pageConfig.promotionText,
style: TextStyle(
fontSize: MediaQuery.of(context).size.height * 0.05,
color: Colors.white,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 20),
if (isLastPage)
Hero(
tag: 'enterButton',
child: Container(
width: MediaQuery.of(context).size.width * 0.4,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SongListPage(),
),
);
},
child: Container(
height: 50,
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: const BorderRadius.horizontal(
left: Radius.circular(25),
right: Radius.circular(25),
),
border: Border.all(
width: 2,
color: Colors.white,
),
),
child: Center(
child: Text(
'开始体验',
style: TextStyle(
color: Colors.white,
fontSize:
MediaQuery.of(context).size.height * 0.05),
),
),
),
),
)),
if (!isLastPage)
Container(
margin: const EdgeInsets.only(bottom: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
widget.pages.length,
(index) => _buildDot(
_currentPage == index,
),
),
)),
],
)),
);
}
Widget _buildDot(bool isActive) {
return AnimatedContainer(
duration: const Duration(milliseconds: 300),
width: isActive ? 16 : 10,
height: isActive ? 16 : 10,
margin: const EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isActive ? Colors.orange : Colors.white,
),
);
}
}
class PageConfig {
final String imagePath;
final String promotionText;
final Color backgroundColor;
PageConfig({
required this.imagePath,
required this.promotionText,
this.backgroundColor = Colors.white,
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment