Trying to use ListView inside YoutubePlayerBuilder in flutter - flutter

I'm trying to basically have a youtube video on top, with a scrollable Listview below. Can't get the listview to be scrollable though. Here's the code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.blueAccent,
),
);
runApp(YoutubePlayerDemoApp());
}
class YoutubePlayerDemoApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Youtube Player Flutter',
theme: ThemeData(
primarySwatch: Colors.blue,
appBarTheme: const AppBarTheme(
color: Colors.blueAccent,
textTheme: TextTheme(
headline6: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w300,
fontSize: 20.0,
),
),
),
iconTheme: const IconThemeData(
color: Colors.blueAccent,
),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
YoutubePlayerController _controller;
TextEditingController _idController;
TextEditingController _seekToController;
PlayerState _playerState;
YoutubeMetaData _videoMetaData;
double _volume = 100;
bool _muted = false;
bool _isPlayerReady = false;
final List<String> _ids = [
'srqZ5jsvXEc',
];
final testData = ["## Ingredients", "### 1 cup peanuts", "### Example2", "### Example 2", "### Example100", "## ", "## Method", "### This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text. This is a paragraph with long text.", "### Set aside to cool. Then serve."];
#override
void initState() {
super.initState();
_controller = YoutubePlayerController(
initialVideoId: _ids.first,
flags: const YoutubePlayerFlags(
mute: false,
autoPlay: false,
disableDragSeek: false,
loop: false,
isLive: false,
forceHD: false,
enableCaption: true,
),
)..addListener(listener);
_idController = TextEditingController();
_seekToController = TextEditingController();
_videoMetaData = const YoutubeMetaData();
_playerState = PlayerState.unknown;
}
void listener() {
if (_isPlayerReady && mounted && !_controller.value.isFullScreen) {
setState(() {
_playerState = _controller.value.playerState;
_videoMetaData = _controller.metadata;
});
}
}
#override
void deactivate() {
// Pauses video while navigating to next page.
_controller.pause();
super.deactivate();
}
#override
void dispose() {
_controller.dispose();
_idController.dispose();
_seekToController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final _markDownData = testData.map((x) => "$x\n").reduce((x, y) => "$x$y");
return YoutubePlayerBuilder(
onExitFullScreen: () {
// The player forces portraitUp after exiting fullscreen. This overrides the behaviour.
SystemChrome.setPreferredOrientations(DeviceOrientation.values);
},
player: YoutubePlayer(
controller: _controller,
showVideoProgressIndicator: true,
progressIndicatorColor: Colors.blueAccent,
topActions: <Widget>[
const SizedBox(width: 8.0),
Expanded(
child: Text(
_controller.metadata.title,
style: const TextStyle(
color: Colors.white,
fontSize: 18.0,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
],
onReady: () {
_isPlayerReady = true;
},
onEnded: (data) {
_controller
.load(_ids[(_ids.indexOf(data.videoId) + 1) % _ids.length]);
},
),
builder: (context, player) => Scaffold(
key: _scaffoldKey,
appBar: AppBar(
leading: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: Image.asset(
'assets/ypf.png',
fit: BoxFit.fitWidth,
),
),
title: const Text(
'Youtube Player Flutter',
style: TextStyle(color: Colors.white),
),
),
body: ListView(
children: [
player,
Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Vegan Burritos',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30.0),
),
),
FlatButton(child: Icon(Icons.favorite_border, color: Colors.redAccent,), onPressed: () {
print('favourite button was pressed');
},),
],
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Icon(Icons.star),
Icon(Icons.star),
Icon(Icons.star),
Icon(Icons.star_half),
Icon(Icons.star_border),
SizedBox(width: 10.0,),
Text('Rate Recipe'),
],
),
),
Container(
height: 1000.0,
child: Markdown(data: _markDownData),
),
],
),
),
],
),
),
);
}
}
Any ideas? I figure its probably because i'm trying to do it inside the YoutubePlayerBuilder but not sure how else to do it. I tried wrapping the YoutubePlayerBuilder inside a listview, but it didn't work.
Thanks in advance,
Jason

SOLVED!!! I just had to change
Container(
height: 1000.0,
child: Markdown(data: _markDownData),
),
to:
Container(
height: 1000.0,
child: MarkdownBody(data: _markDownData),
),
Hope this helps someone in the future!

Related

I'm having issues using Shared Preferences on another page

I have been having issues retrieving the "username" String saved in Shared Preferences (from the Settings page) for the home page text field (~Line 60 main.dart). I have tried a few methods to retrieve it, but so far I haven't had any luck with trying to grab it. The last attempt I tried was using '$user' (~Line 29), but I still haven't had any luck. I'm still very new to Flutter programming, but I had assumed you could access Shared Preferences data globally as long as you had the Key. So far when I tried using the methods I saw online and in documentation I had no luck transferring the data. Thank you for your help!
main.dart
import 'package:bit/shared_preferences.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:bit/saved_data.dart';
void main() {
runApp(MaterialApp(
title: 'App',
themeMode: ThemeMode.system,
theme: MyThemes.lightTheme,
darkTheme: MyThemes.darkTheme,
home: MyApp(),
));
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final theme = MediaQuery.of(context).platformBrightness == Brightness.dark
? 'Dark Theme'
: 'Light Theme';
final user = ''; // Empty String Line 29
var scaffold = Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
// Body Home Page Beginning
body: SingleChildScrollView(
child: Center(
child: Text('Hello $theme!'),
)),
// Body Home Page End
drawer: Drawer(
// Drawer Beginning
child: ListView(
children: [
// Drawer Header
DrawerHeader(
decoration: const BoxDecoration(
color: Colors.blue,
),
child: Stack(
children: const [
Align(
alignment: Alignment.centerLeft,
child: CircleAvatar(
backgroundColor: Colors.white,
radius: 50.0,
)),
Align(
alignment: Alignment.centerRight,
child: Text('$user', // Area To Input Text Line 60
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
)),
Align(
alignment: Alignment(1, 0.3),
child: Text(
'Supporter',
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
))
],
),
),
// Drawer List
ListTile(
title: const Text('Settings'),
subtitle: const Text('Account Info & Settings'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Settings()),
);
},
trailing: const Icon(Icons.arrow_forward_ios_rounded),
),
],
),
),
// Drawer End
);
return MaterialApp(
title: 'App',
themeMode: ThemeMode.system,
theme: MyThemes.lightTheme,
darkTheme: MyThemes.darkTheme,
home: scaffold,
);
}
}
// Settings Page & Account Information
class Settings extends StatefulWidget {
Settings({Key? key}) : super(key: key);
#override
State<Settings> createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
final _preferencesService = PreferencesService();
final _usernameController = TextEditingController();
void initState() {
super.initState();
_populateFields();
}
void _populateFields() async {
final settings = await _preferencesService.getSettings();
setState(() {
_usernameController.text = settings.username;
});
}
#override
Widget build(BuildContext context) {
final theme = MediaQuery.of(context).platformBrightness == Brightness.dark
? 'Dark Theme'
: 'Light Theme';
return Scaffold(
appBar: AppBar(
title: const Text(
'Settings'), /* actions: <Widget>[
IconButton(
onPressed: () async {
_saveSettings;
},
icon: const Icon(Icons.save),
tooltip: 'Save Settings')
] */
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 8, 8, 8),
child: Column(
children: [
Column(
// Account
children: [
const Padding(
padding: EdgeInsets.fromLTRB(0, 12, 0, 0),
child: Text('Account Information',
style: TextStyle(
fontSize: 17.0,
))),
Padding(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 12),
child: TextField(
controller: _usernameController,
inputFormatters: [LengthLimitingTextInputFormatter(25)],
decoration: InputDecoration(
hintText: 'Username',
labelText: 'Username',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0)),
),
),
),
],
),
Container(
child: Column(
// App Settings
children: [
// SwitchListTile(value: DarkMode, onChanged: Light => Dark => Light)
// ChangeThemeButtonWidget(),
TextButton(
onPressed: _saveSettings,
child: const Text('Save Settings'),
)
],
),
),
],
),
)));
}
void _saveSettings() {
final newSettings = SettingsModal(
username: _usernameController.text,
);
print(newSettings);
print(_usernameController.text);
_preferencesService.saveSettings(newSettings);
}
}
shared_preferences.dart
import 'package:bit/main.dart';
import 'package:bit/saved_data.dart';
import 'package:shared_preferences/shared_preferences.dart';
class PreferencesService {
Future saveSettings(SettingsModal settings) async {
final preferences = await SharedPreferences.getInstance();
await preferences.setString('username', settings.username);
print('Saved Settings');
}
Future<SettingsModal> getSettings() async {
final preferences = await SharedPreferences.getInstance();
final username = preferences.getString('username')!;
return SettingsModal(
username: username,
);
}
}
saved_data.dart
import 'package:shared_preferences/shared_preferences.dart';
import 'package:bit/main.dart';
class SettingsModal {
final String username;
SettingsModal({
required this.username,
});
}
The issue is coming because, you like to use user which is not a constant. While adding const on Stack's children as Constance, which can be happened in this case, remove const and it won't show any errors.
child: Stack(
children: [
Align(
alignment: Alignment.centerLeft,
child: CircleAvatar(
backgroundColor: Colors.white,
radius: 50.0,
)),
Align(
alignment: Alignment.centerRight,
child: Text(
user,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
)),
],
),
To receive data from future(SharedPreference) we need to wait.
You can use FutureBuilder in this case.
We can provide default value instead of using ! and make it static .
static Future<SettingsModal> getSettings() async {
final preferences = await SharedPreferences.getInstance();
final username = preferences.getString('username') ?? "Not found";
return SettingsModal(
username: username,
);
}
Use PreferencesService.getSettings(), to get data.
Align(
alignment: Alignment.centerRight,
child: FutureBuilder<SettingsModal>(
future: PreferencesService.getSettings(),
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.connectionState ==
ConnectionState.done) {
return Text(
snapshot.data!.username,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
);
}
/// better to handle other cases, included on answer
return CircularProgressIndicator();
},
)),
More about FutureBuilder

How to color the suggestions when the user is typing in flutter

I am using typeahead package in flutter to get suggestions to users as they type, what I want is to color the suggestions while the user is typing as its shouwn in the picture Colored suggestions while typing
Here is a simple example that am trying to implement
Main.dart
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'CitiesService.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Colored suggestions Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Colored suggestions Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final myControllerCity = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Form(
key: this._formKey,
child: Padding(
padding: EdgeInsets.all(32.0),
child: Column(
children: <Widget>[
//SizedBox(height: 50,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: TypeAheadFormField(
textFieldConfiguration: TextFieldConfiguration(
controller: myControllerCity,
decoration: InputDecoration(labelText: 'City')),
suggestionsCallback: (pattern) {
return CitiesService.getSuggestionsCities(pattern);
},
itemBuilder: (context, suggestion) {
//
List<String> splitted_names_of_cities = suggestion
.toString()
.toLowerCase()
.split(myControllerCity.text);
final children = <Widget>[];
for (var i = 1;
i < splitted_names_of_cities.length;
i++) {
children.add(new ListTile(
title: Text.rich(
TextSpan(
children: [
TextSpan(
text: myControllerCity.text,
style: TextStyle(color: Colors.red),
),
TextSpan(text: splitted_names_of_cities[i]),
],
),
)));
}
print("this is the list $splitted_names_of_cities");
return new ListView(
children: children,
);
},
transitionBuilder: (context, suggestionsBox, controller) {
return suggestionsBox;
},
onSuggestionSelected: (suggestion) {
myControllerCity.text = suggestion;
},
),
),
],
),
],
),
),
)),
);
}
}
And here is the function of the suggestions
static List<String> getSuggestionsCities(String query) {
List<String> wilayas = [];
algeria_cites.forEach((element) => wilayas.contains(element['wilaya_name_ascii']) ?
null : wilayas.add(element['wilaya_name_ascii']) );
wilayas.retainWhere((s) => s.toLowerCase().contains(query.toLowerCase()));
return wilayas;
}
In the previous code, for each item of the suggested cities name I was creating a full ListTile but I had to create TextSpan instead of that.
But each item has its specific length, for that reason I used List<InlineSpan>.
So here is the itemBuilder after fixing the error.
itemBuilder: (context, suggestion) {
List<InlineSpan> temp = [];
String suggestion_in_lower_case = suggestion.toString().toLowerCase();
List<String> splitted_names_of_cities = suggestion_in_lower_case.split(myControllerCity.text.toLowerCase());
for (var i = 0; i < splitted_names_of_cities.length-1; i++) {
if(splitted_names_of_cities.contains(myControllerCity.text.toLowerCase()));{
temp.add(
TextSpan(
text: splitted_names_of_cities[i],
style: TextStyle(
height: 1.0,
color: Colors.black,
),
),
);
temp.add(
TextSpan(
text: myControllerCity.text.toLowerCase(),
style: TextStyle(
color: Colors.red,
),
),
);
}
}
temp.add(
TextSpan(
text: splitted_names_of_cities.last,
style: TextStyle(
color: Colors.black,
),
),
);
return ListTile(
title: Text.rich(
TextSpan(
children: temp,
),
)
);
},
So it is working as expected, here is the demo.
https://i.stack.imgur.com/Tfs95.gif

Flutter Searchdelegate, i want to add background color and appbar color when i click the search

i can change my background color and app bar in home just fine, but when i click the search icon which uses search delegate it all back to white, how do i change the color? just to make it clear, so before the user clicked the search icon the background and app bar was black but when they clicked it it turned to white, how do i change it?
here is the search code :
import 'package:flutter/material.dart';
import 'package:movie_app_3/model/movie_response.dart';
import 'package:movie_app_3/screens/movie_detail_screen/movie_detail_screen.dart';
import '../model/movie.dart';
import '../repository/repository.dart';
class DataSearch extends SearchDelegate {
// void initState() {
// searchBloc..getSearch(query);
// }
final movieRepo = MovieRepository();
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () => query = '',
)
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow, progress: transitionAnimation),
onPressed: () => close(context, null),
);
}
#override
Widget buildResults(BuildContext context) {
return Container();
}
#override
Widget buildSuggestions(BuildContext context) {
if (query.isEmpty) return Container();
return FutureBuilder<MovieResponse>(
future: movieRepo.getSearch(query),
builder: (BuildContext context, AsyncSnapshot<MovieResponse> snapshot) {
if (snapshot.hasData) {
if (snapshot.data.error != null && snapshot.data.error.length > 0) {
return _buildErrorWidget(snapshot.data.error);
}
return _buildHomeWidget(snapshot.data);
} else if (snapshot.hasError) {
return _buildErrorWidget(snapshot.error);
} else {
return _buildLoadingWidget();
}
},
);
}
Widget _buildHomeWidget(MovieResponse data) {
List<Movie> movies = data.movies;
return ListView.builder(
itemCount: movies.length,
itemBuilder: (context, index) {
return ListTile(
leading: FadeInImage(
image: movies[index].poster == null
? AssetImage('assets/images/no-image.jpg')
: NetworkImage("https://image.tmdb.org/t/p/w200/" +
movies[index].poster),
placeholder: AssetImage('assets/images/no-image.jpg'),
width: 50.0,
fit: BoxFit.contain),
title: Text(
movies[index].title,
style: TextStyle(fontFamily: 'Poppins'),
),
subtitle: Text(
movies[index].overview,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontFamily: 'Raleway'),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MovieDetailScreen(movie: movies[index]),
),
);
},
);
},
);
}
Widget _buildLoadingWidget() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: 25.0,
width: 25.0,
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(Colors.black),
strokeWidth: 4.0,
),
)
],
));
}
Widget _buildErrorWidget(String error) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Error occured: $error"),
],
));
}
// #override
// Widget buildSuggestions(BuildContext context) {
// final suggestedList = (query.isEmpty) ?
// recentMovies :
// movies.where((movie) => movie.toLowerCase().contains(query.toLowerCase())).toList();
// return ListView.builder(
// itemCount: suggestedList.length,
// itemBuilder: (context, i) {
// return ListTile(
// leading: Icon(Icons.movie),
// title: Text(suggestedList[i]),
// onTap: () {},
// );
// },
// );
// }
}
here is the home code :
import 'package:flutter/material.dart';
import 'package:movie_app_3/widget/drawer.dart';
import 'package:movie_app_3/screens/home_screen/widget/home_screen1.dart';
import 'package:movie_app_3/screens/home_screen/widget/home_screen2.dart';
import 'package:movie_app_3/widget/search.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen>
with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 2);
}
#override
void dispose() {
_tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.black,
Color(0xff112339),
Colors.black,
],
),
),
child: DefaultTabController(
length: 2,
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
elevation: 0,
title: Text(
'Moviez',
style: TextStyle(
fontSize: 24,
color: Colors.white,
fontFamily: 'Poppins',
),
),
backgroundColor: Colors.transparent,
centerTitle: true,
actions: [
Padding(
padding: EdgeInsets.only(right: 20),
child: IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch());
},
),
),
],
bottom: TabBar(
controller: _tabController,
indicatorColor: Colors.white,
indicatorSize: TabBarIndicatorSize.tab,
indicatorWeight: 2.0,
tabs: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
'Discover',
style: TextStyle(fontSize: 16, fontFamily: 'Raleway'),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
'Genres',
style: TextStyle(fontSize: 16, fontFamily: 'Raleway'),
),
),
],
),
),
drawer: MyDrawer(),
body: TabBarView(
controller: _tabController,
children: <Widget>[
FirstTab(),
SecondTab(),
],
),
),
),
);
}
}
For customizing the Search Delegate, you have to override a method called appBarTheme and then set your custom theme on that.
** NOTE: When you override appBarTheme of SearchDelegate you have to customize evrything related to SearchBar yourself. Just like the code below. **
Do this to change the AppBar Color:
#override
ThemeData appBarTheme(BuildContext context) {
return ThemeData(
appBarTheme: const AppBarTheme(
color: MyColors.mainColor, // affects AppBar's background color
hintColor: Colors.grey, // affects the initial 'Search' text
textTheme: const TextTheme(
headline6: TextStyle( // headline 6 affects the query text
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.bold)),
),
);
}
And for changing the background color of suggestions:
#override
Widget buildSuggestions(BuildContext context) {
return Container(
color: Colors.black,
...
);
}
Similarly do this for results:
#override
Widget buildResults(BuildContext context) {
return Container(
color: Colors.black,
...
);
}
Hope this helps.
Add this to your "DataSearch" class
class _SearchDelegate extends SearchDelegate {
#override
ThemeData appBarTheme(BuildContext context) {
return Theme.of(context).copyWith(
scaffoldBackgroundColor: Colors.green,
);
}
If you already set your MaterialApp theme you can simply use Theme.of(context).copywith to remain body theme. Then you can override appBarTheme to change desired color/styles.
#override
ThemeData appBarTheme(BuildContext context) {
return Theme.of(context).copyWith(
//scaffoldBackgroundColor: , to change scaffold color
appBarTheme: const AppBarTheme( //to change appbar
color: Colors.black,
//titleTextStyle: , to change title text
//toolbarTextStyle: , to change toolbar text style
),
);

Flutter StatefulWidget parameter unable to pass

I know there was a really similar case and got solved, I modified my code to 99% liked to that but somehow my list is undefined.
The list that is undefined is at the line where ' ...(list as List).map((answer) { '.
import 'package:flutter/material.dart';
import 'package:kzstats/common/AppBar.dart';
import 'package:kzstats/common/Drawer.dart';
import '../toggleButton.dart';
class Settings extends StatelessWidget {
final String currentPage = 'Settings';
static const _modes = [
{
'mode': ['KZTimer', 'SimpleKZ', 'Vanilla']
},
{
'tickrate': [128, 102, 64]
},
];
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: HomepageAppBar(currentPage),
drawer: HomepageDrawer(),
body: Padding(
padding: EdgeInsets.all(8),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildHeader(
title: 'Mode',
child: ToggleButton(_modes[0]['mode']),
),
SizedBox(height: 32),
buildHeader(
title: 'Tick rate',
child: ToggleButton(_modes[1]['tickrate']),
),
],
),
),
),
),
);
}
}
Widget buildHeader({#required String title, #required Widget child}) => Column(
children: [
Text(
title,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
child,
],
);
class ToggleButton extends StatefulWidget {
final List<String> list;
ToggleButton(this.list);
#override
State createState() => new _ToggleButtonState();
}
class _ToggleButtonState extends State<ToggleButton> {
List<bool> _selections = [true, false, false];
#override
Widget build(BuildContext context) {
return new Container(
color: Colors.blue.shade200,
child: ToggleButtons(
isSelected: _selections,
fillColor: Colors.lightBlue,
color: Colors.black,
selectedColor: Colors.white,
renderBorder: false,
children: <Widget>[
...(list as List<String>).map((answer) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 12),
child: Text(
answer,
style: TextStyle(fontSize: 18),
),
);
}).toList(),
],
onPressed: (int index) {
setState(() {
for (int i = 0; i < _selections.length; i++) {
if (index == i) {
_selections[i] = true;
} else {
_selections[i] = false;
}
}
});
},
),
);
}
}
In case someone needs the full code, it's available at https://github.com/davidp918/KZStats
I'm new to Flutter and stackoverflow so if anything please just comment, thanks!
We can access a variable of StatefulWidget from the state class using "widget" (for example: widget.list)
Please refer below code sample for the reference.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Settings());
}
}
class Settings extends StatelessWidget {
final String currentPage = 'Settings';
static const modes = [
{
'mode': ['KZTimer', 'SimpleKZ', 'Vanilla']
},
{
'tickrate': [128, 102, 64]
},
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Container(
child: Padding(
padding: EdgeInsets.all(8),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildHeader(
title: 'Mode',
child: ToggleButton(modes[0]['mode']),
),
SizedBox(height: 32),
buildHeader(
title: 'Tick rate',
child: ToggleButton(modes[1]['tickrate']),
),
SizedBox(height: 32),
buildHeader(
title: 'Mode',
child: ToggleButton(modes[0]['mode']),
),
],
),
),
),
),
),
);
}
}
Widget buildHeader({#required String title, #required Widget child}) {
return Column(
children: [
Text(
title,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
SizedBox(height: 16),
child,
],
);
}
class ToggleButton extends StatefulWidget {
final List list;
ToggleButton(this.list);
#override
State createState() => new _ToggleButtonState();
}
class _ToggleButtonState extends State<ToggleButton> {
List<bool> _selections = [false, false, false];
#override
Widget build(BuildContext context) {
return Container(
color: Colors.blue.shade200,
child: ToggleButtons(
isSelected: _selections,
fillColor: Colors.lightBlue,
color: Colors.black,
selectedColor: Colors.white,
renderBorder: false,
children: [
...(widget.list as List)?.map((answer) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 12),
child: Text(
answer.toString() ?? '',
style: TextStyle(fontSize: 18),
),
);
})?.toList(),
],
onPressed: (int index) {
setState(() {
for (int i = 0; i < _selections.length; i++) {
if (index == i) {
_selections[i] = true;
} else {
_selections[i] = false;
}
}
});
},
),
);
}
}

Flutter Onboarding - How to Swipe Two Images at The Same Time?

I want to swipe right background images with an end image located at the end of the bottom of the screen with floating action button and want to swipe right a list of images with background images like other onboarding screens works. Here I needed 3 screens, the Last screen will be a login page. I used the Transformer Page View package for this. Currently, I used an image in the floating action button, but it's not working. How I can do this?
import 'package:flutter/material.dart';
import 'package:onlycentertainment/pages/splashscreen.dart';
import 'package:transformer_page_view/transformer_page_view.dart';
class TestPage1 extends StatefulWidget {
final String title;
TestPage1({this.title});
#override
TestPage1State createState() {
return new TestPage1State();
}
}
class TestPage1State extends State<TestPage1> {
int _slideIndex = 0;
int _bottomIndex = 0;
final List<String> images = [
"assets/images/welcome01.jpg",
"assets/images/welcome02.jpg",
"assets/images/welcome01.jpg",
];
final List<String> text0 = [
"Welcome in your app",
"Enjoy teaching...",
"Showcase your skills",
"Friendship is great"
];
final List<String> text1 = [
"App for food lovers, satisfy your taste",
"Find best meals in your area, simply",
"Have fun while eating your relatives and more",
"Meet new friends from all over the world"
];
final IndexController controller = IndexController();
#override
Widget build(BuildContext context) {
TransformerPageView transformerPageView = TransformerPageView(
pageSnapping: true,
onPageChanged: (index) {
setState(() {
this._slideIndex = index;
this._bottomIndex = index;
});
},
loop: false,
controller: controller,
transformer: new PageTransformerBuilder(
builder: (Widget child, TransformInfo info) {
return SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: new Material(
child: new Container(
alignment: Alignment.center,
color: Colors.white,
child: Column(
children: <Widget>[
new ParallaxContainer(
child: new Image.asset(
images[info.index],
fit: BoxFit.cover,
),
position: info.position,
translationFactor: 400.0,
),
SizedBox(
height: 45.0,
),
new ParallaxContainer(
child: new Text(
text1[info.index],
textAlign: TextAlign.center,
style: new TextStyle(
color: Colors.white,
fontSize: 28.0,
fontFamily: 'Quicksand',
fontWeight: FontWeight.bold),
),
position: info.position,
translationFactor: 300.0,
),
],
),
),
),
);
}),
itemCount: 3);
return Scaffold(
backgroundColor: Color(0xff243951),
body: transformerPageView,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
height: 70,
width: MediaQuery.of(context).size.width,
child: IconButton(icon: Image.asset('assets/images/asset1.png'), onPressed: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>SplashScreen()));
}),
),
);
}
}
I am not sure I understand correctly but, the problem of your code is "SplashScreen()" part, it can't be empty, I made a working sample, check out and let me know if I misunderstand the thing you wanted to do.
import 'package:flutter/material.dart';
import 'package:splashscreen/splashscreen.dart';
import 'package:transformer_page_view/transformer_page_view.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new TestPage1(title: 'Flutter Demo Home Page'),
);
}
}
class TestPage1 extends StatefulWidget {
final String title;
TestPage1({this.title});
#override
TestPage1State createState() {
return new TestPage1State();
}
}
class TestPage1State extends State<TestPage1> {
int _slideIndex = 0;
int _bottomIndex = 0;
final List<String> images = [
"assets/images/welcome01.jpg",
"assets/images/welcome02.jpg",
"assets/images/welcome01.jpg",
];
final List<String> text0 = [
"Welcome in your app",
"Enjoy teaching...",
"Showcase your skills",
"Friendship is great"
];
final List<String> text1 = [
"App for food lovers, satisfy your taste",
"Find best meals in your area, simply",
"Have fun while eating your relatives and more",
"Meet new friends from all over the world"
];
final IndexController controller = IndexController();
#override
Widget build(BuildContext context) {
TransformerPageView transformerPageView = TransformerPageView(
pageSnapping: true,
onPageChanged: (index) {
setState(() {
this._slideIndex = index;
this._bottomIndex = index;
});
},
loop: false,
controller: controller,
transformer: new PageTransformerBuilder(
builder: (Widget child, TransformInfo info) {
return SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: new Material(
child: new Container(
alignment: Alignment.center,
color: Colors.white,
child: Column(
children: <Widget>[
new ParallaxContainer(
child: new Image.asset(
images[info.index],
fit: BoxFit.cover,
),
position: info.position,
translationFactor: 400.0,
),
SizedBox(
height: 45.0,
),
new ParallaxContainer(
child: new Text(
text1[info.index],
textAlign: TextAlign.center,
style: new TextStyle(
color: Colors.white,
fontSize: 28.0,
fontFamily: 'Quicksand',
fontWeight: FontWeight.bold),
),
position: info.position,
translationFactor: 300.0,
),
],
),
),
),
);
}),
itemCount: 3);
return Scaffold(
backgroundColor: Color(0xff243951),
body: transformerPageView,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
height: 70,
width: MediaQuery.of(context).size.width,
child: IconButton(icon: Image.asset(images[_bottomIndex]), onPressed: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>SplashScreen(
seconds: 4,
navigateAfterSeconds: new AfterSplash(),
title: new Text('Welcome In SplashScreen',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0
),
)
)
)
);
}
),
),
);
}
}
class AfterSplash extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Welcome In SplashScreen Package"),
automaticallyImplyLeading: false,
),
body: new Center(
child: new Text("Succeeded!",
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30.0
),
),
),
);
}
}