I am trying to do customized class using stateful widget and I have to use stateful because it have setState function however I want to add property for the class so, when ever I invoke the class I pass the colors I want or store the data I want I did the same for Rassed Button using stateless widget and it is works but for the statefulI have an error that the variable is undefined
I tried to invoke it using widget.borderColor but i have an error that the widget is not defined
here is the code :
class DoseDropDown extends StatefulWidget {
Color borderColor;
Color hintColor;
DoseDropDown({
this.hintColor,
this.borderColor,
});
#override
_DoseDropDownState createState() => _DoseDropDownState();
}
String medicationDose;
List<DropdownMenuItem> getDropDownItem() {
List<DropdownMenuItem> dropDownItems = [];
for (String dose in medcationDose) {
var newItem = DropdownMenuItem(
child: Text(
dose,
style: TextStyle(
here I am trying to use it :
color: hintColor,
and I have error that it is not defined
fontSize: 23, fontWeight: FontWeight.bold,
),
),
value: dose,
);
dropDownItems.add(newItem);
}
return dropDownItems;
}
List<String> medcationDose = [
'مرة واحدة في اليوم',
'مرتان في اليوم',
'ثلاث مرات في اليوم',
'اربعة مرات في اليوم',
'وقت الحاجة'
];
class _DoseDropDownState extends State<DoseDropDown> {
#override
Widget build(BuildContext context) {
return SizedBox(
height: 70,
width: 350,
child: DropdownButtonFormField(
dropdownColor: white,
value: medicationDose,
items: getDropDownItem(),
iconSize: 50,
iconEnabledColor: yellow,
onChanged: (value) {
setState(() {
medicationDose = value;
});
},
decoration: InputDecoration(
prefixIcon: Icon(
MyFlutterApp.pills__2_,
color: yellow,
size: 30,
),
hintText: 'الجرعة',
hintStyle: TextStyle(
fontSize: 30, fontWeight: FontWeight.bold, color: white),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: borderColor,
),
borderRadius: BorderRadius.circular(30.0),
),
),
),
);
}
}
You can copy paste run full code below
In this case, function getDropDownItem() is global and not in class _DoseDropDownState
You can pass hintColor as a parameter
You can in DropdownButtonFormField use widget.hintColor and pass to getDropDownItem
code snippet
List<DropdownMenuItem> getDropDownItem(Color hintColor) {
...
child: DropdownButtonFormField(
dropdownColor: Colors.white,
value: medicationDose,
items: getDropDownItem(widget.hintColor),
working demo
full code
import 'package:flutter/material.dart';
String medicationDose;
List<DropdownMenuItem> getDropDownItem(Color hintColor) {
List<DropdownMenuItem> dropDownItems = [];
for (String dose in medcationDose) {
var newItem = DropdownMenuItem(
child: Text(
dose,
style: TextStyle(
color: hintColor,
fontSize: 23,
fontWeight: FontWeight.bold,
),
),
value: dose,
);
dropDownItems.add(newItem);
}
return dropDownItems;
}
List<String> medcationDose = [
'مرة واحدة في اليوم',
'مرتان في اليوم',
'ثلاث مرات في اليوم',
'اربعة مرات في اليوم',
'وقت الحاجة'
];
class DoseDropDown extends StatefulWidget {
Color borderColor;
Color hintColor;
DoseDropDown({
this.hintColor,
this.borderColor,
});
#override
_DoseDropDownState createState() => _DoseDropDownState();
}
class _DoseDropDownState extends State<DoseDropDown> {
#override
Widget build(BuildContext context) {
return SizedBox(
height: 70,
width: 350,
child: DropdownButtonFormField(
dropdownColor: Colors.white,
value: medicationDose,
items: getDropDownItem(widget.hintColor),
iconSize: 50,
iconEnabledColor: Colors.yellow,
onChanged: (value) {
setState(() {
medicationDose = value;
});
},
decoration: InputDecoration(
prefixIcon: Icon(
Icons.home,
color: Colors.yellow,
size: 30,
),
hintText: 'الجرعة',
hintStyle: TextStyle(
fontSize: 30, fontWeight: FontWeight.bold, color: Colors.white),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.green,
),
borderRadius: BorderRadius.circular(30.0),
),
),
),
);
}
}
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> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DoseDropDown(
hintColor: Colors.brown,
)
],
),
),
);
}
}
Related
I'm trying to load content (Widget) dynamically (by a index).
However if I not use List all is working as expected:
class _MyHomePageState extends State<MyHomePage> {
final titleController = TextEditingController();
String titolo = '';
late Widget display; //This is the future widget
//List<Widget> display = <Widget>[];
//int displayIndex = 1;
initialize it:
#override
Widget build(BuildContext context) {
//display.add(calculator());
display = calculator();
and use it on body property:
body: display,
When I try to use a list:
class _MyHomePageState extends State<MyHomePage> {
final titleController = TextEditingController();
String titolo = '';
//late Widget display;
List<Widget> display = <Widget>[];
//int displayIndex = 1;
initialize:
#override
Widget build(BuildContext context) {
display.add(calculator());
//display = calculator();
and use it on body property:
body: display.first,
I get this error:
Exception has occurred.
_TypeError (type 'TabContainer' is not a subtype of type 'List' of 'function result')
Please note that TabContainer is the first Widget of calculator():
Widget calculator() => TabContainer(
selectedTextStyle: const TextStyle(
fontFamily: 'ThousandSunny',
This the entire code:
import 'package:cookedcalories/utils.dart';
import 'package:flutter/material.dart';
import 'package:convex_bottom_bar/convex_bottom_bar.dart';
import 'package:tab_container/tab_container.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Cooked Calories & Macros',
theme: ThemeData(
primarySwatch: Colors.pink,
),
home: const MyHomePage(title: 'Cooked Calories & Macros'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final titleController = TextEditingController();
String titolo = '';
//late Widget display;
List<Widget> display = <Widget>[];
//int displayIndex = 1;
#override
void initState() {
titleController.addListener(() => setState(() {}));
super.initState();
}
#override
Widget build(BuildContext context) {
display.add(calculator());
//display = calculator();
return Scaffold(
backgroundColor: Colors.yellow,
bottomNavigationBar: ConvexAppBar(
style: TabStyle.react,
items: const [
TabItem(icon: Icons.info_outline),
TabItem(icon: Icons.receipt_outlined),
TabItem(icon: Icons.calculate_outlined),
TabItem(icon: Icons.monetization_on_outlined),
TabItem(icon: Icons.settings_outlined),
],
initialActiveIndex: 1,
onTap: (int i) => print('click index=$i'),
),
appBar: AppBar(
title: Text(
widget.title,
style: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 35,
),
),
),
body: display.first,
);
}
Widget calculator() => TabContainer(
selectedTextStyle: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 35,
fontWeight: FontWeight.bold),
unselectedTextStyle: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 35,
),
color: Colors.white,
radius: 50,
tabEdge: TabEdge.left,
tabs: const [
'A',
'B',
'C',
],
children: [
Align(
alignment: Alignment.topCenter,
child: SingleChildScrollView(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(5, 30, 0, 0),
child: createTitleField()),
),
const Padding(
padding: EdgeInsets.fromLTRB(10, 30, 5, 0),
child: Image(
width: 50,
height: 50,
image: AssetImage('assets/images/clean.png')),
),
],
),
],
)),
),
const Text('Child 2'),
const Text('Child 3'),
],
);
Widget createTitleField() => TextFormField(
style: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 25,
),
controller: titleController,
validator: (value) {
if (value == null || value.trim().isEmpty) {
showSnackBar(
context,
"Attenzione: non hai inserito il Titolo dell'oggetto.",
Colors.pinkAccent.shade400);
return 'Inserisci il Titolo per questo oggetto';
} else if (value.trim().length < 3) {
showSnackBar(
context,
"Attenzione: Il Titolo deve contenere almeno 3 caratteri.",
Colors.pinkAccent.shade400);
return 'Lunghezza minima 3 caratteri';
} else if (value.trim().length > 30) {
showSnackBar(
context,
"Attenzione: Il Titolo non può essere più lungo di 30 caratteri.",
Colors.pinkAccent.shade400);
return 'Lunghezza massima 30 caratteri';
}
titolo = value;
return null;
},
decoration: InputDecoration(
border: const OutlineInputBorder(),
hintText: 'Nome Ricetta',
labelText: 'Nome Ricetta',
labelStyle: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 30,
),
hintStyle: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 25,
),
suffixIcon: titleController.text.isEmpty
? Container(
width: 0,
)
: IconButton(
onPressed: () => titleController.clear(),
icon: const Icon(Icons.close),
)),
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
);
}
Try Stop project, run flutter pub get and start project again.
I am trying to implement this custom slider on my flutter app. I have searched most of the open source libraries but I cannot seem to get the one that suits my need.
The closet I got to is Cupertino Slider but I couldn't customize it to fit my need. Any ideas?
this is what you are looking for, slider_button:
SliderButton(
action: () {
///Do something here OnSlide
},
///Put label over here
label: Text(
"Slide to cancel !",
style: TextStyle(
color: Color(0xff4a4a4a),
fontWeight: FontWeight.w500,
fontSize: 17),
),
icon: Center(
child: Icon(
Icons.power_settings_new,
color: Colors.white,
size: 40.0,
semanticLabel: 'Text to announce in accessibility modes',
)),
///Change All the color and size from here.
width: 230,
radius: 10,
buttonColor: Color(0xffd60000),
backgroundColor: Color(0xff534bae),
highlightedColor: Colors.white,
baseColor: Colors.red,
);
Try this:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
class View extends StatefulWidget {
const View({Key? key}) : super(key: key);
#override
_ViewState createState() => _ViewState();
}
class _ViewState extends State<View> {
int segmentedControlGroupValue = 0;
final Map<int, Widget> myTabs = const <int, Widget>{
0: Icon(Icons.arrow_forward, color: Colors.white,),
1: Text("Start Shopping", style: TextStyle(color: Colors.orange),)
};
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: CupertinoSlidingSegmentedControl(
backgroundColor: Colors.orange.withOpacity(0.2),
groupValue: segmentedControlGroupValue,
thumbColor: CupertinoColors.activeOrange,
children: myTabs,
onValueChanged: (newValue) {
setState(() {
segmentedControlGroupValue = newValue as int;
});
}),
),
);
}
}
I am using a dropdown widget to show multiple drpdowns from it.
String CountryVal, StateVal;
Widget _dropdown(List<String> _options, String selected){
return Container(
padding: EdgeInsets.fromLTRB(15.0, 4.0, 15.0, 4.0),
margin: EdgeInsets.fromLTRB(20.0, 7.0, 20.0, 10.0),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
isExpanded: true,
hint: Text(
_options[0],
style: TextStyle(
color: Colors.blue,
fontSize: 18.0,
),
),
items: _options.map((String value){
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String captureSelected) {
setState(() {
if(selected == 'Country Dropdown'){
CountryVal = captureSelected;
} else if(selected == 'State Dropdown'){
StateVal = captureSelected;
}
});
},
value: selected == 'Country Dropdown' ? CountryVal : StateVal,
style: TextStyle(
color: Colors.blue,
fontSize: 18.0,
),
),
),
);
}
And I have used it multiple times for different dropdowns
List<String> _country = ['- Select Country -', 'USA', 'UK'];
List<String> _state = ['- Select State -', 'New York', 'London'];
_dropdown(_country, 'Country Dropdown');
_dropdown(_state, 'State Dropdown');
Now values on 'State dropdown' depends on 'Country dropdown', and I need to reset the value of 'State dropdown' to offset 0 when 'Country dropdown' value is selected.
I have spend hours searching and trying it myself but could get it right. Please help.
You can copy paste run full code below
You can set StateVal = _state[0]; when Country dropdown value is selected.
code snippet
if (selected == 'Country Dropdown') {
CountryVal = captureSelected;
StateVal = _state[0];
}
working demo
full code
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> {
String CountryVal, StateVal;
List<String> _country = ['- Select Country -', 'USA', 'UK'];
List<String> _state = ['- Select State -', 'New York', 'London'];
Widget _dropdown(List<String> _options, String selected) {
return Container(
padding: EdgeInsets.fromLTRB(15.0, 4.0, 15.0, 4.0),
margin: EdgeInsets.fromLTRB(20.0, 7.0, 20.0, 10.0),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
isExpanded: true,
hint: Text(
_options[0],
style: TextStyle(
color: Colors.blue,
fontSize: 18.0,
),
),
items: _options.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String captureSelected) {
setState(() {
if (selected == 'Country Dropdown') {
CountryVal = captureSelected;
StateVal = _state[0];
} else if (selected == 'State Dropdown') {
StateVal = captureSelected;
}
});
},
value: selected == 'Country Dropdown' ? CountryVal : StateVal,
style: TextStyle(
color: Colors.blue,
fontSize: 18.0,
),
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_dropdown(_country, 'Country Dropdown'),
_dropdown(_state, 'State Dropdown')
],
),
),
);
}
}
I am trying to use Flutter tagging and planning to get and save to database.
I am using Flutter Tagging plugin. Here is the example which i am trying to replicate.
https://fluttercore.com/flutter-tagging-input-widget/
class Tagging extends StatefulWidget {
#override
_TaggingState createState() => _TaggingState();
}
class _TaggingState extends State<Tagging> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
String _selectedValuesJson = 'Nothing to show';
List searchlists = [];
var dtguid;
var dtgname;
int count = 0;
var offset = 0;
String nodata;
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
String text = "Nothing to show";
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
// title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: FlutterTagging(
textFieldDecoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Tags",
labelText: "Enter tags"),
addButtonWidget: _buildAddButton(),
chipsColor: Colors.pinkAccent,
chipsFontColor: Colors.white,
deleteIcon: Icon(Icons.cancel,color: Colors.white),
chipsPadding: EdgeInsets.all(2.0),
chipsFontSize: 14.0,
chipsSpacing: 5.0,
chipsFontFamily: 'helvetica_neue_light',
suggestionsCallback: (pattern) async {
return await TagSearchService.getSuggestions(pattern);
},
onChanged: (result) {
setState(() {
text = result.toString();
});
},
),
),
SizedBox(
height: 20.0,
),
Center(
child: Text(
text,
style: TextStyle(color: Colors.pink),
),
)
],
),
),
);
}
Widget _buildAddButton() {
return Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
color: Colors.pinkAccent,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.add,
color: Colors.white,
size: 15.0,
),
Text(
"Add New Tag",
style: TextStyle(color: Colors.white, fontSize: 14.0),
),
],
),
);
}
}
class TagSearchService {
static Future<List> getSuggestions(String query) async {
await Future.delayed(Duration(milliseconds: 400), null);
List<dynamic> tagList = <dynamic>[];
tagList.add({'name': "Flutter", 'value': 1});
tagList.add({'name': "HummingBird", 'value': 2});
tagList.add({'name': "Dart", 'value': 3});
List<dynamic> filteredTagList = <dynamic>[];
if (query.isNotEmpty) {
filteredTagList.add({'name': query, 'value': 0});
}
for (var tag in tagList) {
if (tag['name'].toLowerCase().contains(query)) {
filteredTagList.add(tag);
}
}
return filteredTagList;
}
}
For some reason it is giving error at below code.
FlutterTagging(
textFieldDecoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Tags",
labelText: "Enter tags"),
addButtonWidget: _buildAddButton(),
chipsColor: Colors.pinkAccent,
chipsFontColor: Colors.white,
deleteIcon: Icon(Icons.cancel,color: Colors.white),
chipsPadding: EdgeInsets.all(2.0),
chipsFontSize: 14.0,
chipsSpacing: 5.0,
chipsFontFamily: 'helvetica_neue_light',
suggestionsCallback: (pattern) async {
return await TagSearchService.getSuggestions(pattern);
},
onChanged: (result) {
Here is the picture.
I am using this version.
flutter_tagging: ^2.2.0+3
You can copy paste run full code below
Your code use flutter_tagging version 1.0.0, you can set in pubspec.yaml
Syntax error will disappear after set version
dependencies:
flutter:
sdk: flutter
flutter_tagging: 1.0.0
for latest version 2.2.0+3, you can directly use https://github.com/sarbagyastha/flutter_tagging/tree/master/example
working demo for version 1.0.0
full code
import 'package:flutter/material.dart';
import 'package:flutter_tagging/flutter_tagging.dart';
class Tagging extends StatefulWidget {
#override
_TaggingState createState() => _TaggingState();
}
class _TaggingState extends State<Tagging> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
String _selectedValuesJson = 'Nothing to show';
List searchlists = [];
var dtguid;
var dtgname;
int count = 0;
var offset = 0;
String nodata;
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
String text = "Nothing to show";
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
// title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: FlutterTagging(
textFieldDecoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Tags",
labelText: "Enter tags"),
addButtonWidget: _buildAddButton(),
chipsColor: Colors.pinkAccent,
chipsFontColor: Colors.white,
deleteIcon: Icon(Icons.cancel, color: Colors.white),
chipsPadding: EdgeInsets.all(2.0),
chipsFontSize: 14.0,
chipsSpacing: 5.0,
chipsFontFamily: 'helvetica_neue_light',
suggestionsCallback: (pattern) async {
return await TagSearchService.getSuggestions(pattern);
},
onChanged: (result) {
setState(() {
text = result.toString();
});
},
),
),
SizedBox(
height: 20.0,
),
Center(
child: Text(
text,
style: TextStyle(color: Colors.pink),
),
)
],
),
),
);
}
Widget _buildAddButton() {
return Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
color: Colors.pinkAccent,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.add,
color: Colors.white,
size: 15.0,
),
Text(
"Add New Tag",
style: TextStyle(color: Colors.white, fontSize: 14.0),
),
],
),
);
}
}
class TagSearchService {
static Future<List> getSuggestions(String query) async {
await Future.delayed(Duration(milliseconds: 400), null);
List<dynamic> tagList = <dynamic>[];
tagList.add({'name': "Flutter", 'value': 1});
tagList.add({'name': "HummingBird", 'value': 2});
tagList.add({'name': "Dart", 'value': 3});
List<dynamic> filteredTagList = <dynamic>[];
if (query.isNotEmpty) {
filteredTagList.add({'name': query, 'value': 0});
}
for (var tag in tagList) {
if (tag['name'].toLowerCase().contains(query)) {
filteredTagList.add(tag);
}
}
return filteredTagList;
}
}
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: Tagging(),
);
}
}
I hope you are doing well today. I'm having an issue with this horizontal scroll in flutter. The images are supposed to scroll left and right and depending on the picture, you will press the button and have the ability to guess the type of pic. For some reason, images and tags don't match with images. The image names are linked to the vehicleNames list in _MyHomePageState. I have also included image_card.dart to show how ImageCard works. Thank you for the second set of eyes.
main.dart
import 'dart:ui';
import 'package:flutter/material.dart';
import 'image_card.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: 'Guess the car!'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{
String curVehName = "";
double scrollPercent = 0.0;
Offset startDrag;
double startDragPercentScroll;
double finishScrollStart;
double finishScrollEnd;
AnimationController finishScrollController;
List<String> vehicleNames = [
'bmw',
'ford',
'rover',
'toyota'
];
#override
initState(){
super.initState();
finishScrollController = AnimationController(
duration: Duration(milliseconds: 150),
vsync: this,
)..addListener(() {
setState(() {
scrollPercent = lerpDouble(finishScrollStart, finishScrollEnd,
finishScrollController.value);
});
});
#override
dispose(){
finishScrollController.dispose();
super.dispose();
}
}
List<Widget> buildCards(){
List<Widget> cardList = [];
for(int i = 0; i < vehicleNames.length;i++){
cardList.add(buildCard(i,scrollPercent));
print("index: ${i}");
}
return cardList;
}
Widget buildCard(int cardIndex, double scrollPercent){
final cardScrollPercent = scrollPercent / ( 1 / vehicleNames.length);
return FractionalTranslation(
translation: Offset(cardIndex-cardScrollPercent,0.0),
child: Padding(
padding: EdgeInsets.all(8.0),
child: ImageCard(imageName: vehicleNames[cardIndex],
),
),
);
}
onHorizontalDragStart(DragStartDetails details){
startDrag = details.globalPosition;
startDragPercentScroll = scrollPercent;
}
onHorizontalDragUpdate(DragUpdateDetails details){
final currentDrag = details.globalPosition;
final dragDistance = currentDrag.dx - startDrag.dx;
final singleCardDragPercent = dragDistance / context.size.width;
setState(() {
scrollPercent = ( startDragPercentScroll + ( -singleCardDragPercent
/ vehicleNames.length)).clamp(0.0, 1.0-(1/vehicleNames.length));
});
}
onHorizontalDragEnd(DragEndDetails details){
finishScrollStart = scrollPercent;
finishScrollEnd = (scrollPercent * vehicleNames.length).round()
/vehicleNames.length;
finishScrollController.forward(from: 0.0);
setState(() {
startDrag = null;
startDragPercentScroll = null;
curVehName = '';
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
GestureDetector(
onHorizontalDragStart: onHorizontalDragStart,
onHorizontalDragUpdate: onHorizontalDragUpdate,
onHorizontalDragEnd: onHorizontalDragEnd,
behavior: HitTestBehavior.translucent ,
child: Stack(
children: buildCards(),
),
),
OutlineButton(
padding: EdgeInsets.all(10.0),
onPressed: (){
setState((){
this.curVehName = vehicleNames[(scrollPercent*10).round()];
});
},
child: Text(
'Show Answer',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
borderSide: BorderSide(
color: Colors.black,
width: 4.0,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
highlightedBorderColor: Colors.black,
),
Text(
curVehName,
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
color: Colors.blue,
letterSpacing: 2,
),
),
],
),
),
);
}
}
image_card.dart
import 'package:flutter/material.dart';
class ImageCard extends StatelessWidget{
final String imageName;
ImageCard({this.imageName});
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
border: Border.all(
color: Colors.black,
width: 4.0,
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image.asset(
'assets/images/$imageName.jpg',
height: 300,
fit: BoxFit.fitHeight,
),
),
);
}
}
I believe I found the issue. It seems that the
this.curVehName = vehicleNames[(scrollPercent*10).round()];
hard-coded the value of numbers needed in my vehicle names list. Once I added 10 pictures and added names to the list, it then worked as directed. The goal now is to see if I can make this a dynamic list.