How to change the width to the CupertinoSlidingSegmentedControl in Flutter - flutter

I am using the Cupertino design library for Android developing in Flutter. I want to change the width of the CupertinoSlidingSegmentedControl. This is what I have
final Map<int, Widget> myTabs = const <int, Widget>{
0: Text("Doctor"),
1: Text("Pacient")
};
CupertinoSlidingSegmentedControl(
groupValue: segmentedControlGroupValue,
children: myTabs,
onValueChanged: (i){
setState(() {
segmentedControlGroupValue = i;
});
},
),

Wrap it in SizedBox:
SizedBox(
width: double.infinity,
child: CupertinoSlidingSegmentedControl(...),
)

I achieved it by wrapping every Text widget with a Container of width double.maxFinite:
final Map<int, Widget> myTabs = const <int, Widget>{
0: Container(width: double.maxFinite, child: Text("Doctor"),),
1: Container(width: double.maxFinite, child: Text("Pacient"),),
};
Extra tip: if you want to change the height of CupertinoSlidingSegmentedControl's children (option buttons), you can set the height of the Container, or you can use padding property, like this:
Container(
padding: EdgeInsets.symmetric(vertical: 10.0),
width: double.maxFinite,
child: Text("Doctor"),
);

Related

How to change the value of 'selectedIndex' from one dart file to the other dart file using flutter GetX?

I have my custom Bottom Navigation Bar in one dart file, i.e. bottomnavbar.dart. And I have list of multiple screens(or pages) in my home.dart file. I am using an .obs variable to store my selected index value.
code from home.dart file:
var selectedIndex = 0.obs;
final screen = [
const Page1(),
const Page2(),
const Page3(),
const Page4(),
const Page5(),
];
...
body: screen[selectedIndex.value],
...
Even if I change the variable value (like 0.obs to 1.obs), page not changing, why??
next of, In my bottomnavbar.dart file, I have extracted and made a widget for my nav bar 'items'. And I have tried to wrap the item widget with Obx:
Widget bnbItems(String image, int index, double height) {
return Obx(
() => InkWell(
splashColor: Theme.of(context).brightness == Brightness.dark
? Colors.white.withOpacity(0.5)
: Colors.pink.withOpacity(0.5),
enableFeedback: true,
onTap: () => setState(() {
selectedIndex.value = index;
_controller.animateTo(index / 4);
// print(selectedIndex);
}),
child: Container(
alignment: Alignment.center,
width: 50,
height: 50,
child: Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Image.asset(
image,
height: height,
),
),
),
),
);}
and I am getting this error:
[Get] the improper use of a GetX has been detected.
You should only use GetX or Obx for the specific widget that will be updated.
If you are seeing this error, you probably did not insert any observable variables into GetX/Obx
or insert them outside the scope that GetX considers suitable for an update
(example: GetX => HeavyWidget => variableObservable).
If you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.
Can anyone give me the solution with some code and explanation? And also how will I be able to set a particular screen as the initial screen?
Replace on tap with this code
onTap: () {
selectedIndex.value = 1; // page index you want to view
},
then remove Obx(()=> on bnbItems widget
Widget bnbItems(String image, int index, double height) {
return InkWell(
splashColor: Theme.of(context).brightness == Brightness.dark
? Colors.white.withOpacity(0.5)
: Colors.pink.withOpacity(0.5),
enableFeedback: true,
onTap: () {
selectedIndex.value = 1; // page index you want to view
},
child: Container(
alignment: Alignment.center,
width: 50,
height: 50,
child: Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Image.asset(
image,
height: height,
),
),
),
);}
then use Obx(()=> wrapper on the body's widget
body: Obx(() => screen[selectedIndex.value]),
why you are using setState in GetX structure?
Try this code for onTap()
onTap: () {
selectedIndex.value = index;
_controller.animateTo(index / 4);
// print(selectedIndex);
},
to set initial screen use index no of that screen in var selectedIndex = 0.obs; instead of 0.

Is there any way to List the list views size in flutter?

I am new to flutter and trying to develop a version updation software. I need to show the version in a radio list. Is there any way to contain the list view in a container? Currently the list view is overflowing through the other widgets. I need to contain the list view between the text and the button. Is there any way to do it.The code the screenshot is given below
[![screenshot][1]][1]
Widget _createVersionRadioTiles(List<String> versions) {
var radioTiles = <Widget>[];
for (var version in versionList) {
var tile = Padding(
padding: const EdgeInsets.all(8.0),
child: RadioListTile<String>(
selected: selectedVersion == version,
tileColor: colorDarkGray,
// selectedTileColor: Colors.white,
value: version,
groupValue: selectedVersion,
onChanged: (String? value) {
setState(() {
selectedVersion = value!.toString();
});
},
title: Text(version),
),
);
radioTiles.add(tile);
}
return Column(
children: [
SizedBox(
height: 500,
width: 500,
child: ListView(children: radioTiles),
)
],
);
} ```
[1]: https://i.stack.imgur.com/qQxns.jpg
Wrap the RadioListTile with a Card widget. It will contain the ListTile in the container.
You can replace SizedBox with Container, and use clipBehavior: Clip.hardEdge to remove the overflows. see code below:
return Column(
children: [
Container(
height: 500,
width: 500,
clipBehavior: Clip.hardEdge,
child: ListView(children: radioTiles),
)
],
);

Flutter - Update items in a ListView

I'm trying to change the order of widgets in a ListView as follows:
Widgets List
List<Widget> widgets = [const Text("Widget 1"), const Text("Widget 2")];
ListView
ListView(children: widgets),
Text("$widgets")
Function
() {
widgets.shuffle();
setState(() {
widgets = widgets;
});
}
This way the order of widgets is changed in the TEXT but not in the list as I intended.
Any idea?
First solution: Add Key to List ListView like this:
ListView(
key: UniqueKey(),// <--- add this
children: widgets,
),
also in your Function you don't need to pass widgets again:
() {
widgets.shuffle();
setState(() {});
}
Second solution: you can use SingleChildScrollView and Column like this:
Padding(
padding: const EdgeInsets.all(20.0),
child: SizedBox(
height: 50,
width: 100,
child: SingleChildScrollView(
child: Column(
children: widgets,
),
),
),
),

Fill the available space in Listtile

I am new to the flutter and trying to fill the empty space in the listtile. I tried to use dense and visualDensity but with that, I am not getting the required result. Any support and suggestions will be appreciated.
here is my code and output:
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
SizedBox(
height: isLargeScreen ? 300 : 200,
child: ListView.builder(
physics: const ScrollPhysics(),
shrinkWrap: true,
itemCount: tags.length,
itemBuilder: (context, index) {
return CheckboxListTile(
value: tempSelectedTags.contains(tags[index].id),
onChanged: (e) {
setState(() {
if (tempSelectedTags.contains(tags[index].id)) {
tempSelectedTags.remove(tags[index].id);
} else {
tempSelectedTags.add(tags[index].id);
}
});
},
title: Text(
tags[index].name,
style: !tempSelectedTags.contains(tags[index].id)
? theme.textTheme.labelMedium?.copyWith(
color: ThemeConfig.colorTertiary)
: theme.textTheme.titleSmall?.copyWith(
color: ThemeConfig.colorTertiary),
),
);
}),
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(bottom:sdPaddingMedium),
child: SdPrimaryButton(
title: appLocalizations.btnApply,
onPressed: () {
viewModel.setTags(tempSelectedTags);
Navigator.pop(context);
},
),
),
],
)
Output can be seen here
There are two important things that determine the vertical layout in your column.
The whole box has a fixed size
SizedBox(
height: isLargeScreen ? 300 : 200,
There is a flexible space between the checkbox options and the bottom-right button
const Spacer(),
So if you want to remove the space, you can either
reduce the overall box size or
replace the const Spacer with a constant spacing like
SizedBox(height: 50) and also remove the SizedBox, so that the whole box will be content-sized

if statement in ListView flutter

I'm trying to have a responsive drawer that when the screen size is higher than X itemExtent is set to default, how could I add a if statement inside a ListView?
Widget drawer(context){
double _containerHeight = MediaQuery. of(context). size. height;
int _numberOfListTiles = 16;
return new Drawer(
child: Container(
height: _containerHeight,
color: const Color(0xff68778d),
child: ListView(
padding: EdgeInsets.zero,
itemExtent: _containerHeight/_numberOfListTiles,
children: [
],
),
)
);
}
I would like to do:
if(_containerHeight < 700){
itemExtent: _containerHeight/_numberOfListTiles,
}
The cleanest way (in my opinion) would be to instantiate your variable at the top of your drawer method as you did for the _containerHieght and _numberOfListTiles variables.
Your code would then look like that
Widget drawer(context) {
final double _containerHeight = MediaQuery.of(context).size.height;
final int _numberOfListTiles = 16;
double itemExtent;
if(_containerHeight < 700){
itemExtent = _containerHeight/_numberOfListTiles;
} else {
itemExtent = 100; // Default ?
}
return new Drawer(
child: Container(
height: _containerHeight,
color: const Color(0xff68778d),
child: ListView(
padding: EdgeInsets.zero,
itemExtent: _containerHeight / _numberOfListTiles,
children: [],
),
));
}