Related
I was trying to get the single doc data from firebase and wanted to update
'''
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:wallet_app/utils/custom_textfield.dart';
import '../module/firebase_data.dart';
import '../utils/utilts.dart';
class EditPage extends StatefulWidget {
const EditPage({
Key? key,
required this.docId,
}) : super(key: key);
final String docId;
#override
State<EditPage> createState() => _EditPageState();
}
class _EditPageState extends State<EditPage> {
late DocumentSnapshot data;
Future getData() async {
User? user = FirebaseAuth.instance.currentUser;
await FirebaseFirestore.instance
.collection('users')
.doc(user?.uid)
.collection('transactions')
.doc(widget.docId)
.get()
.then((value) => data = value);
}
#override
Widget build(BuildContext context) {
TextEditingController titleController =
TextEditingController(text: data['title']);
TextEditingController amountController =
TextEditingController(text: data['amount'].toString());
TextEditingController descriptionController =
TextEditingController(text: data['description']);
bool income = data['type'];
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
foregroundColor: Colors.grey.shade800,
elevation: 0,
centerTitle: true,
title: const Text(
'Edit Transaction',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
body: FutureBuilder(
future: getData(),
builder: (context, snapshot) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomTextfield(
hintText: 'Title', controller: titleController),
CustomTextfield(
hintText: 'Amount',
controller: amountController,
keyBoradType: TextInputType.number,
),
CustomTextfield(
hintText: 'Description',
controller: descriptionController,
miniLines: 4,
maxLines: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Expense',
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 18),
),
Switch(
activeColor: Colors.green.shade300,
inactiveTrackColor: Colors.red.shade300,
inactiveThumbColor: Colors.red.shade100,
value: income,
onChanged: (v) {
setState(() {
income = v;
});
}),
const Text(
'Income',
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 18),
),
],
),
NeumorphicButton(
margin: const EdgeInsets.only(top: 15),
style: NeumorphicStyle(
shape: NeumorphicShape.flat,
color: Colors.grey.shade800,
depth: 6,
),
onPressed: () async {
if (titleController.text.isEmpty &&
amountController.text.isEmpty) {
Utils.showError(message: 'Please fill all the fields');
return;
} else {
FireData()
.updateTransaction(
title: titleController.text,
description: descriptionController.text,
amount: double.parse(amountController.text),
type: income,
docId: widget.docId)
.then((value) => {
if (income == true)
{
Utils.showError(
message: 'Income Edited Successfully')
}
else
{
Utils.showError(
message:
'Expense Edited Successfully')
},
titleController.clear(),
descriptionController.clear(),
amountController.clear(),
income = false,
});
Navigator.pop(context);
}
},
child: const Text(
'Edit Transaction',
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.w500,
),
),
),
TextButton(onPressed: () => data, child: const Text('data'))
],
),
);
}),
);
}
}
'''
I want to update the data note I am using setState function to update the state of the slider but its not updating. I want to show the available data and then allow to update it.
I also tried to get the data from the previous page but I even got stuck in that if.
I can get the Data from previous page if there's any solution for that also we will try that method.
Screenshot here
I would like to change the color of my arrow (Icon Button) after querying my firebase (likedby) array. Essentially my upvote / downvote system works by adding the user to a likedby/dislikedby array on the post and I want the arrow color to change if the users id is in the likedby or dislikedby arrays.
class HomeScreen extends StatefulWidget {
final String currentUserId;
const HomeScreen({Key key, this.currentUserId}) : super(key: key);
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: Color(0xffff5722), title: Text("Feed")),
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('The Laryngoscope')
.snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView(
children: snapshot.data.docs.map((document) {
return Center(
child: Padding(
padding: EdgeInsets.fromLTRB(15, 6, 15, 2),
child: Card(
elevation: 8.0,
child: Column(
children: [
ListTile(
title: Text(document['title'] + "\n"),
subtitle: Text(document['authors']),
),
Divider(),
ButtonBar(
children: [
Text(document['likes'].toString()),
IconButton(
icon: Icon(
FontAwesomeIcons.chevronUp,
color: Colors.grey,
size: 30,
),
onPressed: () async {
articleRef.doc(document['title']).update({
"dislikedby": FieldValue.arrayRemove(
[widget.currentUserId]),
"likedby": FieldValue.arrayUnion(
[widget.currentUserId])
});
var documents = (await articleRef
.doc(document['title'])
.get());
articleRef.doc(document['title']).update({
"likes":
(documents.data()['likedby'].length) -
(documents
.data()['dislikedby']
.length)
});
}),
IconButton(
icon: Icon(
FontAwesomeIcons.chevronDown,
color: Colors.grey,
size: 30,
),
onPressed: () async {
articleRef.doc(document['title']).update({
"likedby": FieldValue.arrayRemove(
[widget.currentUserId]),
"dislikedby": FieldValue.arrayUnion(
[widget.currentUserId])
});
var documents = (await articleRef
.doc(document['title'])
.get());
articleRef.doc(document['title']).update({
"likes": (documents
.data()['likedby']
.length) -
(documents.data()['dislikedby'].length)
});
},
),
OutlinedButton(
style: ElevatedButton.styleFrom(
primary: Colors.white, // background
onPrimary: Color(0xffff5722), // foreground
),
onPressed: () {},
child: Text('Comment'),
),
FloatingActionButton(
child: Icon(Icons.share),
backgroundColor: Color(0xFFFF5722),
onPressed: () {},
),
],
)
],
),
),
),
);
}).toList(),
);
}),
);
}
}
I'm trying to add widgets inside a slide menu in flutter, I don't know if it's possible or not. I want to use the slide menu as filter selection page for a search page.
Yes, it is possible. You can use Custom layout as a child of Drawer widget.
drawer: new Drawer(
child: new Container(
padding: new EdgeInsets.all(32.0),
child: new Column(
children: <Widget>[
ListTile(
title: Text('Select Language', style: TextStyle(fontSize: 16),),
onTap: null,
),
_drawerItemLanguage(),
itemDivider(),
ListTile(
title: Text('Select Price :'+sliderValue.toString(), style: TextStyle(fontSize: 16),),
onTap: null,
),
_drawerItemRandeSlider(),
],
),
),
),
Widget _drawerItemLanguage(){
return Column(
children: <Widget>[
CheckboxListTile(
title: Text("English"),
value: selectedData,
onChanged: (bool value){
setState(() {
selectedData = value;
});
},
secondary: Icon(Icons.language),
),
CheckboxListTile(
title: Text("Hindi"),
value: filledData,
onChanged: (bool value){
setState(() {
filledData = value;
});
},
secondary: Icon(Icons.language),
),
],
);
}
Widget _drawerItemRandeSlider(){
return ListTile(
leading: Text("0"),
contentPadding: EdgeInsets.only(top: 20.0),
title: Slider(
value: sliderValue,
min: 0.0,
max: 100.0,
onChanged: (value){
setState(() {
sliderValue = value;
});
},
activeColor: Colors.green,
//inactiveColor: Colors.red,
divisions: 100,
label: sliderValue.toString(),
),
trailing: Text("100"),
);
}
itemDivider(){
return Divider(
height: 1,
color: Colors.black,
);
}
I am trying to add some city list to a dialog with checkbox so that i need to implement multiple click on items. what I am trying to do is given below.
onPressed from button calls Rest Service and on success result I just show a dialog
void showCityDialog(BuildContext context) {
SimpleDialog dialog = new SimpleDialog(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(
"CITIES",
style: TextStyle(fontSize: 18.0, color: Colors.black),
textAlign: TextAlign.center,
),
new RaisedButton(
onPressed: () {print("clicked");},
color: Color(0xFFfab82b),
child: new Text(
"Done",
style: TextStyle(color: Colors.white),
),)],),
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
constraints: BoxConstraints(maxHeight: 500.0),
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: cityData.length,
itemBuilder: (context, position) {
return new CheckboxListTile(
value: checkboxValueCity,
onChanged: (bool value) {
setState(() {
checkboxValueCity = value;
});
},
activeColor: Color(0xFFfab82b),
dense: true,
title: Text(
cityData[position].city_name,
style: TextStyle(fontSize: 16.0, color: Colors.black),
),);},),),],)],);
showDialog(
context: context,
builder: (BuildContext context) {
return dialog;
});
}
checkboxValueCity is a boolean variable in class , on click of chekboxListItem i need to update checkbox value as checked and uncheced. At the same time need to add/remove that item to a list which is also inside that class.
But in my code checkbox is not refershing on every click but when i close that box and open it again checkbox is checked. then how can i get multiple click from tile and how can i return list from dialog?
Your dialog needs to be a StatefulWidget (Flutter Github issue). The member variable that tracks selection state needs to be in the dialog class. You can use a callback to update a member variable in your parent class with the List of selected cities. There also seem to be some issues using a ListView.builder inside of a SimpleDialog or AlertDialog (search the Flutter Github for issues) so I used a plain Dialog.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Checkbox Dialog Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Checkbox Dialog 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> {
bool checkboxValueCity = false;
List<String> allCities = ['Alpha', 'Beta', 'Gamma'];
List<String> selectedCities = [];
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
showDialog(
context: context,
builder: (context) {
return _MyDialog(
cities: allCities,
selectedCities: selectedCities,
onSelectedCitiesListChanged: (cities) {
selectedCities = cities;
print(selectedCities);
});
});
}),
);
}
}
class _MyDialog extends StatefulWidget {
_MyDialog({
this.cities,
this.selectedCities,
this.onSelectedCitiesListChanged,
});
final List<String> cities;
final List<String> selectedCities;
final ValueChanged<List<String>> onSelectedCitiesListChanged;
#override
_MyDialogState createState() => _MyDialogState();
}
class _MyDialogState extends State<_MyDialog> {
List<String> _tempSelectedCities = [];
#override
void initState() {
_tempSelectedCities = widget.selectedCities;
super.initState();
}
#override
Widget build(BuildContext context) {
return Dialog(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'CITIES',
style: TextStyle(fontSize: 18.0, color: Colors.black),
textAlign: TextAlign.center,
),
RaisedButton(
onPressed: () {
Navigator.pop(context);
},
color: Color(0xFFfab82b),
child: Text(
'Done',
style: TextStyle(color: Colors.white),
),
),
],
),
Expanded(
child: ListView.builder(
itemCount: widget.cities.length,
itemBuilder: (BuildContext context, int index) {
final cityName = widget.cities[index];
return Container(
child: CheckboxListTile(
title: Text(cityName),
value: _tempSelectedCities.contains(cityName),
onChanged: (bool value) {
if (value) {
if (!_tempSelectedCities.contains(cityName)) {
setState(() {
_tempSelectedCities.add(cityName);
});
}
} else {
if (_tempSelectedCities.contains(cityName)) {
setState(() {
_tempSelectedCities.removeWhere(
(String city) => city == cityName);
});
}
}
widget
.onSelectedCitiesListChanged(_tempSelectedCities);
}),
);
}),
),
],
),
);
}
}
Use StatefulBuilder to update Widgets only inside Dialog. StatefulBuilder is best for update sebsection of the widget tree where
state is needed.
simple code snippet
void _showDialog() {
showDialog(
context: context,
builder: (context) {
return StatefulBuilder( // StatefulBuilder
builder: (context, setState) {
return AlertDialog(
actions: <Widget>[
Container(
width: 400,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
"Student Attendence",
style: TextStyle(fontSize: 20),
),
SizedBox(
height: 5,
),
Container(
height: 2,
color: Colors.black,
),
SizedBox(
height: 15,
),
CheckboxListTile(
value: user1,
title: Text("user1"),
onChanged: (value){
setState(() {
user1=value;
});
},
),
Divider(
height: 10,
),
CheckboxListTile(
value: user2,
title: Text("user2"),
onChanged: (value){
setState(() {
user2=value;
});
},
),
Divider(
height: 10,
),
CheckboxListTile(
value: user3,
title: Text("user3"),
onChanged: (value){
setState(() {
user3=value;
});
},
),
Divider(
height: 10,
),
CheckboxListTile(
value: user4,
title: Text("user4"),
onChanged: (value){
setState(() {
user4=value;
});
},
),
Divider(
height: 10,
),
SizedBox(
height: 5,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Material(
elevation: 5.0,
color: Colors.blue[900],
child: MaterialButton(
padding: EdgeInsets.fromLTRB(
10.0, 5.0, 10.0, 5.0),
onPressed: () {},
child: Text("Save",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 15,
)),
),
),
Material(
elevation: 5.0,
color: Colors.blue[900],
child: MaterialButton(
padding: EdgeInsets.fromLTRB(
10.0, 5.0, 10.0, 5.0),
onPressed: () {
setState(() {
Navigator.of(context).pop();
});
},
child: Text("Cancel",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 15,
)),
),
),
Material(
elevation: 5.0,
color: Colors.blue[900],
child: MaterialButton(
padding: EdgeInsets.fromLTRB(
10.0, 5.0, 10.0, 5.0),
onPressed: () {},
child: Text("Select All",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 15,
)),
),
),
],
)
],
))
],
);
},
);
},
);
}
example
Although Albert's answer works, you need not go thru all that. Simply wrap the content: with a StatefulBuilder, voila!
https://api.flutter.dev/flutter/widgets/StatefulBuilder-class.html.
Note: It is important where you declare the variable(s) you want to change.
I modified your code a bit, I want when users check the list, the list won't be updated to the main view, but they will when users click the "Update" button.
But some how, it doesn't work. Can you please check ?
Thank you very much
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Checkbox Dialog Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Checkbox Dialog 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> {
bool checkboxValueCity = false;
List<String> allCities = ['Alpha', 'Beta', 'Gamma'];
List<String> selectedCities = [];
List<String> selectedCitiesTemp = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("App Bar"),
),
body: Center(
child: Column(
children: <Widget>[
_list(),
RaisedButton(
child: Text("Update From TMP List"),
onPressed: () {
setState(() {
selectedCities = selectedCitiesTemp;
});
},
)
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return _MyDialog(
cities: allCities,
selectedCities: selectedCities,
onSelectedCitiesListChanged: (cities) {
setState(() {
selectedCitiesTemp = cities;
});
},
);
});
}),
);
}
Widget _list() {
List<Widget> list = [];
for(String item in selectedCities) {
list.add(ListTile(
title: Text(item),
));
}
return Column(
children: list
);
}
}
class _MyDialog extends StatefulWidget {
_MyDialog({
this.cities,
this.selectedCities,
this.onSelectedCitiesListChanged,
});
final List<String> cities;
final List<String> selectedCities;
final ValueChanged<List<String>> onSelectedCitiesListChanged;
#override
_MyDialogState createState() => _MyDialogState();
}
class _MyDialogState extends State<_MyDialog> {
List<String> _tempSelectedCities = [];
#override
void initState() {
_tempSelectedCities = widget.selectedCities;
super.initState();
}
#override
Widget build(BuildContext context) {
return Dialog(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'CITIES',
style: TextStyle(fontSize: 18.0, color: Colors.black),
textAlign: TextAlign.center,
),
],
),
Expanded(
child: ListView.builder(
itemCount: widget.cities.length,
itemBuilder: (BuildContext context, int index) {
final cityName = widget.cities[index];
return Container(
child: CheckboxListTile(
title: Text(cityName),
value: _tempSelectedCities.contains(cityName),
onChanged: (bool value) {
if (value) {
if (!_tempSelectedCities.contains(cityName)) {
setState(() {
_tempSelectedCities.add(cityName);
});
}
} else {
if (_tempSelectedCities.contains(cityName)) {
setState(() {
_tempSelectedCities.removeWhere(
(String city) => city == cityName);
});
}
}
widget.onSelectedCitiesListChanged(_tempSelectedCities);
}),
);
}),
),
],
),
);
}
}
I want to create a round CheckBox like this
I've tried multiple variations of this, but none of them seem to work. Including I tried to use ClipRRect .
Because there are more code, I only select part of it to show here.
new Row(
children: <Widget>[
//new ClipRRect(
// borderRadius: BorderRadius.all(Radius.circular(90.0)),
// child:
new Checkbox(
tristate: true,
value: true,
onChanged: (bool newValue){
setState(() {
});
},
activeColor: Color(0xff06bbfb),
),
// ),
new Expanded(
child: new Text('将此手机号码和QQ号绑定,提高账号安全性。',
style: new TextStyle(
color: Color(0xff797979)
),
)
),
],
),
I am new to Flutter.Thanks in advance.
The Material Design checkbox has a shape property and you can set CircleBorder() to it and it will be round.
Checkbox(
checkColor: Colors.white,
fillColor: MaterialStateProperty.resolveWith(getColor),
value: isChecked,
shape: CircleBorder(),
onChanged: (bool? value) {
setState(() {
isChecked = value!;
});
},
);
You can try & play with this Code: Round CheckBox
bool _value = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Circle CheckBox"),
),
body: Center(
child: InkWell(
onTap: () {
setState(() {
_value = !_value;
});
},
child: Container(
decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.blue),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: _value
? Icon(
Icons.check,
size: 30.0,
color: Colors.white,
)
: Icon(
Icons.check_box_outline_blank,
size: 30.0,
color: Colors.blue,
),
),
),
)),
);
}
Since Flutter 2.2.0, the shape property has been introduced in the Checkbox Material Class.
Example for adding round corners to a checkbox:
Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
)
Copy the code of the Material Checkbox and create your new Checkbox widget.
In this widget change the variable const Radius _kEdgeRadius = Radius.circular(1.0) to Radius.circular(100).
I had a hard time building this and came up with this solution. I thought someone like me would need it one day. So here it is.
ClipRRect(
clipBehavior: Clip.hardEdge,
borderRadius: BorderRadius.all(Radius.circular(5)),
child: SizedBox(
width: Checkbox.width,
height: Checkbox.width,
child: Container(
decoration: new BoxDecoration(
border: Border.all(
width: 1,
),
borderRadius: new BorderRadius.circular(5),
),
child: Theme(
data: ThemeData(
unselectedWidgetColor: Colors.transparent,
),
child: Checkbox(
value: isWinnerTakesAll,
onChanged: (state) =>
setState(() => isWinnerTakesAll = !isWinnerTakesAll),
activeColor: Colors.transparent,
checkColor: CommonColors.checkBoxColor,
materialTapTargetSize: MaterialTapTargetSize.padded,
),
),
),
),
),
I hope this solves your problem! Any questions are welcomed.
Reason for using Theme widget
Without the theme widget, the checkbox had its original square box in the unselected state and I removed it with making it transparent.
BE AWARE: THIS PACKAGE IS DISCONTINUED !
There is a simple package you can add that keeps the functionality and animation of the checkbox: https://pub.dev/packages/circular_check_box
Implementation after installing and importing package:
CircularCheckBox(
value: someBooleanValue,
materialTapTargetSize: MaterialTapTargetSize.padded,
onChanged: (bool x) {
someBooleanValue = !someBooleanValue;
}
),
Set up the Theme like this:
Theme(
data: ThemeData(
checkboxTheme: CheckboxThemeData(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
),
);
With Flutter 2.2.1 shape property is added. so its easy to add change shape of checkbox.
Here I have created a circular checkbox widget:
import 'package:flutter/material.dart';
class CircularCheckbox extends StatelessWidget {
final bool? value;
final ValueChanged<bool?>? onChanged;
const CircularCheckbox({Key? key, required this.value, required this.onChanged}) : super(key: key);
#override
Widget build(BuildContext context) {
return Transform.scale(
scale: 1.3,
child: Checkbox(
value: value,
onChanged: onChanged,
),
);
}
}
you can scale the checkbox to respect to your design.
for theming the checkbox:
Update themeData of MaterialApp like this:
MaterialApp(
theme: ThemeData(toggleableActiveColor: colorScheme.primary,
checkboxTheme: Theme.of(context).checkboxTheme.copyWith(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
side: BorderSide(
width: 1.5, color:
Theme.of(context).unselectedWidgetColor),
splashRadius: 0),)
)
by applying the theme you have a nice circular checkbox:
Checkbox(
value: _bigBox,
//Simply add this line
shape: CircleBorder(),
splashRadius: 20,
onChanged: (value) {
_bigBox = value;
setState(() {});
},
),
I had a hard time building this and came up with this solution. I thought someone like me would need it one day. So here it is.
InkWell(
onTap: () {
setState(() {
selected = !selected;
});
},
child: Container(
height: 28,
width: 28,
decoration: BoxDecoration(
shape: BoxShape.circle, color: selected ? Colors.green : Colors.white,
border: Border.all(width: 2, color: Colors.green)
),
child: Padding(
padding: const EdgeInsets.all(3.0),
child: selected ? Icon(
Icons.check,
size: 18.0,
color: Colors.white,
) : Container()
),
),
),
We can use only material icons to achieve this as below:
bool checkboxValue = false;
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
setState(() {
checkboxValue = !checkboxValue;
});
},
child: checkboxValue
? Icon(
Icons.radio_button_checked,
color: Colors.blue,
size: 20,
)
: Icon(
Icons.radio_button_unchecked,
color: Colors.grey,
size: 20,
),
),
SizedBox(width: 5),
Text("Accept Terms and Conditions"),
],
),
Checkbox(
checkColor: Colors.white,
fillColor: MaterialStateProperty.resolveWith(getColor),
value: isChecked,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2)),
onChanged: (bool? value) {
setState(() {
isChecked = value!;
});
},
);
You can simply set the shape of the Checkbox as below;
Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
)
link to documentation
Why do you complicate it with ClipRect ? Just use the official material icon.
try this:
import 'package:flutter/material.dart';
class CircleCheckbox extends StatelessWidget {
final bool value;
final ValueChanged<bool> onChanged;
final Color activeColor;
final Color checkColor;
final bool tristate;
final MaterialTapTargetSize materialTapTargetSize;
CircleCheckbox({
Key key,
#required this.value,
this.tristate = false,
#required this.onChanged,
this.activeColor,
this.checkColor,
this.materialTapTargetSize,
}) : assert(tristate != null),
assert(tristate || value != null),
super(key: key);
#override
Widget build(BuildContext context) {
return ClipOval(
child: SizedBox(
width: Checkbox.width,
height: Checkbox.width,
child: Container(
decoration: new BoxDecoration(
border: Border.all(
width: 2,
color: Theme.of(context).unselectedWidgetColor ??
Theme.of(context).disabledColor),
borderRadius: new BorderRadius.circular(100),
),
child: Checkbox(
value: value,
tristate: tristate,
onChanged: onChanged,
activeColor: activeColor,
checkColor: checkColor,
materialTapTargetSize: materialTapTargetSize,
),
),
),
);
}
}
Assuming you have a boolean variable acceptTerms, you can implement it in Flutter 2.2 like this. Make sure you save your checkbox state too:
Checkbox(
value: acceptTerms,
onChanged: (value) {
setState(() {
acceptTerms = !acceptTerms;
});
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
),
Container(
decoration: BoxDecoration(
border: Border.all(
color: (checkedValue) ? Colors.red : Colors.blue,
width: 1,
),
borderRadius: BorderRadius.all(
Radius.circular(5),
)),
width: 24,
height: 24,
child: Theme(
data: ThemeData(
unselectedWidgetColor: Colors.transparent,
),
child: Checkbox(
activeColor: Colors.transparent,
checkColor: Colors.red,
value: checkedValue,
tristate: false,
onChanged: (bool isChecked) {
setState(() {
checkedValue = isChecked;
});
},
),
),
),