Theming flutter apps - flutter

today I tried theming my app... I looked through a few packages and ended up using the stacked_themes package. Now I tried to implement the code as shown in the documentation but Im not sure how I have to implement the dialog
theme model file:
import 'package:google_fonts/google_fonts.dart';
import 'package:stacked_themes/stacked_themes.dart';
import 'package:flutter/material.dart';
class MultiThemeModel {
int index;
String themeName;
MultiThemeModel({required this.index, required this.themeName});
}
titlesForThemeModel(int index) {
switch (index) {
case 0:
return 'Luxury Purple';
case 1:
return 'Red Fine Wine';
}
return 'No theme for index';
}
List<MultiThemeModel> get themes => List<MultiThemeModel>.generate(
2,
(index) =>
MultiThemeModel(index: index, themeName: titlesForThemeModel(index)));
List<Widget> get widgets => themes
.map((themeData) => MultipleThemeViewerWidget(themeData: themeData))
.toList();
class MultipleThemeViewerWidget extends StatelessWidget {
MultipleThemeViewerWidget({Key? key, required this.themeData})
: super(key: key);
final MultiThemeModel themeData;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
right: 40,
),
child: GestureDetector(
onTap: () {
getThemeManager(context).selectThemeAtIndex(themeData.index);
},
child: Container(
height: 60,
width: 105,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).scaffoldBackgroundColor.withOpacity(.3),
border: Border.all(
color: Theme.of(context).scaffoldBackgroundColor, width: 3)),
child: Center(
child: Text(
themeData.themeName,
style: GoogleFonts.poppins(
textStyle: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context).scaffoldBackgroundColor,
),
),
),
),
),
),
);
}
}
List of themes:
List<ThemeData> getThemes() {
return [
ThemeData(
brightness: Brightness.light,
primaryColor: purpleDesign[100],
scaffoldBackgroundColor: purpleDesign[400],
indicatorColor: purpleDesign[50],
primaryColorLight: purpleDesign[300],
hintColor: purpleDesign[400]),
ThemeData(
brightness: Brightness.light,
primaryColor: redDesign[100],
scaffoldBackgroundColor: redDesign[400],
indicatorColor: redDesign[50],
primaryColorLight: redDesign[300],
hintColor: redDesign[400])
];
}
dialog:
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
elevation: 1,
backgroundColor: Theme.of(context).indicatorColor,
insetAnimationCurve: Curves.decelerate,
child: Container(
height: 170,
child: Padding(
padding: const EdgeInsets.only(
left: 33,
top: 85,
),
child: Column(
children: [
Row(children: [
for(var theme in themes)
MultipleThemeViewerWidget(themeData: ),],),
],
),
),
),
);
my problem - I don't know what to pass to the themeData: in the forloop from the dialog... it would be really nice if somebody could help with this
thanks in advance:)

Related

Null check operator used on a null value error in flutter Dashboard page

I got this error when I am running the app. I could not figure out why this error occurred.
So I am switching a project to flutter null safety but i am getting Null check operator used on a null value error i tried looking into other similar issues tried but its not working for me the complete error is as following
Stack Trace
The following _CastError was thrown building DashboardPage(dirty,
dependencies: [_InheritedTheme,
_InheritedProviderScope<DocumentSnapshot?>, _LocalizationsScope-[GlobalKey#556e8]], state:
_DashboardPageState#0b8da): Null check operator used on a null value
The relevant error-causing widget was: DashboardPage
My main.app
void main() => runApp(ElectricalIssueTrackerApp());
class ElectricalIssueTrackerApp extends StatelessWidget {
static const appName = 'Electrical Issue Tracker';
static const appIcon = AssetImage('assets/icons/192.png');
static const appLegalese = 'GNU General Public License v3.0';
// Move to Misc
static const appIssueTracker =
'';
// Move to Misc
static const appIssueTrackerMailing = '';
static const appRepository =
'';
const ElectricalIssueTrackerApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: appName,
theme: _theme,
home: FutureBuilder<FirebaseApp>(
future: Firebase.initializeApp(),
builder: (context, snapshot) {
// Loading screen, when initializing firebase app.
if (!snapshot.hasData) {
return Loading();
}
return Authenticated(
child: Verified(
child: DashboardPage(),
),
);
},
),
);
}
static const _primary = Color.fromARGB(255, 0, 38, 70);
static const _accent = Color.fromARGB(255, 245, 248, 253);
static const _secondary = Color(0xFF924642);
static const _vistaWhite = Color(0xFFFEF9F7);
static const _fontFamily = 'Ubuntu';
static get _theme {
return ThemeData(
visualDensity: VisualDensity.standard,
fontFamily: _fontFamily,
brightness: Brightness.light,
primaryColor: _primary,
colorScheme: ColorScheme.light(
primary: _primary,
onPrimary: _accent,
secondary: _secondary,
onSecondary: _vistaWhite,
surface: _accent,
onSurface: _primary,
background: _accent,
onBackground: _primary,
),
disabledColor: Color(0x99002646),
scaffoldBackgroundColor: _accent,
cardColor: Colors.white,
appBarTheme: AppBarTheme(
color: _accent,
iconTheme: IconThemeData(
color: _primary,
),
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
),
elevation: 0,
actionsIconTheme: const IconThemeData(
color: _primary,
),
titleTextStyle: TextStyle(
fontFamily: _fontFamily,
fontSize: 20,
fontWeight: FontWeight.bold,
letterSpacing: 0.5,
color: _primary,
),
),
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20),
),
),
elevation: 8,
),
iconTheme: const IconThemeData(
color: _primary,
),
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: _primary,
foregroundColor: _accent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
backgroundColor: _primary,
primary: _accent,
onSurface: _accent,
),
),
dialogTheme: DialogTheme(
backgroundColor: _accent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
snackBarTheme: const SnackBarThemeData(
backgroundColor: _primary,
contentTextStyle: TextStyle(
fontFamily: _fontFamily,
color: _accent,
letterSpacing: 0.5,
),
),
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: _accent,
enabledBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide.none,
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: _primary),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.red),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.red),
),
labelStyle: const TextStyle(color: _primary, fontSize: 14),
focusColor: _primary,
),
);
}
}
My Dashboard.app
class DashboardPage extends StatefulWidget {
const DashboardPage({Key? key}) : super(key: key);
#override
_DashboardPageState createState() => _DashboardPageState();
static _DashboardPageState of(BuildContext context) =>
context.findAncestorStateOfType<_DashboardPageState>()!;
}
class _DashboardPageState extends State<DashboardPage> {
bool _raiseNewIssueFormIsShown = false;
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final misc = Provider.of<MiscSnapshot>(context).misc;
final userSnapshot = Provider.of<UserSnapshot>(context);
final user = userSnapshot.user;
NetworkImage? userPhoto;
final photoUrl = Provider.of<User>(context).photoURL;
if (photoUrl != null) {
userPhoto = NetworkImage(photoUrl);
}
return Scaffold(
appBar: AppBar(
title: FadeInLeft(
preferences: const AnimationPreferences(
duration: Duration(milliseconds: 400),
),
child: Text(
_raiseNewIssueFormIsShown
? 'Raise an issue'
: ElectricalIssueTrackerApp.appName,
),
),
actions: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => showDialog(
context: context,
builder: (_) => MiscellaneousDialog(userSnapshot),
),
child: Padding(
padding: const EdgeInsets.all(10),
child: PhysicalModel(
color: Colors.transparent,
elevation: 3,
shape: BoxShape.circle,
child: CircleAvatar(
backgroundColor: theme.primaryColor,
child: Text(
('${user.name}${user.email}-'[0]).toUpperCase(),
style: TextStyle(
color: theme.colorScheme.onPrimary,
),
),
foregroundImage: userPhoto,
),
),
),
),
],
),
body: CupertinoScrollbar(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.all(8),
child: Wrap(
spacing: 10,
runSpacing: 30,
children: [
// The analytics widget
ActiveAndResolvedIssueCounters(misc: misc),
// View all active issues if user has permission
if (user.scope.canViewActiveIssues) ActiveIssuesSection(),
if (user.scope.canViewResolvedIssues)
buildResolvedIssuesButton(misc, userSnapshot),
// Raise an issue section
if (user.scope.canCreateIssue) RaiseAnIssueSection(),
// All issues raised by the user.
MyIssuesSection(),
// Footer
SizedBox(height: 30),
],
),
),
),
);
}
Future<void> showRaiseNewIssueForm(BuildContext context) async {
setState(() => _raiseNewIssueFormIsShown = true);
await Scaffold.of(context)
.showBottomSheet((_) => RaiseNewIssueBottomSheet())
.closed;
setState(() => _raiseNewIssueFormIsShown = false);
}
Widget buildResolvedIssuesButton(Misc misc, UserSnapshot userSnapshot) {
return Center(
child: OutlinedButton(
child: Text('View already resolved issues'),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return MultiProvider(
providers: [
Provider.value(value: userSnapshot),
Provider.value(value: misc),
],
child: ResolvedIssuesPage(),
);
},
),
),
),
);
}
}
raise_issue_section.dart
class RaiseAnIssueSection extends StatelessWidget {
const RaiseAnIssueSection({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Container(
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: theme.cardColor,
borderRadius: BorderRadius.circular(16),
// color: theme.colorScheme.surface,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Having an electrical issue in campus?',
style: TextStyle(
color: theme.primaryColor,
),
),
SizedBox(height: 18),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FloatingActionButton.extended(
onPressed: () =>
DashboardPage.of(context).showRaiseNewIssueForm(context),
label: Text('Raise new issue'),
icon: Icon(FontAwesomeIcons.feather),
),
],
),
],
),
);
}
}
misc.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'misc.freezed.dart';
typedef MiscSnapshot = DocumentSnapshot<Misc>;
#freezed
class Misc with _$Misc {
const Misc._();
const factory Misc._create({
required List<String> locationBlocks,
required int activeIssuesCount,
required int resolvedIssuesCount,
}) = _Misc;
static const _LocationBlocksKey = 'location-blocks';
static const _ActiveIssuesCountKey = 'active-issues-count';
static const _ResolvedIssuesCountKey = 'resolved-issues-count';
static final _ref =
FirebaseFirestore.instance.collection('misc').withConverter<Misc>(
fromFirestore: (snapshot, options) {
final data = snapshot.data()!;
return Misc._create(
locationBlocks: data[_LocationBlocksKey].cast<String>(),
activeIssuesCount: data[_ActiveIssuesCountKey],
resolvedIssuesCount: data[_ResolvedIssuesCountKey]);
},
toFirestore: (value, options) {
return {
_LocationBlocksKey: value.locationBlocks,
};
},
).doc('default');
static get ref => _ref;
static Stream<MiscSnapshot> get watch => _ref.snapshots();
static Future<MiscSnapshot> get read => _ref.get();
static Future<void> informIssueCreated() async {
await _ref.update({
_ActiveIssuesCountKey: FieldValue.increment(1),
});
}
static Future<void> informIssueResolved() async {
await _ref.update({
_ActiveIssuesCountKey: FieldValue.increment(-1),
_ResolvedIssuesCountKey: FieldValue.increment(1),
});
}
static Future<void> informActiveIssuePurged() async {
await _ref.update({
_ActiveIssuesCountKey: FieldValue.increment(-1),
});
}
static Future<void> updateActiveIssuesCount(int value) async {
assert(value >= 0, 'bad argument: cannot write negative value');
if (value < 0) {
return;
}
await _ref.update({_ActiveIssuesCountKey: value});
}
}
extension MiscSnapshotExtension on MiscSnapshot {
Misc get misc => this.data()!;
}
You'll mostly get the "Null check operator used on a null value"-error when ever you explicitly say something is not null using the bang operator ! on something that actually is.
Looking at your code sample that could be in the following lines:
static _DashboardPageState of(BuildContext context) =>
context.findAncestorStateOfType<_DashboardPageState>()!
I assume DashboardPage.of(context) is called somewhere, when it actually doesn't have a DashboardPage parent for that context instance. However, I cannot find it in the sample. Is it missing from it?

Flutter: Place widget on top of the other with negative positioning

I am trying to implement this modalBottomSheet
and I thought to use Stack with negative positioning
showModalBottomSheet(
context: context,
builder: (context) {
return Stack(
alignment: AlignmentDirectional.bottomStart,
children: [
Container(
width: double.infinity,
height: 200,
color: Colors.white,
child: Column(//here there will be the text)
),
Positioned(
top: -20,
left: 0,
right: 0,
child: CircleAvatar(
backgroundColor: Palette.white,
radius: 38,
child: CircleAvatar(
backgroundImage: NetworkImage(snapshot.data.image),
radius: 34,
backgroundColor: Palette.white),
),
)]);
However this cuts the top part of the CircleAvatar picture (as I kind of expected).
Any idea on how to implement this?
you need to change the clipBehavior to Clip.none on the Stack
Stack(
clipBehavior: Clip.none,
...)
Here is my tricky implementation.
Set bottom sheet's background color to transparent.
Add top margin as avatar's half height to base Container.
Set base container's background color to white
Change the avatar's top position value to 0
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () {
show();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
void show() {
showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
builder: (context) {
return Stack(
alignment: AlignmentDirectional.bottomStart,
children: [
Container(
width: double.infinity,
height: 200,
margin: EdgeInsets.only(top: 35),
color: Colors.transparent,
child: Container(
padding: EdgeInsets.only(top: 60),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'Alessandro Liparoti',
style: TextStyle(
color: Colors.black,
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 25),
Text(
'4 games palyed',
style: TextStyle(
color: Colors.grey,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
Positioned(
top: 0,
left: 0,
right: 0,
child: CircleAvatar(
backgroundColor: Colors.white,
radius: 38,
child: CircleAvatar(
backgroundImage: NetworkImage(
'https://image.flaticon.com/icons/png/512/147/147144.png'),
radius: 34,
backgroundColor: Colors.white),
),
),
],
);
});
}
}

flutter app on restart not showing home page after hot reload it works

I'm beginner at flutter app development.i'm trying to fetch more then ten pages from api with for loop and addall results in list.for that i created future function and statefulwidget
here my code is
import 'dart:convert';
import 'package:MovieAPi/infopage.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
List data = [];
Future<void> _getMovies() async {
for (var i = 1; i < 10; i++) {
var url =
"https://api.themoviedb.org/3/trending/movie/week?api_key=1dce78a9836cf6fbc01190431d9443fe&page=$i";
http.Response response = await http.get(url);
var JsonBody = json.decode(response.body);
data.addAll(JsonBody['results']);
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: TextTheme(
title: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),
subtitle: TextStyle(fontSize: 18, fontWeight: FontWeight.w700),
),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MovieTile(),
);
}
}
class MovieTile extends StatefulWidget {
#override
_MovieTileState createState() => _MovieTileState();
}
class _MovieTileState extends State<MovieTile> {
void initState() {
super.initState();
setState(() {
_getMovies();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Movies", style: Theme.of(context).textTheme.title),
backgroundColor: Colors.white,
bottomOpacity: 0.0,
shadowColor: Colors.white,
automaticallyImplyLeading: false,
),
body: ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
String image = data[index]['poster_path'];
String title = data[index]['title'];
String release_date = data[index]['overview'];
String id = data[index]['id'].toString();
String vote = data[index]['vote_average'].toString();
return GestureDetector(
onTap: () {
return Navigator.push(context,
MaterialPageRoute(builder: (context) => InfoMovie(id)));
},
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 8.0, horizontal: 10),
child: Container(
width: MediaQuery.of(context).size.width,
height: 500.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: CachedNetworkImageProvider(
"https://image.tmdb.org/t/p/original$image",
),
fit: BoxFit.cover,
),
boxShadow: [
BoxShadow(
offset: Offset(1, 9),
blurRadius: 10,
color: Colors.black26,
)
],
),
child: Stack(
children: [
Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(20),
),
),
Positioned(
bottom: 0,
child: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.5),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20),
),
),
padding: EdgeInsets.all(20),
width: MediaQuery.of(context).size.width * 0.95,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context)
.textTheme
.title
.copyWith(color: Colors.white),
),
SizedBox(height: 5),
Text(
release_date,
style: Theme.of(context)
.textTheme
.subtitle
.copyWith(
color: Colors.white.withOpacity(0.9)),
textAlign: TextAlign.left,
maxLines: 3,
overflow: TextOverflow.ellipsis,
softWrap: true,
),
],
),
),
),
Positioned(
top: 20,
left: 10,
child: Container(
height: 50,
width: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.white.withOpacity(0.6),
width: 1)),
child: Center(
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
child: Center(
child: Text(
vote,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
),
),
),
),
],
),
),
),
);
},
));
}
}
frist when i open app showing nothing
like this
only blank screen
and when i hot reload then showing results
here
First, setState is not necessary in initState. Secondly, since ListView.builder is the root element of your page body, you cannot directly see the data content because it's empty data = [] at app startup.
To solve this, better you try something like this
return Scaffold(
body: data.length > 0 ? ListView.builder(
// ...
) : Center(
child: CircularProgressIndicator(),
),
)
Also, it's better you put your List data variable and _getMovies function in _MovieTileState like this
class _MovieTileState extends State<MovieTile> {
List data;
void initState() {
super.initState();
data = [];
_getMovies();
}
Future<void> _getMovies() async {
for (var i = 1; i < 10; i++) {
var url = "https://api.themoviedb.org/3/trending/movie/week?api_key=1dce78a9836cf6fbc01190431d9443fe&page=$i";
http.Response response = await http.get(url);
var JsonBody = json.decode(response.body);
setState(() {
data.addAll(JsonBody['results']);
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// ...
),
body: data.length > 0 ? ListView.builder(
// ...
) : Center(
child: CircularProgressIndicator(),
),
);
}
}

How to make this custom RangeSlider in Flutter?

I want to make a custom Range slider that looks like this:
However, I tried but my RangeSlider looks like:
My code:
data: SliderTheme.of(context).copyWith(
trackShape: RectangularSliderTrackShape(),
trackHeight: 2.0,
thumbShape:
RoundSliderThumbShape(enabledThumbRadius: 9.0),
overlayShape:
RoundSliderOverlayShape(overlayRadius: 18.0),
valueIndicatorShape: RoundSliderOverlayShape(),
valueIndicatorColor: Color(0xffF5F5F5),
valueIndicatorTextStyle:
TextStyle(color: Color(0xff7E3338), fontSize: 14.0),
rangeThumbShape: RoundRangeSliderThumbShape(),
rangeValueIndicatorShape:
PaddleRangeSliderValueIndicatorShape(),
),
child: RangeSlider(
values: selectedRange,
min: 0.0,
max: 50000.0,
semanticFormatterCallback: (RangeValues rangeValues) {
return '${rangeValues.start.round()} - ${rangeValues.end.round()} dollars';
},
//added talk back feature for android
labels: RangeLabels(
'${selectedRange.start}', '${selectedRange.end}'),
activeColor: Color(0xff7E3338),
inactiveColor: Color(0xffD7D8DD),
onChanged: (RangeValues newRange) {
setState(() => selectedRange = newRange);
},
),
),
What can I do different in the code that will give me the expected output?
Please check this plugin where you can customize the slider as you want i have created the sample from the above-mentioned image.
But you can customize it as per your needs.
Plugin :https://pub.dev/packages/flutter_xlider
Check the code below :
import 'package:flutter/material.dart';
import 'package:flutter_xlider/flutter_xlider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
//
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double _lowerValue = 50;
double _upperValue = 180;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 50, left: 20, right: 20),
alignment: Alignment.centerLeft,
child: FlutterSlider(
values: [1000, 15000],
rangeSlider: true,
//rtl: true,
ignoreSteps: [
FlutterSliderIgnoreSteps(from: 8000, to: 12000),
FlutterSliderIgnoreSteps(from: 18000, to: 22000),
],
max: 25000,
min: 0,
step: FlutterSliderStep(step: 100),
jump: true,
trackBar: FlutterSliderTrackBar(
activeTrackBarHeight: 2,
activeTrackBar: BoxDecoration(color: Colors.brown),
),
tooltip: FlutterSliderTooltip(
textStyle: TextStyle(fontSize: 17, color: Colors.lightBlue),
),
handler: FlutterSliderHandler(
decoration: BoxDecoration(),
child: Container(
decoration: BoxDecoration(
color: Colors.brown,
borderRadius: BorderRadius.circular(25)),
padding: EdgeInsets.all(10),
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25)),
),
),
),
rightHandler: FlutterSliderHandler(
decoration: BoxDecoration(),
child: Container(
decoration: BoxDecoration(
color: Colors.brown,
borderRadius: BorderRadius.circular(25)),
padding: EdgeInsets.all(10),
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25)),
),
),
),
disabled: false,
onDragging: (handlerIndex, lowerValue, upperValue) {
_lowerValue = lowerValue;
_upperValue = upperValue;
setState(() {});
},
)),
],
),
),
);
}
}
This is the image output
you can change the colors accordingly.
Let me know if it works.
Check out this code for tooltip:
tooltip: FlutterSliderTooltip(
disableAnimation: true,
alwaysShowTooltip: true,
textStyle: TextStyle(fontSize: 17, color: Colors.lightBlue),
),
Wrap your Range Slider in Slider theme and customize your slider data theme according to your need. use the bellow image for reference and name of all the properties of slider.

Flutter adding Space between AppBar and body

Following Problem, I'd like to have Space between the AppBar and the MealFormField.
I tried to Wrap the MealFormField into a Container or Column and then Add some Space, but this is not working.
I Added a Picture of the Screen and draw where the Space between the AppBar and the MealFormField should be added.
Code
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:intl/intl.dart';
import 'package:mealapp/bloc/auth/auth_bloc.dart';
import 'package:mealapp/bloc/form/add_meal_form_bloc.dart';
import 'package:mealapp/components/loading.dart';
import 'package:mealapp/models/global.dart';
import 'package:mealapp/services/repositories/meal_repository.dart';
import 'package:status_alert/status_alert.dart';
class MealFormScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => AddMealFormBloc(
mealRepository: MealRepository(),
authBloc: context.bloc<AuthBloc>(),
),
child: Scaffold(
appBar: AppBar(
title: Text(
'Add Meal',
style: darkTodoTitle.copyWith(fontSize: 24),
),
centerTitle: true,
iconTheme: IconThemeData(color: Colors.black),
elevation: 0,
backgroundColor: Colors.white,
brightness: Brightness.light,
),
body: MealFormFields(),
),
);
}
}
class MealFormFields extends StatelessWidget {
#override
Widget build(BuildContext context) {
final formBloc = context.bloc<AddMealFormBloc>();
return FormBlocListener<AddMealFormBloc, String, String>(
onSuccess: (context, _) {
LoadingDialog.hide();
StatusAlert.show(
context,
duration: Duration(seconds: 2),
title: 'Success',
subtitle: 'Successfully added a meal.',
configuration: IconConfiguration(icon: Icons.done),
);
ExtendedNavigator.rootNavigator.pop();
},
onSubmitting: (context, _) {
LoadingDialog.show(context);
},
child: Padding(
padding: const EdgeInsets.all(24.0),
child: ListView(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Add your new meal",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
const SizedBox(height: 24),
TextFieldBlocBuilder(
textFieldBloc: formBloc.mealNameField,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
labelText: 'Enter meal name',
),
),
DateTimeFieldBlocBuilder(
dateTimeFieldBloc: formBloc.mealDateField,
format: DateFormat("dd-MM-yyyy"),
initialDate: DateTime.now(),
firstDate: DateTime.now().add(Duration(days: 0)),
lastDate: DateTime.now().add(Duration(days: 365)),
decoration: InputDecoration(
prefixIcon: Icon(Icons.calendar_today),
),
),
FlatButton(
onPressed: () {
print(formBloc.state.canSubmit);
formBloc.submit();
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Text("Save"),
color: redColor,
textColor: Colors.white,
),
],
),
),
);
}
}
You should wrap your MealFormFields(), with a Padding Widget like so:
class MealFormScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => AddMealFormBloc(
mealRepository: MealRepository(),
authBloc: context.bloc<AuthBloc>(),
),
child: Scaffold(
appBar: AppBar(
title: Text(
'Add Meal',
style: darkTodoTitle.copyWith(fontSize: 24),
),
centerTitle: true,
iconTheme: IconThemeData(color: Colors.black),
elevation: 0,
backgroundColor: Colors.white,
brightness: Brightness.light,
),
body: Padding(
// I set the padding here to only the top, you can increase the double (16.0) to suit exactly what you're looking to achieve visually
padding: EdgeInsets.only(top: 16.0),
child: MealFormFields(),
),
),
);
}
}
Hope it works for you.