Change home titlebar to scrollable

This commit is contained in:
stonegate 2020-04-30 01:32:45 +08:00
parent a758c2d96d
commit 69d2568513
6 changed files with 209 additions and 250 deletions

View File

@ -25,6 +25,29 @@ void callbackDispatcher() {
}); });
} }
ThemeData lightTheme = ThemeData(
accentColorBrightness: Brightness.dark,
primaryColor: Colors.grey[100],
// accentColor: _accentSetColor,
primaryColorLight: Colors.white,
primaryColorDark: Colors.grey[300],
dialogBackgroundColor: Colors.white,
backgroundColor: Colors.grey[100],
appBarTheme: AppBarTheme(
color: Colors.grey[100],
elevation: 0,
),
textTheme: TextTheme(
bodyText2: TextStyle(fontSize: 15.0, fontWeight: FontWeight.normal),
),
tabBarTheme: TabBarTheme(
labelColor: Colors.black,
unselectedLabelColor: Colors.grey[400],
),
);
class SettingState extends ChangeNotifier { class SettingState extends ChangeNotifier {
KeyValueStorage themeStorage = KeyValueStorage(themesKey); KeyValueStorage themeStorage = KeyValueStorage(themesKey);
KeyValueStorage accentStorage = KeyValueStorage(accentsKey); KeyValueStorage accentStorage = KeyValueStorage(accentsKey);

View File

@ -12,80 +12,14 @@ import 'package:fluttertoast/fluttertoast.dart';
import '../../class/searchpodcast.dart'; import '../../class/searchpodcast.dart';
import '../../class/subscribe_podcast.dart'; import '../../class/subscribe_podcast.dart';
import '../../home/appbar/popupmenu.dart';
import '../../util/context_extension.dart'; import '../../util/context_extension.dart';
import '../../webfeed/webfeed.dart'; import '../../webfeed/webfeed.dart';
import '../../.env.dart'; import '../../.env.dart';
import '../nested_home.dart';
class MyHomePage extends StatefulWidget { class MyHomePageDelegate extends SearchDelegate<int> {
@override final String searchFieldLabel;
_MyHomePageState createState() => _MyHomePageState(); MyHomePageDelegate({this.searchFieldLabel})
} : super(searchFieldLabel: searchFieldLabel);
class _MyHomePageState extends State<MyHomePage> {
final _MyHomePageDelegate _delegate = _MyHomePageDelegate();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
var _androidAppRetain = MethodChannel("android_app_retain");
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
systemNavigationBarIconBrightness:
Theme.of(context).accentColorBrightness,
systemNavigationBarColor: Theme.of(context).primaryColor,
// statusBarColor: Theme.of(context).primaryColor,
),
child: Scaffold(
key: _scaffoldKey,
appBar: AppBar(
//elevation: 1.0,
centerTitle: true,
leading: IconButton(
tooltip: 'Add',
icon: const Icon(Icons.add_circle_outline),
onPressed: () async {
await showSearch<int>(
context: context,
delegate: _delegate,
);
},
),
title: Image(
image: Theme.of(context).brightness == Brightness.light
? AssetImage('assets/text.png')
: AssetImage('assets/text_light.png'),
height: 30,
),
actions: <Widget>[
PopupMenu(),
],
),
body: WillPopScope(
onWillPop: () async {
if (Platform.isAndroid) {
_androidAppRetain.invokeMethod('sendToBackground');
return false;
} else {
return true;
}
},
child: Home(),
),
),
);
}
}
class _MyHomePageDelegate extends SearchDelegate<int> {
static Future<List> getList(String searchText) async { static Future<List> getList(String searchText) async {
String apiKey = environment['apiKey']; String apiKey = environment['apiKey'];
String url = String url =
@ -329,89 +263,6 @@ class _SearchResultState extends State<SearchResult>
subscribeWorker.setSubscribeItem(item); subscribeWorker.setSubscribeItem(item);
} }
// savePodcast(String rss) async {
// if (mounted) setState(() => _adding = true);
// importOmpl.importState = ImportState.import;
// try {
// BaseOptions options = new BaseOptions(
// connectTimeout: 30000,
// receiveTimeout: 30000,
// );
// Response response = await Dio(options).get(rss);
// var dbHelper = DBHelper();
// String _realUrl = response.realUri.toString();
// bool _checkUrl = await dbHelper.checkPodcast(_realUrl);
// if (_checkUrl) {
// if (mounted) setState(() => _issubscribe = true);
// var _p = RssFeed.parse(response.data);
// print(_p.title);
// var dir = await getApplicationDocumentsDirectory();
// Response<List<int>> imageResponse = await Dio().get<List<int>>(
// _p.itunes.image.href,
// options: Options(responseType: ResponseType.bytes));
// img.Image image = img.decodeImage(imageResponse.data);
// img.Image thumbnail = img.copyResize(image, width: 300);
// String _uuid = Uuid().v4();
// File("${dir.path}/$_uuid.png")
// ..writeAsBytesSync(img.encodePng(thumbnail));
// String _imagePath = "${dir.path}/$_uuid.png";
// String _primaryColor = await getColor(File("${dir.path}/$_uuid.png"));
// String _author = _p.itunes.author ?? _p.author ?? '';
// String _provider = _p.generator ?? '';
// String _link = _p.link ?? '';
// PodcastLocal podcastLocal = PodcastLocal(
// _p.title,
// _p.itunes.image.href,
// _realUrl,
// _primaryColor,
// _author,
// _uuid,
// _imagePath,
// _provider,
// _link,
// description: _p.description);
// await groupList.subscribe(podcastLocal);
// if (_provider.contains('fireside')) {
// FiresideData data = FiresideData(_uuid, _link);
// await data.fatchData();
// }
// importOmpl.importState = ImportState.parse;
// await dbHelper.savePodcastRss(_p, _uuid);
// groupList.updatePodcast(podcastLocal.id);
// importOmpl.importState = ImportState.complete;
// } else {
// importOmpl.importState = ImportState.error;
// Fluttertoast.showToast(
// msg: 'Podcast subscribed already',
// gravity: ToastGravity.TOP,
// );
// await Future.delayed(Duration(seconds: 10));
// importOmpl.importState = ImportState.stop;
// }
// } catch (e) {
// importOmpl.importState = ImportState.error;
// Fluttertoast.showToast(
// msg: 'Network error, Subscribe failed',
// gravity: ToastGravity.TOP,
// );
// await Future.delayed(Duration(seconds: 5));
// importOmpl.importState = ImportState.stop;
// }
// }
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border: Border(

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart' hide NestedScrollView; import 'package:flutter/material.dart' hide NestedScrollView;
import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tsacdop/class/download_state.dart'; import 'package:tsacdop/class/download_state.dart';
import 'package:tsacdop/class/podcast_group.dart'; import 'package:tsacdop/class/podcast_group.dart';
@ -21,6 +22,8 @@ import '../util/custompaint.dart';
import '../home/appbar/importompl.dart'; import '../home/appbar/importompl.dart';
import '../home/audioplayer.dart'; import '../home/audioplayer.dart';
import 'appbar/addpodcast.dart';
import 'appbar/popupmenu.dart';
import 'home_groups.dart'; import 'home_groups.dart';
import 'download_list.dart'; import 'download_list.dart';
@ -30,6 +33,10 @@ class Home extends StatefulWidget {
} }
class _HomeState extends State<Home> with SingleTickerProviderStateMixin { class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
final MyHomePageDelegate _delegate =
MyHomePageDelegate(searchFieldLabel: 'Search podcast');
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TabController _controller; TabController _controller;
Decoration _getIndicator(BuildContext context) { Decoration _getIndicator(BuildContext context) {
return UnderlineTabIndicator( return UnderlineTabIndicator(
@ -41,6 +48,8 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
)); ));
} }
var _androidAppRetain = MethodChannel("android_app_retain");
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -58,7 +67,25 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
Widget build(BuildContext context) { Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width; double width = MediaQuery.of(context).size.width;
double height = (width - 20) / 3 + 140; double height = (width - 20) / 3 + 140;
return SafeArea( return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
systemNavigationBarIconBrightness:
Theme.of(context).accentColorBrightness,
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
systemNavigationBarColor: Theme.of(context).primaryColor,
),
child: Scaffold(
key: _scaffoldKey,
body: WillPopScope(
onWillPop: () async {
if (Platform.isAndroid) {
_androidAppRetain.invokeMethod('sendToBackground');
return false;
} else {
return true;
}
},
child: SafeArea(
child: Stack( child: Stack(
children: <Widget>[ children: <Widget>[
Column( Column(
@ -73,6 +100,37 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
headerSliverBuilder: headerSliverBuilder:
(BuildContext context, bool innerBoxScrolled) { (BuildContext context, bool innerBoxScrolled) {
return <Widget>[ return <Widget>[
SliverToBoxAdapter(
child: SizedBox(
height: 50.0,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
tooltip: 'Add',
icon: const Icon(
Icons.add_circle_outline),
onPressed: () async {
await showSearch<int>(
context: context,
delegate: _delegate,
);
},
),
Image(
image: Theme.of(context).brightness ==
Brightness.light
? AssetImage('assets/text.png')
: AssetImage(
'assets/text_light.png'),
height: 30,
),
PopupMenu(),
],
),
),
),
SliverList( SliverList(
delegate: SliverChildBuilderDelegate( delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) { (BuildContext context, int index) {
@ -134,7 +192,9 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
Container(child: PlayerWidget()), Container(child: PlayerWidget()),
], ],
), ),
); ),
),
));
} }
} }
@ -573,7 +633,7 @@ class _RecentUpdateState extends State<_RecentUpdate>
), ),
]), ]),
) )
: Center(child: CircularProgressIndicator()); : Center();
}, },
); );
} }

View File

@ -40,6 +40,14 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
_groupIndex = 0; _groupIndex = 0;
} }
Widget _circleContainer(BuildContext context) => Container(
margin: EdgeInsets.symmetric(horizontal: 10),
height: 50,
width: 50,
decoration:
BoxDecoration(shape: BoxShape.circle, color: context.primaryColor),
);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double _width = MediaQuery.of(context).size.width; double _width = MediaQuery.of(context).size.width;
@ -140,13 +148,46 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
height: 70, height: 70,
color: color:
Theme.of(context).scaffoldBackgroundColor, Theme.of(context).scaffoldBackgroundColor,
), child: Row(
children: <Widget>[
_circleContainer(context),
_circleContainer(context),
_circleContainer(context)
],
)),
], ],
)), )),
Container( Container(
height: (_width - 20) / 3 + 40, height: (_width - 20) / 3 + 40,
color: Theme.of(context).primaryColor, color: Theme.of(context).primaryColor,
margin: EdgeInsets.symmetric(horizontal: 15), margin: EdgeInsets.symmetric(horizontal: 15),
child: Center(
child: _groupIndex == 0
? Text.rich(TextSpan(
style: context.textTheme.headline6
.copyWith(height: 2),
children: [
TextSpan(
text: 'Welcome to Tsacdop\n',
style: context.textTheme.headline6
.copyWith(
color: context.accentColor)),
TextSpan(
text: 'Get started\n',
style: context.textTheme.headline6
.copyWith(
color: context.accentColor)),
TextSpan(text: 'Tap '),
WidgetSpan(
child:
Icon(Icons.add_circle_outline)),
TextSpan(text: ' to subscribe podcasts')
],
))
: Text('No podcast in this group',
style: TextStyle(
color: context.textTheme.bodyText2.color
.withOpacity(0.5)))),
), ),
], ],
), ),

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tsacdop/class/settingstate.dart'; import 'package:tsacdop/class/settingstate.dart';
import 'package:tsacdop/home/appbar/addpodcast.dart'; import 'package:tsacdop/home/home.dart';
import 'package:tsacdop/util/pageroute.dart'; import 'package:tsacdop/util/pageroute.dart';
import 'fourthpage.dart'; import 'fourthpage.dart';
import 'secondpage.dart'; import 'secondpage.dart';
@ -209,7 +209,7 @@ class _SlideIntroState extends State<SlideIntro> {
onTap: () { onTap: () {
if (widget.goto == Goto.home) { if (widget.goto == Goto.home) {
Navigator.push(context, Navigator.push(context,
SlideLeftRoute(page: MyHomePage())); SlideLeftRoute(page: Home()));
Provider.of<SettingState>(context, Provider.of<SettingState>(context,
listen: false) listen: false)
.saveShowIntro(); .saveShowIntro();

View File

@ -4,12 +4,12 @@ import 'package:flutter/services.dart';
import 'package:flutter_downloader/flutter_downloader.dart'; import 'package:flutter_downloader/flutter_downloader.dart';
import 'class/podcast_group.dart'; import 'class/podcast_group.dart';
import 'home/appbar/addpodcast.dart';
import 'class/audiostate.dart'; import 'class/audiostate.dart';
import 'class/settingstate.dart'; import 'class/settingstate.dart';
import 'class/download_state.dart'; import 'class/download_state.dart';
import 'class/refresh_podcast.dart'; import 'class/refresh_podcast.dart';
import 'class/subscribe_podcast.dart'; import 'class/subscribe_podcast.dart';
import 'home/home.dart';
import 'intro_slider/app_intro.dart'; import 'intro_slider/app_intro.dart';
final SettingState themeSetting = SettingState(); final SettingState themeSetting = SettingState();
@ -20,14 +20,16 @@ Future main() async {
runApp( runApp(
MultiProvider( MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(create: (_) => themeSetting), ChangeNotifierProvider(
create: (_) => themeSetting,
),
ChangeNotifierProvider(create: (_) => AudioPlayerNotifier()), ChangeNotifierProvider(create: (_) => AudioPlayerNotifier()),
ChangeNotifierProvider(create: (_) => GroupList()), ChangeNotifierProvider(create: (_) => GroupList()),
ChangeNotifierProvider(create: (_) => SubscribeWorker()), ChangeNotifierProvider(create: (_) => SubscribeWorker()),
ChangeNotifierProvider(create: (_) => RefreshWorker()), ChangeNotifierProvider(create: (_) => RefreshWorker()),
ChangeNotifierProvider( ChangeNotifierProvider(
create: (_) => DownloadState(), create: (_) => DownloadState(),
), )
], ],
child: MyApp(), child: MyApp(),
), ),
@ -50,26 +52,8 @@ class MyApp extends StatelessWidget {
themeMode: setting.theme, themeMode: setting.theme,
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: 'Tsacdop', title: 'Tsacdop',
theme: ThemeData( theme: lightTheme.copyWith(
accentColorBrightness: Brightness.dark,
primaryColor: Colors.grey[100],
accentColor: setting.accentSetColor, accentColor: setting.accentSetColor,
primaryColorLight: Colors.white,
primaryColorDark: Colors.grey[300],
dialogBackgroundColor: Colors.white,
backgroundColor: Colors.grey[100],
appBarTheme: AppBarTheme(
color: Colors.grey[100],
elevation: 0,
),
textTheme: TextTheme(
bodyText2:
TextStyle(fontSize: 15.0, fontWeight: FontWeight.normal),
),
tabBarTheme: TabBarTheme(
labelColor: Colors.black,
unselectedLabelColor: Colors.grey[400],
),
), ),
darkTheme: ThemeData.dark().copyWith( darkTheme: ThemeData.dark().copyWith(
accentColor: setting.accentSetColor, accentColor: setting.accentSetColor,
@ -80,7 +64,7 @@ class MyApp extends StatelessWidget {
.copyWith(color: setting.realDark ? Colors.black87 : null), .copyWith(color: setting.realDark ? Colors.black87 : null),
appBarTheme: AppBarTheme(elevation: 0), appBarTheme: AppBarTheme(elevation: 0),
), ),
home: setting.showIntro ? SlideIntro(goto: Goto.home) : MyHomePage(), home: setting.showIntro ? SlideIntro(goto: Goto.home) : Home(),
); );
}, },
); );