Please,
I'm beginning with Get and my initial problem is to create a BottomNavigationBar. I 'm trying create with Statelwess Widget and using Get for control the indexes. Its happening error when to clock on options.
Is it possible ?
Anyone did it anytime
class ProfileScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: GetBuilder<ProfileController>(
init: ProfileController(),
builder: (s) => IndexedStack(
index: s.selectedIndex,
children: <Widget>[
Body(),
Body(),
Body(),
],
),
),
bottomNavigationBar: SuperFaBottomNavigationBar(),
);
}
}
class SuperFaBottomNavigationBar extends StatelessWidget {
const SuperFaBottomNavigationBar({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetBuilder<ProfileController>(
init: ProfileController(),
builder: (s) => BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Inicio'),
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text('Pesquisa'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Perfil'),
),
],
currentIndex: s.selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: (index) => s.onItemTapped(index),
/* currentIndex: Get.find<ProfileController>().selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: Get.find<ProfileController>().onItemTapped, */
),
);
}
}
class ProfileController extends GetController {
final _selectedIndex = 0.obs;
set selectedIndex(value) => this._selectedIndex.value = value;
get selectedIndex => this._selectedIndex.value;
onItemTapped(int index) {
this.selectedIndex(index);
update();
}
}
Hi, you can't put init twice. Why are you putting a GetBuilder in the bottomBar?
You just need to wrap indexedStack in a GetBuilder, and that's it.
I guess this do exactly what you want
class BottomNavigationPageController extends GetxController {
static BottomNavigationPageController get to => Get.find();
final currentIndex = 0.obs;
List<Widget> pages = [
Tab1(),
Tab2(),
Tab3(),
];
Widget get currentPage => pages[currentIndex.value];
void changePage(int _index) {
currentIndex.value = _index;
}
}
class BottomNavigationPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return obx(
() => Scaffold(
body: BottomNavigationPageController.to.currentPage,
bottomNavigationBar: BottomNavigationBar(
currentIndex: BottomNavigationPageController.to.currentIndex.value,
onTap: BottomNavigationPageController.to.changePage,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Container(),
),
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Container(),
),
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Container(),
),
],
),
),
);
}
}
Hijacking this a little, but how would you add transition effects and/or router to BottomNavigationBar?
Hijacking this a little, but how would you add transition effects and/or router to BottomNavigationBar?
you say transition between tabs or each tab having multiple pages? for the second case you can use nested navigation. for transition between tabs on bottomNavibationBar I guess you can't add a transition effect.
Transition animations between tabs on BottomNavigationBar. Or implementing routing instead of programmatic thisPage[isIndex] type of solution. It's not only transition animations that are missing with BottomNavigationBar, but also Android back button handling. Routing would solve a lot of that. Was wondering if there's an elegant solution to that with Get.
I searched a lot and found no way to do tabs navigation as routes. For android back button, which action do you want? if is for trancking the tabs like a stack you can do exactly that, save the index on a stack every time change tab, and poping it when press the back button, but i guess this is not a good aproach.
You made 2 mistakes when creating your model, one was to try to access a set as if it were a method, and another was to initialize the same controller 2 times. Here is an example of your code working:
class ProfileScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: GetBuilder<ProfileController>(
init: ProfileController(),
builder: (s) => IndexedStack(
index: s.selectedIndex,
children: <Widget>[
Center(
child: Text(s._selectedIndex.string),
),
Center(
child: Text(s._selectedIndex.string),
),
Center(
child: Text(s._selectedIndex.string),
),
],
),
),
bottomNavigationBar: SuperFaBottomNavigationBar(),
);
}
}
class SuperFaBottomNavigationBar extends StatelessWidget {
const SuperFaBottomNavigationBar({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetBuilder<ProfileController>( // init only first time
builder: (s) => BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Inicio'),
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text('Pesquisa'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Perfil'),
),
],
currentIndex: s.selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: (index) => s.onItemTapped(index),
/* currentIndex: Get.find<ProfileController>().selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: Get.find<ProfileController>().onItemTapped, */
),
);
}
}
class ProfileController extends GetxController {
final _selectedIndex = 0.obs;
set selectedIndex(value) => this._selectedIndex.value = value;
get selectedIndex => this._selectedIndex.value;
onItemTapped(int index) {
this.selectedIndex = index; // The set method is accessed this way, you have confused it with methods.
update();
}
}
Well, as it was misuse, and I presented the corrected and compile example, I am closing this. If you encounter a problem with Get, you can open another issue.
Most helpful comment
You made 2 mistakes when creating your model, one was to try to access a set as if it were a method, and another was to initialize the same controller 2 times. Here is an example of your code working: