I am trying to create a container with a gesture detector that changes color onTap, but for some reason it is not doing so. I have a bool and a function to setstate and change it, and in the backgroundColor of the container I have it changing based on the color of the bool. Any advice would be greatly appreciated.
import 'package:flutter/material.dart';
class VotingButton extends StatefulWidget {
#override
State<VotingButton> createState() => _VotingButtonState();
}
class _VotingButtonState extends State<VotingButton> {
bool savePressed = false;
void buttonPressed() {
setState(() {
if (savePressed == false) {
savePressed == true;
} else if (savePressed == true) {
savePressed == false;
}
});
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 18.0),
child: GestureDetector(
onTap: () {
buttonPressed;
print(savePressed); //stays false for some reason
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: savePressed ? Colors.blue : Colors.red[400],
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 40),
child: Text(
'I\'ll be Here!',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
),
),
);
}
}
import 'package:flutter/material.dart';
class VotingButton extends StatefulWidget {
#override
State<VotingButton> createState() => _VotingButtonState();
}
class _VotingButtonState extends State<VotingButton> {
bool savePressed = false;
void buttonPressed() {
setState(() {
if (savePressed == false) {
savePressed == true;
} else if (savePressed == true) {
savePressed == false;
}
});
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 18.0),
child: GestureDetector(
onTap: () {
//You are referencing but not calling here, you should use ()
buttonPressed();
print(savePressed); //stays false for some reason
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: savePressed ? Colors.blue : Colors.red[400],
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 40),
child: Text(
'I\'ll be Here!',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
),
),
);
}
}
In GestureDetector you not calling buttonPressed method properly
Try this:
GestureDetector(
onTap: buttonPressed,
......
And optimise code by making change into buttonPressed method
Try this:
void buttonPressed() {
setState(() {
savePressed = !savePressed;
});
}
Try this, I change a little bit your buttonPressed method, and GestureDetector onTap. Hope it helps
import 'package:flutter/material.dart';
class VotingButton extends StatefulWidget {
#override
State<VotingButton> createState() => _VotingButtonState();
}
class _VotingButtonState extends State<VotingButton> {
bool savePressed = false;
void buttonPressed() {
setState(() {
savePressed = !savePressed;
});
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 18.0),
child: GestureDetector(
onTap: () {
buttonPressed();
print(savePressed);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: savePressed ? Colors.blue : Colors.red[400],
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 40),
child: Text(
'I\'ll be Here!',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
),
),
);
}
}
Try the following code:
import 'package:flutter/material.dart';
class VotingButton extends StatefulWidget {
#override
State<VotingButton> createState() => _VotingButtonState();
}
class _VotingButtonState extends State<VotingButton> {
bool savePressed = false;
void buttonPressed() {
setState(() {
savePressed = !savePressed;
});
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 18.0),
child: GestureDetector(
onTap: () {
buttonPressed();
print(savePressed);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: savePressed ? Colors.blue : Colors.red[400],
),
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 40),
child: Text(
'I\'ll be Here!',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
),
),
);
}
}
Related
I am trying to implement multi-select feature, everything seem to be working well on debug mode including the loading indicators but unfortunately the changes doesn't update(notifyListeners()) on release mode
This is how my viewModel looks like:
class HobbyViewModel extends ChangeNotifier {
bool loading = false;
bool isSelected = false;
List<dynamic> hobbyList = [
'Shopping',
'Swimming',
'Travelling',
'Brunch',
'Music',
'Trips',
'Camping'
];
List<dynamic>? selectedHobby = [];
checkHobbySelected(hobby, UserModel user) {
if (user.hobbies != null) {
selectedHobby = user.hobbies!;
notifyListeners();
}
if (selectedHobby!.contains(hobby)) {
isSelected = true;
notifyListeners();
} else {
isSelected = false;
notifyListeners();
}
}
setHobby(hobby) {
if (!selectedHobby!.contains(hobby)) {
if (selectedHobby!.length < 5) {
selectedHobby!.add(hobby);
// notifyListeners();
}
print('>>>>> $selectedHobby');
notifyListeners();
} else {
selectedHobby!.removeWhere((element) => element == hobby);
print('>>>>> $selectedHobby');
notifyListeners();
}
}
updateHobbies(BuildContext context) async {
loading = true;
notifyListeners();
try {
await usersRef.doc(firebaseAuth.currentUser!.uid).update({
'hobbies': selectedHobby,
});
} catch (e) {
loading = false;
notifyListeners();
}
loading = false;
notifyListeners();
Navigator.pop(context);
}
}
This is the hobby page where I am multi-selecting:
import 'package:quicktext/view_models/profile/hobby_view_model.dart';
class Hobby extends StatefulWidget {
final UserModel user;
const Hobby({Key? key, required this.user}) : super(key: key);
#override
State<Hobby> createState() => _HobbyState();
}
class _HobbyState extends State<Hobby> {
#override
Widget build(BuildContext context) {
HobbyViewModel viewModel =
Provider.of<HobbyViewModel>(context, listen: true);
return Scaffold(
appBar: AppBar(
title: Text(
'What are your Hobbies?',
style: TextStyle(
fontSize: 17.0,
),
),
),
body: LoadingOverlay(
isLoading: viewModel.loading,
progressIndicator: CupertinoActivityIndicator(),
opacity: 0.1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: SingleChildScrollView(
child: Wrap(
children: viewModel.hobbyList.map(
(hobby) {
viewModel.checkHobbySelected(hobby, widget.user);
return GestureDetector(
onTap: () => viewModel.setHobby(hobby),
child: Container(
margin: EdgeInsets.symmetric(horizontal: 5, vertical: 4),
child: Container(
padding:
EdgeInsets.symmetric(vertical: 5, horizontal: 12),
decoration: BoxDecoration(
color: viewModel.isSelected
? Color(0xffffb109)
: Colors.white,
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: Colors.grey,
),
),
child: Text(
hobby,
style: TextStyle(
color: viewModel.isSelected
? Colors.white
: Colors.grey,
fontSize: 14,
),
),
),
),
);
},
).toList(),
),
),
),
),
bottomNavigationBar: Padding(
padding: const EdgeInsets.only(bottom: 100.0, right: 20.0, left: 20.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: Container(
height: 60.0,
color: Theme.of(context).colorScheme.secondary,
child: InkWell(
onTap: () => viewModel.updateHobbies(context),
child: Center(
child: const Text(
'Done',
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
),
),
),
);
}
}
Is there anything wrong with my code? I am using provider ^6.0.1
The ones I found in different sites all have a search icon on the header and the search bar only appears when it is clicked but I want a search bar that is already there but also with a search button that is connected to it
Illustration:
Try this code(also with the logic to use the Search Functionality). If you like it.
Full Code
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool hasFocus = false;
FocusNode focus = FocusNode();
TextEditingController searchController = TextEditingController();
#override
void initState() {
super.initState();
focus.addListener(() {
onFocusChange();
});
searchController.addListener(() {
filterClints();
});
}
#override
void dispose() {
searchController.dispose();
focus.removeListener(onFocusChange);
super.dispose();
}
void onFocusChange() {
if (focus.hasFocus) {
setState(() {
hasFocus = true;
});
} else {
setState(() {
hasFocus = false;
});
}
}
#override
Widget build(BuildContext context) {
bool isSearching = searchController.text.isNotEmpty;
return Scaffold(
body: Column(
children: [
Container(
child: Padding(
padding: const EdgeInsets.only(
left: 5,
right: 5,
top: 0,
bottom: 7,
),
child: TextField(
focusNode: focus,
controller: searchController,
// style: TextStyle(fontSize: 14, ),
decoration: InputDecoration(
hintText: "Search",
label: const Text("Search customers & places"),
contentPadding: const EdgeInsets.symmetric(vertical: 2),
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(50)),
borderSide: BorderSide(
color: Theme.of(context).colorScheme.primary,
),
),
prefixIcon: const Icon(
Icons.search,
),
suffixIcon: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (hasFocus)
InkWell(
onTap: () {},
child: const Icon(
Icons.clear,
color: Colors.grey,
),
),
const SizedBox(
width: 10,
),
PopupMenuButton(
icon: const Icon(Icons.more_vert_sharp,
color: Colors.grey),
itemBuilder: (context) => [
const PopupMenuItem(),
PopupMenuItem(),
],
onSelected: (value) {},
)
],
),
),
),
),
),
],
),
);
}
}
Preview
You can change the values prefixIcon/suffixIcon in textField to suit your needs.
I have a list in this file called check_symptoms.dart which the list is called _chosenItems
i want it to pass it to another file which is a stateful widget
here's my code for Check_symptoms.dart
import 'package:diagnose_app/results.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/services.dart';
class SymptomsChecker extends StatefulWidget {
const SymptomsChecker({Key? key}) : super(key: key);
#override
State<SymptomsChecker> createState() => _SymptomsCheckerState();
}
class _SymptomsCheckerState extends State<SymptomsChecker> {
List _items = [];
List _itemsForDisplay = [];
List _chosenItems = [];
int maxheight = 0;
ScrollController _scrollController = ScrollController();
Future<void> readJson() async {
final String response =
await rootBundle.loadString('assets/data/Symptoms.json');
final data = await json.decode(response);
setState(() {
_items = data["Symptoms"];
_itemsForDisplay = _items;
});
}
#override
void initState() {
// TODO: implement initState
readJson();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromARGB(255, 105, 120, 255),
body: Padding(
padding: const EdgeInsets.all(5),
child: Column(
children: [
// Display the data loaded from sample.json
// _ListChosenItem(23),
SizedBox(
height: 25,
),
_searchBar(),
Divider(
height: 1,
),
Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
return _ListItem(index);
},
itemCount: _itemsForDisplay.length,
),
),
Divider(
height: 2,
),
Padding(
padding: const EdgeInsets.all(3.0),
child: LimitedBox(
maxHeight: 200,
child: Scrollbar(
controller: _scrollController,
child: SingleChildScrollView(
//scrollDirection: Axis.horizontal,
child: Wrap(
children: _chosenItems.map((item) {
//print(_chosenItems);
return chosenItems(item);
}).toList(),
),
),
),
),
),
Divider(
color: Colors.black,
height: 10,
thickness: 1,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Container(
height: 50,
width: double.infinity,
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
// sending chosenItems to results.dart
builder: (context) => Results(list: _chosenItems)));
},
child: Text(
"Find Results",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
),
style: ElevatedButton.styleFrom(),
),
),
),
SizedBox(
height: 5,
),
],
),
),
);
}
Padding chosenItems(item) {
return Padding(
padding: const EdgeInsets.all(3.0),
child: Builder(builder: (context) {
return ElevatedButton.icon(
onPressed: () {
setState(() {
_itemsForDisplay.add(item);
//_items.add(item);
_chosenItems.remove(item);
});
},
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
textStyle:
const TextStyle(fontSize: 15, fontWeight: FontWeight.w400)),
label: Text(item),
icon: Icon(
Icons.remove_circle,
color: Color.fromARGB(255, 255, 217, 216),
),
);
}),
);
}
_searchBar() {
return Padding(
padding: const EdgeInsets.all(8),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)),
filled: true,
fillColor: Color.fromARGB(255, 244, 244, 244),
hintText: 'Search Symptoms'),
style: TextStyle(color: Color.fromARGB(255, 22, 25, 52)),
maxLines: 1,
onChanged: (text) {
text = text.toLowerCase();
setState(() {
_itemsForDisplay = _items.where((item) {
var itemEntity = item.toLowerCase();
return itemEntity.contains(text);
}).toList();
});
},
),
);
}
_ListItem(index) {
return Wrap(
children: [
ElevatedButton(
onPressed: () {
setState(() {
_chosenItems.add(_itemsForDisplay[index]);
_itemsForDisplay.removeAt((index));
//_items.removeAt((index));
});
},
style: ElevatedButton.styleFrom(
textStyle:
const TextStyle(fontSize: 18, fontWeight: FontWeight.w500)),
child: Text(_itemsForDisplay[index]),
),
],
);
}
_ListChosenItem(index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
children: [
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
textStyle: const TextStyle(fontSize: 20)),
child: Text(_chosenItems[index]),
),
],
),
);
}
}
here's the way I'm receiving the list in results.dart
import 'package:flutter/material.dart';
class Results extends StatefulWidget {
final List list;
const Results({required this.list});
#override
State<Results> createState() => _ResultsState(list);
}
class _ResultsState extends State<Results> {
#override
Widget build(BuildContext context) {
print(list);
return Scaffold();
}
}
this line of code of results.dart
State<Results> createState() => _ResultsState(list);
is says:
List list Type: List
package:diagnose_app/results.dart
Don't put any logic in createState.dartno_logic_in_create_state Too
many positional arguments: 0 expected, but 1 found. Try removing the
extra arguments.
Am I passing the list in a wrong way? thanks for helping in advance.
First of all, an instance of State can access the members of its parent StatefulWidget via the widget property.
So your particular problem can be solved simply by accessing widget.list, you don't need to pass the list explicitly to _ResultsState:
import 'package:flutter/material.dart';
class Results extends StatefulWidget {
final List list;
const Results({required this.list});
#override
State<Results> createState() => _ResultsState();
}
class _ResultsState extends State<Results> {
#override
Widget build(BuildContext context) {
print(widget.list);
return Scaffold();
}
}
But further, if you do want to explicitly pass a value to a class constructor, you'll need to add the field as a member to the class and define the constructor that takes that value.
i am trying to display a typing indicator before showing a message, i have tried the code below but it only displays the typing indicator once (only for the first message), what i want is to display it each time i want to print a message.
this is after modification, the code still after the first message does not display the typing indicator again
import 'package:bubble/bubble.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_bubble/bubble_type.dart';
import 'package:flutter_chat_bubble/chat_bubble.dart';
import 'package:flutter_chat_bubble/clippers/chat_bubble_clipper_2.dart';
import 'package:flutter_dialogflow/dialogflow_v2.dart';
import 'package:progress_indicators/progress_indicators.dart';
void main() {
runApp(Bot());
}
class Bot extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'bot',
theme: ThemeData(
primarySwatch: Colors.grey,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
debugShowCheckedModeBanner: false,
home: HomePage(title: 'bot'),
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool _nextWidget = false;
#override
void initState() {
super.initState();
}
void myMethod(){
Future.delayed(
const Duration(
seconds: 5,
milliseconds: 500,
),
() {
if (this.mounted) {
setState(() {
_nextWidget = true;
});
}
});
}
void response(query) async {
AuthGoogle authGoogle = await AuthGoogle(
fileJson: "assets/credentials.json").build();
Dialogflow dialogflow =
Dialogflow(authGoogle: authGoogle, language: Language.english);
AIResponse aiResponse = await dialogflow.detectIntent(query);
setState(() {
messsages.insert(0, {
"data": 0,
"message": aiResponse.getListMessage()[0]["text"]["text"][0].toString()
});
});
print(aiResponse.getListMessage()[0]["text"]["text"][0].toString());
}
final messageInsert = TextEditingController();
List<Map> messsages = List();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[850],
appBar: AppBar(
leading: IconButton(icon: Icon(Icons.menu, color: Colors.white, size: 45)),
backgroundColor: Colors.grey[800],
),
body: Container(
child: Column(
children: [
Flexible(
child: ListView.builder(
reverse: true,
itemCount: messsages.length,
itemBuilder: (context, index) => chat(
messsages[index]["message"].toString(),
messsages[index]["data"])
),
),
Container(
color: Colors.grey[850],
child: ListTile(
leading: IconButton(
icon: Icon(Icons.mic_off, color: Colors.white, size: 35),
),
title: Container(
height: 45,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Colors.white,
),
padding: EdgeInsets.only(left: 10),
child: TextFormField(
cursorColor: Colors.grey[850],
controller: messageInsert,
decoration: InputDecoration(
hintText: "Chat with me",
hintStyle: TextStyle(
color: Colors.black
),
),
style: TextStyle(
fontSize: 16,
color: Colors.black
),
onChanged: (value) {}
)
),
trailing:
IconButton(
icon: Icon(
Icons.send,
size: 30.0,
color: Colors.greenAccent,
),
onPressed: () {
if (messageInsert.text.isEmpty) {
print("empty message");
} else {
setState(() {
messsages.insert(0,
{"data": 1, "message": messageInsert.text});
});
response(messageInsert.text);
messageInsert.clear();
}
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
})
)
),
SizedBox(height: 10.0)
]
),
)
);
}
Widget bot(String message) {
myMethod();
return _nextWidget ? botMessage(message) : botInd();
}
Widget botInd() {
return Container(
alignment: Alignment.bottomLeft,
margin: EdgeInsets.only(top: 20),
child: Container(
constraints: BoxConstraints(maxWidth: 75, maxHeight: 100),
child: JumpingDotsProgressIndicator(fontSize: 50.0, color: Colors.white)
)
);
}
Widget botMessage(String message) {
return ChatBubble(
clipper: ChatBubbleClipper2(type: BubbleType.receiverBubble),
alignment: Alignment.bottomLeft,
margin: EdgeInsets.only(top: 20),
backGroundColor: Colors.white,
child: Container(
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.7),
child: Text(
message,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)
)
)
);
}
Widget user(String message) {
return ChatBubble(
clipper: ChatBubbleClipper2(type: BubbleType.sendBubble),
alignment: Alignment.bottomRight,
margin: EdgeInsets.only(top: 20),
backGroundColor: Colors.white,
child: Container(
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.7),
child: Text(
message,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)
)
)
);
}
Widget chat(String message, int data) {
return data == 0 ? bot(message) : user(message);
}
}
The initState method runs 1 time just before your code appears on the screen. Therefore, I suggest you use the block of code you wrote in the initState method and want to run, by creating a new method other than initState like:
void myMethod(){
Future.delayed(
const Duration(
seconds: 7,
milliseconds: 500,
),
() {
if (this.mounted) {
setState(() {
_nextWidget = !_nextWidget;
});
}
});}
After doing that, try calling "myMethod".
Hope this works for you.
I am using simple coverflow plugin for an app. Each container is scrollable horizontally and has a title with 3 choices as Card.
Issue is when I select any of the card choice, it selects same option on other cards in the list as well, as shown below:
As you can see above, the leftmost and rightmost cards shows the selected card option in green color when I select card # 1 from first container.
What do I need to do so that I should be able to select an option from center card which doesn't highlight / select same option on other cards ?
Code below:
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new CoverFlow(
dismissedCallback: disposeDismissed,
currentItemChangedCallback: (int index) {
print(index);
},
height: 600,
itemCount: d.length,
itemBuilder: (BuildContext context, int index) {
return Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)),
child: Column(children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 25.0),
child: Text(
"Test",
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
),),
Container(
height: 50.0,
child: GestureDetector(
child: Card(
color: _c
? Colors.lightGreen
: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.symmetric(
horizontal: 10, vertical: 6),
child: Center(
child: Text("1",
style: TextStyle(
fontSize: 18.0),
textAlign: TextAlign.center))
),
onTap: () {
setState(() {
_s = true;
_c = true;
_w = false;
_wr = false;
});
},)),
Container(
height: 50.0,
child: GestureDetector(
child: Card(
color:
_w ? Colors.redAccent : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.symmetric(
horizontal: 10, vertical: 6),
child: Center(
child: Text(
"2",
style: TextStyle(
fontSize: 18.0),
textAlign: TextAlign.center,
))),
onTap: () {
setState(() {
_s = false;
_c = false;
_w = true;
_wr = false;
});
},
)),
Container(
height: 50.0,
child: GestureDetector(
child: Card(
color: _wr
? Colors.redAccent
: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.symmetric(
horizontal: 10, vertical: 6),
child: Center(
child: Text(
"3",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0),
),)),
onTap: () {
setState(() {
_s = false;
_c = false;
_w = false;
_wr = true;
});
},
)),
Padding(
padding: EdgeInsets.only(top: 25.0),
)
]
),
),
);
},
));}
Widget widgetBuilder(int i) {
if (d.length == 0) {
return Container();
} else {
print([i % d.length]);
return d[i % d.length];
}}
disposeDismissed(int dismissedItem, DismissDirection direction) {
d.removeAt(dismissedItem % d.length);
}
}
I think that you use the same state for your 3 cards, so the _c var is the same for all your 3 cards.
You can create a new StatefulWidget that build a card (and have it's own _c var inside of it) or you can use an array (List or Map) indexed by the index from CoverFlow in your actual widget.
Option 1:
class CustomCard extends StatefulWidget {
#override
_CustomCardState createState() => _CustomCardState();
}
class _CustomCardState extends State<CustomCard> {
// Initialise here or in `initState()` method.
bool _s = false;
bool _c = false;
bool _w = false;
bool _wr = false;
#override
Widget build(BuildContext context) {
return Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
child: Column(children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 25.0),
child: Text(
"Test",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
),
Container(
height: 50.0,
child: GestureDetector(
child: Card(
color: _c ? Colors.lightGreen : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
child: Center(
child: Text("1",
style: TextStyle(fontSize: 18.0),
textAlign: TextAlign.center))),
onTap: () {
setState(() {
_s = true;
_c = true;
_w = false;
_wr = false;
});
},
)),
Container(
height: 50.0,
child: GestureDetector(
child: Card(
color: _w ? Colors.redAccent : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
child: Center(
child: Text(
"2",
style: TextStyle(fontSize: 18.0),
textAlign: TextAlign.center,
))),
onTap: () {
setState(() {
_s = false;
_c = false;
_w = true;
_wr = false;
});
},
)),
Container(
height: 50.0,
child: GestureDetector(
child: Card(
color: _wr ? Colors.redAccent : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
child: Center(
child: Text(
"3",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.0),
),
)),
onTap: () {
setState(() {
_s = false;
_c = false;
_w = false;
_wr = true;
});
},
)),
Padding(
padding: EdgeInsets.only(top: 25.0),
)
]));
}
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new CoverFlow(
dismissedCallback: disposeDismissed,
currentItemChangedCallback: (int index) {
print(index);
},
height: 600,
itemCount: d.length,
itemBuilder: (BuildContext context, int index) {
return Container(
child: CustomCard()
);
},
));}
Widget widgetBuilder(int i) {
if (d.length == 0) {
return Container();
} else {
print([i % d.length]);
return d[i % d.length];
}}
disposeDismissed(int dismissedItem, DismissDirection direction) {
d.removeAt(dismissedItem % d.length);
}
You can add options in your CustomCard widget.
Option 2:
Create a class for your data :
class MyData {
bool s = false;
bool c = false;
bool w = false;
bool wr = false;
}
Create a list to store your data (in your State):
List<MyData> _cardsData;
#override
initState() {
super.initState();
_cardsData = List.generate(d.length, (index) => MyData());
}
Use the list:
// ...
onTap: () {
setState(() {
_cardsData[index].c = true;
})
}
// ...
You just need to specify the index and the currentIndex, this code works:
import 'package:flutter/material.dart';
import 'package:simple_coverflow/simple_coverflow.dart';
void main() => runApp(MaterialApp(
home: MyApp(),
));
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int curerntIndex = 0;
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new CoverFlow(
dismissedCallback: disposeDismissed,
currentItemChangedCallback: (int index) {
print(index);
setState(() {
curerntIndex = index;
});
},
height: 600,
itemCount: d.length,
itemBuilder: (BuildContext context, int index) {
return Item(index, curerntIndex);
},
));
}
}
class Item extends StatefulWidget {
final int index;
final int curerntIndex;
Item(this.index, this.curerntIndex);
#override
_ItemState createState() => _ItemState(index, curerntIndex);
}
class _ItemState extends State<Item> {
final int index;
final int curerntIndex;
bool _s = true;
bool _c = true;
bool _w = false;
bool _wr = false;
_ItemState(this.index, this.curerntIndex);
#override
Widget build(BuildContext context) {
return Container(
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
child: Column(children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 25.0),
child: Text(
"Test",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
),
Container(
height: 50.0,
child: GestureDetector(
child: Card(
color: _c ? Colors.lightGreen : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
child: Center(
child: Text("1",
style: TextStyle(fontSize: 18.0),
textAlign: TextAlign.center))),
onTap: () {
if (index == curerntIndex) {
setState(() {
_s = true;
_c = true;
_w = false;
_wr = false;
});
}
},
)),
Container(
height: 50.0,
child: GestureDetector(
child: Card(
color: _w ? Colors.redAccent : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
child: Center(
child: Text(
"2",
style: TextStyle(fontSize: 18.0),
textAlign: TextAlign.center,
))),
onTap: () {
if (index == curerntIndex) {
setState(() {
_s = false;
_c = false;
_w = true;
_wr = false;
});
}
},
)),
Container(
height: 50.0,
child: GestureDetector(
child: Card(
color: _wr ? Colors.redAccent : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
child: Center(
child: Text(
"3",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.0),
),
)),
onTap: () {
if (index == curerntIndex) {
setState(() {
_s = false;
_c = false;
_w = false;
_wr = true;
});
}
},
)),
Padding(
padding: EdgeInsets.only(top: 25.0),
)
]),
),
);
}
}
no its not you are the one who changes the color using _c to color green so it changes in all of them but actually you are choosing only one.as in flutter you don't have to type new to create new gesture detector so if you want to change the color only for the tapped cell do it by the index you get from currentItemChangedCallback: (int index), or by changing the tapped widget color only.