Last active
December 23, 2020 09:12
-
-
Save yasinarik/2891a686936fa9857dbf8e0fa3824ae7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:get/get.dart'; | |
/* -------------------------------------------------------------------------- */ | |
/* READ HERE FIRST */ | |
/* -------------------------------------------------------------------------- */ | |
/// How can I use different instances of controllers for each new view (or route)? | |
/// | |
/// I can use: | |
/// Controller controller = Get.put(Controller(), tag: "uniqueTag"); | |
/// | |
/// However, then I have to use: | |
/// Controller controller = Get.find(tag: "uniqueTag"); | |
/// | |
/// inside each child widget class. So I need to pass the exact same "uniqueTag". | |
/* -------------------------------------------------------------------------- */ | |
/* main */ | |
/* -------------------------------------------------------------------------- */ | |
void main() async { | |
runApp(App()); | |
} | |
/* -------------------------------------------------------------------------- */ | |
/* App */ | |
/* -------------------------------------------------------------------------- */ | |
class App extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return GetMaterialApp( | |
home: MainView(), | |
); | |
} | |
} | |
/* -------------------------------------------------------------------------- */ | |
/* MainView */ | |
/* -------------------------------------------------------------------------- */ | |
/// This is the MainView. Let's think it like a PostScreen or ProfileScreen of Instagram, Twitter etc. | |
/// I would like to be able to navigate to the new instance of the MainView. | |
/// | |
class MainView extends StatelessWidget { | |
/// In order to differantiate the controller instances, I have to provide a "tag". | |
/// Indeed I want to use Uuid package which generates a random Uuid as a String. | |
/// Obviously, any other random string can be used. Like "Random().nextInt(9999);" | |
/// | |
/// So it may seem that I know the tag currently is "uniqueTag" but indeed, I won't be knowing it. | |
/// Also if I have to pass the tag as a variable, I have to do it for ALL children of the MainView. | |
/// Otherwise, I can't .find() the RIGHT controller instance. | |
Controller controller = Get.put(Controller(), tag: "uniqueTag"); | |
@override | |
Widget build(BuildContext context) { | |
return Obx(() { | |
return Scaffold( | |
body: Center( | |
child: Column( | |
children: [ | |
// Title | |
Container( | |
padding: EdgeInsets.all(16), | |
margin: EdgeInsets.all(16), | |
color: Colors.red, | |
child: Text("Example usage of GetX / Obx with a \"tag\" property."), | |
), | |
// Button | |
GestureDetector( | |
onTap: () { | |
Get.to(MainView(), preventDuplicates: false); | |
}, | |
child: Container( | |
color: Colors.pink, | |
margin: EdgeInsets.all(16), | |
padding: EdgeInsets.all(16), | |
child: Text("TAP --> Navigate to a new MainView"), | |
), | |
), | |
// Button | |
GestureDetector( | |
onTap: () { | |
controller.addItemToList(); | |
}, | |
child: Container( | |
color: Colors.blue, | |
margin: EdgeInsets.all(16), | |
padding: EdgeInsets.all(16), | |
child: Text("TAP --> Add item to list"), | |
), | |
), | |
// ListView | |
Container( | |
height: 200, | |
child: ListView.builder( | |
scrollDirection: Axis.horizontal, | |
itemCount: controller.someList.length, | |
itemBuilder: (_, i) { | |
return ListItemWidget(index: i); | |
}, | |
), | |
), | |
], | |
), | |
), | |
); | |
}); | |
} | |
} | |
/* -------------------------------------------------------------------------- */ | |
/* ListItemWidget */ | |
/* -------------------------------------------------------------------------- */ | |
/// ListItemWidget: This widget used in the ListView.builder() | |
/// When a new item added to the list (from Controller), | |
/// a new ListItemWidget is also created into the horizontal ListView. | |
/// | |
/// ListItemWidget shows the index and respective counter of the each item. | |
/// When pressed (or tapped), it increases only the respective counter of the particular ListItemWidget. | |
class ListItemWidget extends StatelessWidget { | |
final int index; | |
ListItemWidget({this.index}); | |
/// The problematic part for scaling my app. When putting this controller for the first time | |
/// inside each instance of MainView, I have to use a unique tag. | |
/// Indeed I want to use Uuid package which generates a random Uuid as a String. | |
/// Obviously, any other random string can be used. Like "Random().nextInt(9999);" | |
/// | |
/// However, ListItemWidget doesn't know what the "tag" is. I mean the "uniqueTag" | |
/// would be something like "ak38-sldjaf-9r84j-flfl" kind of Uuid, in real usage. | |
Controller controller = Get.find(tag: "uniqueTag"); | |
// Controller controller = Get.find(); | |
/// Controller controller = Get.find(); | |
/// If I was using it like that (without a "tag"), | |
/// it will give an error because there isn't a controller to find. | |
/// | |
/// So if I remove the "tag" while putting the controller (instantiating inside the MainView) it would work. | |
/// However, this time, when navigating to a new MainView, | |
/// all of the routes will share the same controller instance. This is "unwanted" for some of my use cases. | |
@override | |
Widget build(BuildContext context) { | |
// Obx used in order to make it reactive. | |
return Obx(() { | |
return GestureDetector( | |
behavior: HitTestBehavior.translucent, | |
onTap: () { | |
controller.increaseCounterAtIndex(index); | |
}, | |
child: Container( | |
margin: EdgeInsets.all(16), | |
height: 200, | |
color: Colors.yellow, | |
child: Column( | |
children: [ | |
Container( | |
padding: EdgeInsets.all(12), | |
child: Text("This is a ListItemWidget with index: $index"), | |
), | |
Container( | |
padding: EdgeInsets.all(12), | |
child: Text("Counter of this item: " + controller.someList[index].value.toString()), | |
), | |
Container( | |
padding: EdgeInsets.all(12), | |
child: Text("TAP to increase this counter"), | |
), | |
], | |
), | |
), | |
); | |
}); | |
} | |
} | |
/* -------------------------------------------------------------------------- */ | |
/* Controller */ | |
/* -------------------------------------------------------------------------- */ | |
///This is the plain simple controller class. No bindings were used. | |
class Controller extends GetxController { | |
var someList = <RxInt>[].obs; | |
// Adds a new list item. | |
addItemToList() { | |
someList.add(0.obs); | |
} | |
// Increases the respective counter of the particular item. | |
increaseCounterAtIndex(int index) { | |
someList[index].value++; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment