onTap replace widget from another file flutter - flutter

Say my App() contains some widget and to make the code look pretty, i have created classes for child widgets. Now these child widgets contain onTap functions which are supposed to replace a widget on App(), so how do i approach this type of problem ?

Some code of what you're doing would be useful or where you're trying to "replace a widget".
If by replace you mean show a different widget in the place of another then you just use a boolean to decide which one to show. These are the steps I would follow to implement this.
Make the widget in your App() stateful and create a member variable boolean called showingOriginalWidget = true;
In your child widget classes take in a Function in the parameter called onSwapWidget.
In your onTap function in your child widget call onSwapWidget()
In your App() supply the widget that's performing this action with your Function to call back to
See below
childWidget(onSwapWidget: (){
setState((){
// toggle the original widget state
showingOriginalWidget = !showOriginalWidget;
});
});
Where you're showing your widgets add a condition so that you show either one depending on the value.
example
...
child: showingOriginalWidget ? originalWidget() : swappedOutWidget()
...
That should do the trick.

Related

How to find a child widget of certain type by context in Flutter?

I have a Statefull/Stateless widget I need to check if the widget contains certain type of widget as its child.
Example:
Statefull Widget -> Container() => Column() => [Text(), Expanded() -> ListView()]
Here I need to check if the Statefull widget consists ListView() through its context...
I think what you are looking for is byType method.
This will find widgets by searching for widgets with a particular type.
So in your case, you'll have something like this:
expect(find.byType(ListView), findsOneWidget);

How to make individual GetxControllers for reusable widget

I am trying to replace the use of Stateful widget with Getx. Most cases, I do not need it, however, when I am trying to create a list of cards widget, I find it hard to not to use the Stateful widget.
Obx(() {
getxA.updateA(name);
return Text(getxA.a());
})
RxString a = 'aaa'.obs;
updateA(String name) {
a(name);
}
When I have this Obx() - Text Widget inside the List Widget, it causes the error because each Text widget triggers updateA(String name) function.
It looks like every card is sharing one GetxController (getxA). Is there any way that to have each Text widget have its own GetxController? Or is it not possible in this case and I have to use the Stateful widget?

How use onTap function of treeview library flutter

Hi I am using this pubdev package https://pub.dev/packages/tree_view/example . My problem is that when I use the onTap function the expanded does not work, I was checking the library and I noticed that it is because of this code, however I do not know how to solve it or if there is another way to access that function from the library from the widget. Any ideas
If you notice it when the onTap function is different from empty, the toggleExpanded() function does not apply
So any ideas??
You need to control the expansion yourself using the startExpanded property of the TreeView widget.
First, you have a boolean variable (say _startExpanded) in your StatefulWidget that hold the state of the expansion and you can set it the default state (for instance, false).
bool _startExpanded = false;
Then, you pass the variable to your TreeView widget:
TreeView(
startExpanded: _startExpanded,
children: _getChildList(documentList),
),
To expand, you call:
setState((){
_startExpanded = true;
});
To close, you call:
setState((){
_startExpanded = false;
});

When using GetX observables, which UI widgets need to be wrapped in Obx?

To learn GetX I created a simple controller class:
class MyDataController extends GetxController {
RxString aString = ''.obs;
void updateString(String s) {
aString.value = s;
}
}
aString's value is displayed in two classes: the AppBar (not discussed here) and another class in which aString is both set and displayed:
class Level1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
final MyDataController controller = Get.find();
final textController = TextEditingController();
return Column(
children: [
TextField(
controller: textController,
onChanged: (_) {
controller.updateString(textController.text);
},
),
Text(controller.aString.value),
],
);
}
}
I'm confused about which widgets need to be wrapped in an instance of Obx().
If I wrap only the Text() (display widget) in an Obx instance, it's updated when the TextField() (input widget) changes. And if I wrap only the TextField() widget in an Obx instance, I get an error message:
The following message was thrown building Obx(has builder, dirty,
state: _ObxState#019a0):
[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.
Everything seems clear: widgets displaying state must be wrapped in Obx() instances to display updated variables. That makes perfect sense. And widgets that change state don't need to be wrapped in Obx() instances.
I'm confused, though, because if I wrap both widgets in separate Obx() instances, I get the error message. But if I wrap the entire Column() in an Obx() instance, the text is properly updated when the TextField() changes. ... What am I missing in my understanding?
You got it all up to the point when you wrapped the Text widget in an Obx. In actual fact it is best to wrap only the smallest widget that would need updating in Obx, the Text widget in this case.
Let me explain what happened the cases in which you tried testing it out:
Case 1: When you wrapped only the Text widget in Obx (The best thing to do)
This case happen to be the best and most encouraged approach. In this scenario when the value of aString changes in the controller (MyDataController) the Obx is notified to re-build only the affected Text widget from scratch, and this is exactly the aim of GetX.
Case 2: When you wrapped both the Text && the TextField widget in Obx (This will throw an error).
In this case you have wrapped both the Text and TextField widget in Obx, we can therefore let case 1 account for the Text widget.
Now, moving unto the TextField widget, an error will occur because the TexField widget is not in any way dependent on any obs-value (observable value).
It is important to note that in the onChanged callback provided to the textField, the method updateString called on the controller have no effect whatsoever on TextField's parameter and thus this leads GetX to throw an error since you are trying to forcibly update/re-build a widget that needs no rebuilding.
Case 3: When you wrapped the whole column in Obx (Will not throw an error but not the best practice).
In this case the widget will be built with no error whatsoever since the Text widget (which is inside the Column) is dependent on the value of aString. So, let's see what happens when the method updateString is called.
When the updateString is called the whole Column is re-built (along with the TextField and the Text widgets and this action will as well cause the value in the Text widget to be updated.
Now, you can see why this third case can be detrimental, if you try wrapping your whole app in Obx, your whole app will then have to get re-built (which can really affect your app's performance negatively. Of course GetX has a way of disallowing that and thus it throws an error when you try wrapping an HeavyWidget in Obx or GetX.

Flutter: display dynamic list

I've got a widget that displays a classes' list, but that list changes (the content changes) over time by other elements and interactions of the program. How can the DisplayListWidget detect this? Do the elements that change this list have to communicate with the displaylistwidget?
EDIT: I'm familiair with stateful widgets and setState () {}. It's just that the data changes in the background (e.g. by a timer) so there's no reference from bussiness logic classes to widgets to even call setState.
If you would like to notify (rebuild) widgets when data changes, check out provider package.
There are some other options:
BLoC (Business Logic Component) design pattern.
mobx
Redux
Good luck
Try wrapping the display widget in a state widget, and then whenever you update the list, call setState(() { //update list here })
ex.
// this is the widget that you'd nest directly into the rest of your tree
class FooList extends StatefulWidget {
FooListState createState() => FooListState();
}
// this is the state you will want to call setState on
class FooListState extends State<FooList> {
Widget build(BuildContext context) {
return DisplayListWidget [...]
}
}
I would recommend following this flutter tutorial where they dynamically update a list
And to learn more about StatefulWidgets and States check this out: https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html