Basically, I have define a list of array but how to call the list on the label. can someone help me
#override
Widget build(BuildContext context) {
return Column(
children: [
Container(
color: AppColor.white,
width: MediaQuery.of(context).size.width,
child: RawChip(
showCheckmark: false,
label: Text(widget.list,
style: TextStyle(
color: isSelected ? Colors.black : const Color.fromARGB(255, 45, 110, 162),
fontFamily: 'Poppins'
),),
backgroundColor: isSelected ? Colors.white : const Color.fromARGB(255, 200, 222, 255),
shape: const StadiumBorder(
side: BorderSide(color: Colors.transparent)),
//selectedColor: Colors.red,
selected: isSelected,
onPressed: (){
setState(() {
isSelected = isSelected ? false : true;
});
},
widget.variableName is used to refer top level widget(StatefulWidget ). To get data within state class, just use local
class MyWidget extends StatefulWidget {
final int widgetData;
const MyWidget({
Key? key,
required this.widgetData,
}) : super(key: key);
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
final int stateData = 3;
late int makingLocal;
#override
void initState() {
super.initState();
makingLocal = widget.widgetData;
}
#override
Widget build(BuildContext context) {
...
}
}
in your case it will be just list but.
Container(
child: Column(children: list),
),
Related
I made an int variable tab1 and a function addTab to control the screen in modalBottomSheet, and I thought that when TextButton in HandAdd1() is pressed, a function addTab is executed, and changes the int variable tab1.
In MyApp(), as a result HandAdd2() widget is shown according to the list in MyApp(), but int variable tab1 doesn't change no matter how many times I press the TextButton in HandAdd1(), so the screen doesn't change, and I don't know what the problem is.
Can you help me ?
Here's the code:
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int tab1 = 0;
addTab (){
setState(() {
tab1++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton:FloatingActionButton.extended(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
padding:EdgeInsets.fromLTRB(20,30,20,20),
height:MediaQuery.of(context).size.height * 50,
margin: const EdgeInsets.only(
left: 0,
right: 0,
bottom: 0,
),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft:Radius.circular(25),
topRight: Radius.circular(25),
),
),
child: Scaffold(body:[HandAdd1(addTab:addTab) , HandAdd2()][tab1]),
);
},
backgroundColor: Colors.transparent,
);
);
}
}
and here's HandAdd1() WIdget. (HandAdd2() is almost similar to HandAdd1())
class HandAdd1 extends StatefulWidget {
const HandAdd1({Key? key, this.addTab}) : super(key: key);
final void addTab;
#override
HandAdd1State createState() => HandAdd1State();
}
class HandAdd1State extends State<HandAdd1> {
#override
Widget build(BuildContext context) {
return Column(
children:[
Align(alignment:Alignment.centerLeft, child:Padding(
padding:EdgeInsets.fromLTRB(0,20,0,0,),
child:Text('''title''' ,
),
),
),
Padding(
padding:EdgeInsets.fromLTRB(0,20,0,20,),
child:Container(),
),
InkWell(child: Container(
margin:EdgeInsets.fromLTRB(0,20,0,0,),
alignment:Alignment.center,
width: MediaQuery.of(context).size.width * 50,
height:60,
decoration: BoxDecoration(
borderRadius:BorderRadius.all(Radius.circular(10)),
color: Colors.pinkAccent,
),
child:Text('button' , style: TextStyle(color:Colors.white , fontWeight:FontWeight.w500 , fontSize: 20,))
),
onTap: (){
widget.addTab;
}
),
],
);
}
}
You need to pass addTab function to a addTab property as a VoidCallback.
In your HandAdd1 widget,
Change from final void addTab; to final VoidCallback addTab;
And from widget.addTab; to widget.addTab();
I am making my first Flutter app and I have a question. I have a bottom navigation bar with icons from flutter. But I want to use SVG icons in the bottom navigation bar. How can I do that?
The code I have so far:
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
int currentPage = 0;
late TabController tabController;
final List<Color> colors = [
Colors.blue,
Colors.blue,
Colors.blue,
Colors.blue,
Colors.blue
];
List<Widget> screens = [
InAppWebViewExampleScreen(),
GoogleScreen(),
GoogleScreen(),
YouTubeScreen(),
];
#override
void initState() {
tabController = TabController(length: 5, vsync: this);
tabController.animation!.addListener(
() {
final value = tabController.animation!.value.round();
if (value != currentPage && mounted) {
changePage(value);
}
},
);
super.initState();
}
void changePage(int newPage) {
setState(() {
currentPage = newPage;
});
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FrostedBottomBar(
opacity: 0.6,
sigmaX: 5,
sigmaY: 5,
child: TabBar(
indicatorPadding: const EdgeInsets.fromLTRB(6, 0, 6, 0),
controller: tabController,
indicator: const UnderlineTabIndicator(
borderSide: BorderSide(color: Colors.blue, width: 4),
insets: EdgeInsets.fromLTRB(16, 0, 16, 8),
),
tabs: [
TabsIcon(
icons: Icons.home,
color: currentPage == 0 ? colors[0] : Colors.white),
TabsIcon(
icons: Icons.search,
color: currentPage == 1 ? colors[1] : Colors.white),
TabsIcon(
icons: Icons.queue_play_next,
color: currentPage == 2 ? colors[2] : Colors.white),
TabsIcon(
icons: Icons.file_download,
color: currentPage == 3 ? colors[3] : Colors.white),
TabsIcon(
icons: Icons.menu,
color: currentPage == 4 ? colors[4] : Colors.white),
],
),
borderRadius: BorderRadius.circular(500),
duration: const Duration(milliseconds: 800),
hideOnScroll: false,
body: (context, controller) => screens[currentPage]
),
);
}
}
class TabsIcon extends StatelessWidget {
final Color color;
final double height;
final double width;
final IconData icons;
const TabsIcon(
{Key? key,
this.color = Colors.white,
this.height = 60,
this.width = 50,
required this.icons})
: super(key: key);
#override
Widget build(BuildContext context) {
return SizedBox(
height: height,
width: width,
child: Center(
child: Icon(
icons,
color: color,
),
),
);
}
}
I am a beginner in Flutter so if you have a solution, please make it simple. Thanks in advance!
I do not think that is possible with BottomNavigationBar, but you have 2 options either making your icon pack and add it to the application and you can reference to this link or using BottomAppBar instead of BottomNavigationBar which allow having a widget child and you can reference to this link.
It's not possible, you can't use it with iconData, you should remove TabsIcon and try to use another widget.
I have column of InkWells. When a button is pressed, it changes color to red from white. The problem is, when another button is pressed, the previous button doesn't change back to white.
How can I solve this?
class NavigationButton extends StatefulWidget {
const NavigationButton({
Key key,
this.title,
}) : super(key: key);
final String title;
#override
_NavigationButtonState createState() => _NavigationButtonState();
}
class _NavigationButtonState extends State<NavigationButton> {
Color _color = Colors.white;
#override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkWell(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
child: Container(
child: Text(
widget.title,
style: TextStyle(color: Colors.white, fontSize: 25)
)
),
onTap: () {
setState(() {
_color = Colors.red;
});
}
),
SizedBox(width: 10),
Container(
width: 10,
height: 10,
decoration: BoxDecoration(color: _color, shape: BoxShape.circle)
)
]
);
}
}
The menu wuth navigation buttons:
child: Container(
height: 205,
width: 210,
padding: EdgeInsets.only(right: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
for (int index = 0; index < _sectionsName.length; index++)
NavigationButton(title: _sectionsName[index], index: index)
]
)
)
Thanks in advance...
can be solved by taking a boolean variable isSeleted;
For the current situation you will have to take bool in the widget where you have defined the NavigationButton List and wrap navigationButton with gesturedetector.
import 'package:flutter/material.dart';
class NavigationButton extends StatefulWidget {
final buttonColor;
final textColor;
final String title;
const NavigationButton({
Key key,
this.title,
this.buttonColor,
this.textColor,
}) : super(key: key);
#override
_NavigationButtonState createState() => _NavigationButtonState();
}
class _NavigationButtonState extends State<NavigationButton> {
#override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(width: 10),
Container(
decoration: BoxDecoration(
color: widget.buttonColor,
),
child: Container(
child: Text(
widget.title,
style: TextStyle(
color: widget.textColor,
fontSize: 25,
),
),
),
)
],
);
}
}
class MainScreen extends StatefulWidget {
const MainScreen({Key key}) : super(key: key);
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
// List isSelected = [];
Map _sectionsName = {"one ": false, "two": false};
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 205,
width: 210,
padding: EdgeInsets.only(right: 10),
child: ListView(
children: _sectionsName.keys
.map<Widget>((item) => GestureDetector(
onTap: () {
_sectionsName.forEach((key, value) {
if (key == item) {
setState(() {
_sectionsName[key] = true;
});
}else{
_sectionsName[key] = false;
}
});
},
child: NavigationButton(
title: item,
buttonColor: _sectionsName[item] == true
? Colors.red
: Colors.white,
textColor: _sectionsName[item] == true
? Colors.white
: Colors.black,
),
))
.toList(),
),
),
);
}
}
I'd like to implement a custom radio button, but I can select all of them, and of course, the "radio" means, I can choose only one.
My code:
class RadioSelect extends StatefulWidget {
const RadioSelect(this.text, this.index, {Key key}) : super(key: key);
final String text;
final int index;
#override
_RadioSelectState createState() => _RadioSelectState();
}
class _RadioSelectState extends State<RadioSelect> {
int sizeIndex = 0;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
sizeIndex = widget.index;
});
},
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
margin: EdgeInsets.only(right: 8, top: 8),
width: 70,
height: 55,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 3,
color: sizeIndex == widget.index
? Color.fromARGB(255, 139, 195, 74)
: Colors.white,
),
borderRadius: BorderRadius.all(
Radius.circular(10) // <--- border radius here
)),
child: Text(
widget.text,
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
);
}
}
I know this is because every RadioSelect() is a different instance, but how can I make it work?
You can do it based on the Radio widget:
Change your widget to a StatelessWidget.
class RadioSelect extends StatelessWidget {
#override
Widget build(BuildContext context) {
// ...
}
}
Create a isSelected property and set your widget layout based on this property.
class RadioSelect extends StatelessWidget {
final bool isSelected;
const RadioSelect({this.isSelected});
#override
Widget build(BuildContext context) {
return Container(
// Some logic based on isSelected
color: isSelected ? Colors.red : Colors.white,
);
}
}
Create a onChanged property and, every time the user clicks on it, call this property.
class RadioSelect extends StatelessWidget {
final void Function() onChanged;
final bool isSelected;
const RadioSelect({this.isSelected, this.onChanged});
#override
Widget build(BuildContext context) {
return GestureDetector(
// Use onChanged as callback
onTap: () => onChanged(),
child: Container(
color: isSelected ? Colors.red : Colors.white,
),
);
}
}
Now, when you have to use multiple instances of it, you can use a index to keep track of what radio is currently selected:
class _MainWidgetState extends State<MainWidget> {
// Keeping track of the number of ratios you are using
final int _numRadios = 10;
int _currentIndex;
#override
Widget build(BuildContext context) {
return Column(
children: [
for (int i = 0; i < _numRatios; i++)
RadioSelect(
// The radio is select if the current index of this widget
// is equal to the current index of this child in the Column
isSelected: _currentIndex == i,
// When the user taps one ratio, updte the current index
// of this widget and set a new state
onChanged: () => setState(() => _currentIndex = i),
)
]
);
}
}
Note: The code above considers the layout of all ratios are equal. If each ratio must have its own text, for example, you can replace _numRatios with a list of strings or a more descriptive data object:
class _MainWidgetState extends State<MainWidget> {
final List<String> texts = ["radio1", "radio2", "radio3", "radio4"];
int _currentIndex;
#override
Widget build(BuildContext context) {
return Column(
children: [
for (int i = 0; i < texts.length; i++)
RadioSelect(
// Supposing you have a text property in your RadioSelect
// Access the text of the current child in the list of strings
text: texts[i],
isSelected: _currentIndex == i,
onChanged: () => setState(() => _currentIndex = i),
)
]
);
}
}
video:https://drive.google.com/file/d/1Nh49PxHeCak4YkaCHVec8hQCzgTN7Kr-/view?usp=sharing
The subcomponent clicks on the callback function, and the background color of the subcomponent cannot be changed by changing the value of list
I tried using deep copy and it still didn't work. How can I change the code to switch the background color?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
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> {
List<bool> tabsActive = [true,false,false,false,false];
void changeTabs(int view) {
print("view:$view");
for(int i = 0;i < tabsActive.length;i++) {
tabsActive[i] = false;
}
setState(() {
tabsActive[view-1] = true;
});
print(tabsActive);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body:Center(
child: Row(
children: <Widget>[
GameTabs("tab1",1,tabsActive[0],changeTabs),
GameTabs("tab2",2,tabsActive[1],changeTabs),
GameTabs("tab3",3,tabsActive[2],changeTabs),
GameTabs("tab4",4,tabsActive[3],changeTabs),
GameTabs("tab5",5,tabsActive[4],changeTabs),
],
),
)
);
}
}
typedef CallIntFun = void Function(int);
class GameTabs extends StatefulWidget {
final String title;
final int view;
final bool active;
CallIntFun changeTabs;
GameTabs(this.title,this.view,this.active,this.changeTabs);
#override
_GameTabsState createState() => _GameTabsState(title,view,active,changeTabs);
}
class _GameTabsState extends State<GameTabs> with SingleTickerProviderStateMixin {
AnimationController _controller;
final String title;
final int view;
final bool active;
Color bgColor;
CallIntFun changeTabs;
_GameTabsState(this.title,this.view,this.active,this.changeTabs);
#override
Widget build(BuildContext context) {
if (active) {
return ActiveGameTabs(title);
}
return Expanded(
child: GestureDetector(
onTap: (){
changeTabs(view);
},
child: Container(
height: 56,
padding: EdgeInsets.fromLTRB(0, 6, 0, 0),
decoration: BoxDecoration(
color: Color.fromRGBO(235, 235, 235, 1),
border: Border.all(
color: Colors.green,
width: 3.0,
style: BorderStyle.none
),
),
child: Text(
title,
textAlign: TextAlign.center,
),
),
)
);
}
}
class ActiveGameTabs extends StatelessWidget {
final String title;
ActiveGameTabs(this.title);
#override
Widget build(BuildContext context) {
return Expanded(
child: Container(
height: 56,
padding: EdgeInsets.fromLTRB(0, 6, 0, 0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.green,
width: 3.0,
style: BorderStyle.none
),
),
child: Text(
title,
textAlign: TextAlign.center,
),
)
);
}
}
You are passing the values from widget to state when the state is created for the first time. So it won't change when there is a change in any of those property (Because state won't gets created each time). You want to change your GameTab implementation like this:
class GameTabs extends StatefulWidget {
final String title;
final int view;
final bool active;
CallIntFun changeTabs;
GameTabs(this.title,this.view,this.active,this.changeTabs);
#override
_GameTabsState createState() => _GameTabsState();
}
class _GameTabsState extends State<GameTabs> with SingleTickerProviderStateMixin {
AnimationController _controller;
#override
Widget build(BuildContext context) {
if (widget.active) {
return ActiveGameTabs(widget.title);
}
return Expanded(
child: GestureDetector(
onTap: (){
widget.changeTabs(widget.view);
},
child: Container(
height: 56,
padding: EdgeInsets.fromLTRB(0, 6, 0, 0),
decoration: BoxDecoration(
color: Color.fromRGBO(235, 235, 235, 1),
border: Border.all(
color: Colors.green,
width: 3.0,
style: BorderStyle.none
),
),
child: Text(
widget.title,
textAlign: TextAlign.center,
),
),
)
);
}
}