Don't show backbutton if index > 0 - flutter

I have a scaffold and on the leading of AppBar a custom back button.
I have a int refIndex that initially is 0, but changes to the same value as the index of Pageview.builder changes
I want the backbuttnn to disappear if the refIndex > 0. I have no idea why its not working.
Widget leadingWiget() {
if (refIndex == 0) {
return IconButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
icon: const Icon(
Icons.chevron_left,
color: Colors.black,
size: 40,
),
onPressed: () {
// Navigator.of(context).pop();
print(refIndex);
},
);
}
return const SizedBox(height: 0, width: 0);
}
EDIT: I have the var declared right after the class class _QuestionsPageState extends State<QuestionsPage> {
in Pageview.builder, after itemBuilder: (ctx, index) { I have refIndex = index;
Is it wrong? I'm facing the same problem if I want to display the refIndex. The value itself changes when I change pages, but the displayed is the same as the initial, 0.

You can use the Visibilty Widget.
For example:
Visibilty(
visible: refIndex == 0,
child: IconButton(...),
)

Related

Clicking the button does not show the loader in Flutter

I need to add a loader to the button. That is, when you click on the Save button, you need to show the CircularProgressIndicator. I wanted to implement this through Bloc, because if I do this through setState (() {}), then I will have to rebuild the widget and the new added data on the page will disappear. Therefore, I want to do it through Bloc. I created a variable there and assign values ​​to it, the values ​​change but the loader does not update, tell me how can I make the loader show?
return BlocBuilder<EditPhotoCubit, EditPhotoState>(
builder: (context, state) {
return SizedBox(
height: size.height,
width: size.width,
child: _child(size, topPadding, context, cubitEditPhoto,
mainState.charging),
);
});
}
return const SizedBox();
});
...
SizedBox(
width: 148,
child: cubitEditPhoto.isLoading
? const CircularProgressIndicator(
color: constants.Colors.purpleMain)
: DefaultButtonGlow(
text: 'Save',
color:Colors.purpleMain,
shadowColor: Colors.purpleMain,
textStyle: Styles.buttonTextStyle,
onPressed: () async {
cubitEditPhoto.isLoading = true;
await cubitEditPhoto
.uploadImage(widget.chargingId)
.then((value) {
cubitEditPhoto.isLoading = false;
});
},
),
),
cubit
class EditPhotoCubit extends Cubit<EditPhotoState> {
EditPhotoCubit() : super(EditPhotoInitial());
bool isLoading = false;
}

How to validate a form that has cards to select from and the user should obligatorily select one of them?

I have a code whereby the genders of a pet is listed in two separate cards and when the user taps on one of them, it changes color to indicate that it has been selected and is saved in the database. However, the app is letting the user continue to the next page without choosing any one of the values. I want to do a validation whereby the user will have to choose one of the cards to be able to move forward. How can I do this please?
Here is my code:
Expanded(
child: GridView.count(
crossAxisCount: 2,
primary: false,
scrollDirection: Axis.vertical,
children: List.generate(petGenders.length, (index) {
return GestureDetector(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0)),
color:
selectedIndex == index ? primaryColor : null,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
petGenders[petKeys[index]],
SizedBox(
height: 15.0,
),
Text(
petKeys[index],
style: TextStyle(
color: selectedIndex == index
? Colors.white
: null,
fontSize: 18.0,
fontWeight: FontWeight.w600),
),
],
),
),
),
onTap: () {
setState(() {
widget.pet.gender = petKeys[index];
selectedIndex = index;
});
});
}),
),
),
The model:
Map<String, Image> genders() => {
"Male":
Image(image: AssetImage('Assets/images/male.png'), width: 50),
"Female":
Image(image: AssetImage('Assets/images/female.png'), width: 50)
};
Take one variable
bool isGenderSelected = false;
Then change its value to true on tap of card like
onTap: () {
setState(() {
isGenderSelected = true;
widget.pet.gender = petKeys[index];
selectedIndex = index;
});
});
Now check if it's true then only allow the user to go next page or show some message to the user
Scenario like this, I prefer using nullable selectedValue. In this case, I will create nullable int to hold and switch between selection.
int? selectedIndex;
And using color will be like
color: selectedIndex==index? SelectedColor:null,
you can replace null with inactive color.
For validation part, do null check on selectedIndex .
if(selectedIndex!=null){.....}

How i can change the icon in the Icon button

I am trying to build a whatsapp clone and when I was working on the changing the camera from front and back. I was trying to change the Icon in the Icon button but it was not changing
I will attach my code file below
Widget bottomIcon({Icon icon,double size,Function onpress}){
return IconButton(
icon: icon,
iconSize: size,
color: Colors.white,
onPressed: onpress,
);
}
Icon iconForcam=Icon(Icons.camera_rear);
#override
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return Container();
}
return MaterialApp(
home: Padding(
padding: const EdgeInsets.all(1.0),
child: Stack(
fit: StackFit.expand,
children: [
CameraPreview(controller),
Positioned(
bottom: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(width: 20.0,),
bottomIcon(icon: Icon(Icons.flash_on_rounded),size: 50.0),
SizedBox(width: 20.0,),
bottomIcon(icon: Icon(Icons.fiber_manual_record_outlined),size: 100.0),
SizedBox(width: 30.0,),
bottomIcon(icon: iconForcam,size: 50.0,onpress: (){
setState(() {
if(iconForcam == Icon(Icons.camera_front)){
iconForcam = Icon(Icons.camera_rear);
}else if(iconForcam == Icon(Icons.camera_rear)){
print('rearcam');
iconForcam = Icon(Icons.camera_front);
}
});
//toggleCamera();
}),
],
),
),
],
),
),
);
}
}
I have the doubt that in the if I can comapre two icons in the if Statement.
You can define a boolean variable
//Define
bool _isFront = true;
//Usage
bottomIcon(
icon: _isFront ?
Icons.camera_front : Icons.camera_rear,
size: 50.0, onpress: (){
setState(() {
_isFront = !_isFront;
});
//toggleCamera();
})
I tried like this and got that correct
//Defint
int _oldIndex=0;
Icon iconForcam=Icon(Icons.camera_rear);
//Inside code
bottomIcon(icon: iconForcam,size: 50.0,onpress: (){
setState(() {
if(_oldIndex == 0){
iconForcam = Icon(Icons.camera_rear);
_oldIndex = 1;
}else if(_oldIndex == 1){
//print('rearcam');
iconForcam = Icon(Icons.camera_front);
_oldIndex = 0;
}
});
toggleCamera(_oldIndex);
}),
You can store whether the front camera is on or not in shared_prefernces or database, use provider/stream/bloc to expose this value to UI. Now you can use this package to change icon with animation. Install this package to your flutter project, import it in the file, and then replace icon property of the camera button with the below code:
AdvancedIcon(
icon: Icons.camera_front,
secondaryIcon: Icons.camera_rear,
state: isFrontCameraOn ? AdvancedIconState.primary : AdvancedIconState.secondary,
)
Now the icon will automatically change depending on whether the front camera is on or not.
If you have problem with the database or provider part of this question just let me know.

GestureDetector and exclusive activation while calling onTap in a widget list

I'm trying to create a simple vertical scrolling calendar.
Problem is that I can't manage to find a way to reset back to previous state in case I tap on a new container.
Here's the code:
class CalendarBox extends StatelessWidget {
BoxProprieties boxProprieties = BoxProprieties();
Map item;
CalendarBox({this.item});
bool selected = false;
#override
Widget build(BuildContext context) {
return Consumer<Producer>(
builder: (context, producer, child) => GestureDetector(
onTap: () {
print(item['dateTime']);
selected = producer.selectedState(selected);
},
child: AnimatedContainer(
duration: Duration(milliseconds: 100),
color: selected == true ? Colors.blue : Colors.grey[200],
height: 80,
width: 50,
margin: EdgeInsets.only(top: 5),
child: Column(
children: [
Text(
'${item['dayNum']}',
style: TextStyle(
fontWeight: FontWeight.bold,
color: boxProprieties.dayColor(item['dateTime'])),
),
],
),
),
),
);
}
}
Here's the situation:
One way to achieve it is, create a model for boxes and keep a value current selected block, in your model you will have the index assigned to that block,
int currentSelected =1; //initial value
class Block{
int id;
..
.. // any other stuff
}
now in your code, the check modifies to
block.id == currentSelected ? Colors.blue : Colors.grey[200],
your on tap modifies to
onTap: () {
setState(){
currentSelected = block.id
};
},
If you want to prevent the rebuild of the whole thing every time you can use valueNotifire for current selected block. Hope this gives you an idea.

Button text color change

I'm building simple quiz app as a learning project. I'd like to change only clicked button color. Now it changes colors of all buttons. I've tried to make a list of colors, so every button could take its color from the list.
class _AnwserButtonsState extends State<AnwserButtons> {
Color color = Colors.black;
#override
Widget build(BuildContext context) {
return Container(
height: 200,
child: ListView(
children: widget.anwsers
.map(
(anwser) => RaisedButton(
child: Text(anwser, style: TextStyle(color: color)),
onPressed: () => onPressed(anwser),
),
)
.toList(),
),
);
}
onPressed(anwser) {
setState(
() {
if (anwser == widget.properAnwser) {
color = Colors.green;
} else {
color = Colors.red;
}
},
);
}
}
You need an id value. You could use index when use ListView.builder.
ListView.builder(
itemCount: widget.anwsers.length,
itemBuilder: (BuildContext context, int index) {
return Column(
children: <Widget> [
RaisedButton(
child: Text(widget.anwsers[index], style: TextStyle(color: color)),
onPressed: () => onPressed(widget.anwsers[index], index),
),
)
onPressed(anwser, index) {
setState(
() {
if (anwser == widget.properAnwser[index]) {
color = Colors.green;
} else {
color = Colors.red;
}
},
);
}
}
This could give you an idea. But my opinion is make a class that has answer, correct answer, color and id. Could be much easier and readable when use a class for this example.
You'll be better off using ListView.builder, since you'll be able to control each RaisedButton through its index in the List
Useful Links:
https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html
https://medium.com/#DakshHub/flutter-displaying-dynamic-contents-using-listview-builder-f2cedb1a19fb