Skip to content

Instantly share code, notes, and snippets.

@yasinarik
Last active December 23, 2020 09:12
Show Gist options
  • Save yasinarik/2891a686936fa9857dbf8e0fa3824ae7 to your computer and use it in GitHub Desktop.
Save yasinarik/2891a686936fa9857dbf8e0fa3824ae7 to your computer and use it in GitHub Desktop.
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