How to disable Bold Text set by iOS Accessibility setting in Flutter? - flutter

I know I should not disable any of the text and bold settings set on the device but I have a reason for it. I have disabled the text size by setting the textScaleFactor to 1 on a global level. But this does nothing to avoid the user from setting the Bold Text option that also changes the size of the text. How do I override that function also so even if the user sets it on the device there is no effect on the app? I have tried setting the fontweitgh on the text item using a TextStyle but that does also not stop the Bolding.

After checking Text widget I found out that it's using boldTextOverride from MediaQuery to change font weight of default text style provided to it. So I guess you can override it by wrapping your MeterialApp inside of a MediaQuery and assigning false to boldText and set useInheritedMediaQuery on MaterialApp to true to prevent it from creating another MediaQuery. Something like this:
return MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window).copyWith(boldText: false),
child: MaterialApp(
useInheritedMediaQuery: true,
),
);

Amir_P's answer is good but, when testing it out, I found that it breaks switching between dark mode and light mode in system, as the Flutter app would only apply system brightness after killing and reopening the app on iOS rather than immediately while the app is open. Therefore, I think that rather than wrapping MaterialApp in a MediaQuery, the following should be done:
return MaterialApp(
builder: (context, child) => MediaQuery(
data: MediaQuery.of(context).copyWith(boldText: false),
child: child!,
),
);
The builder property of the Material App is specifically for overriding things like this - see https://api.flutter.dev/flutter/material/MaterialApp/builder.html

Related

Flutter Image Hovering Overlay Effect

I am working on a flutter web project and I want to the following overlay effect over my image that whenever the cursor hovers over the image, a few buttons should show up, and the opacity of the image gets reduced (or blurred out) while hovering.
I have tried InkWell and GestureDectector but nothing seems to work.
This is basically what I am trying to achieve : Preview.
Try using hovering package to achieve the hovering effect on flutter_web.
First, import the package:
import 'package:hovering/hovering.dart';
Add a GlobalKey within your StatelessWidget:
final _key = GlobalKey<ScaffoldState>();
And then, use the HoverWidget:
HoverWidget(
hoverChild: Container(
height: 200,
width: 200,
color: Colors.green,
child: Center(child: Text('Hover Me..')),
),
onHover: (event) {
_key.currentState.showSnackBar(SnackBar(
content: Text('Yaay! I am Hovered'),
));
},
child: Container(
height: 200,
width: 200,
color: Colors.red,
child: Center(child: Text('Hover Me..')),
),
)
Check the example use case here
Hi Raj this is pretty simple
You just need to use Listener Widget which detects onPointerHover and update you app's state
Here is the api link follow it
Listener in Flutter
If any difficulties comment down below
Okay, over time I have tried many ways and would like to share my insight in case somebody else is looking for the same solution too.
So, the basic way to achieve this is to use the Hovering package.
Another way would be to use MouseRegion.
You can use the onEnter and onExit property of MouseRegion to detect when did the cursor entered and left the region/container you are trying to add a hove effect to.
You can use that to switch between your different app states.
Or it has onHover property as well, that basically tells that if the cursor is currently hovering that region or not you can use that too.
Note: I tried the Listener widget as well, but either I didn't understood it well, or it was too complicated to work with. Anyways, I couldn't achieve what I wanted.

Flutter: Changing Cards in Screen without rebuilding the whole page

I am pretty new to Flutter / Dart and right now, I have a problem. I have a homepage in my App and it displays an AppBar, a BottomNavigationBar and a body. The body is a simple card with content in it. The problem is: I need to be able to display three different cards, depending on the status I get from a server.
So there is the ActiveCard, the InactiveCard and the ErrorCard. The ErrorCard has a Button to go back to the InactiveCard and the ActiveCard as well as the InactiveCard should be wrapped in an Inkwell or similar to start a ride for example.
Now I am wondering: I am not sure how to implement all this. Can I just create three Stateless Widgets for each Card and depending on the server status just "replace" or "change" the body in my homepage? And where can I "control" the current status? Like I said, the Cards need to be clickable and "erase" themselves to make space for the following card (e.g: InactiveTrip gets clicked, now there should be the Card for ActiveTrip, because I started my trip and the user should see that my trip is currently active)
I cant provide code really, because so far I have not really something with will be even close to the result I expect.
Maybe you have some tips and packages I can use.
You can convert the statelessWidget to statefulWidget ans use setState() method.This is
recommended for small application but if your apps have more complexity then you have learn the state Management like provider,bloc pattern or Mvvm architechture.
yes, you can use statelessWidget for this purpose.
and you can use bloc pattern
to manage the page state.
I will use stateless for page and stream for the card content:
//Card model is your data modal
StreamController<Card> _streamController = StreamController();
Card _currentCard = /* default inactivate */;
StreamBuilder<bool>(
stream: _streamController.stream,
initialData: _currentCard,
builder: (BuildContext context, AsyncSnapshot<Card> snapshot) {
//return Container(/*content of your card*/);
},
),
//Everytime you need to change the card content, you sink the new value
_streamController.sink.add(_currentCard = /*new card data modal*/);

Flutter Floating Action Button with Dynamic Status

Putting the finishing touches on my first Flutter mobile app.
Another important ToDo: My Floating Action Button appears in the Top App Bar for every page, but i would like its status to change (enabled / disabled) depending on the current page. Is this possible? if so, any tutorials, resources, reference material and / or code examples fit for a novice, would be much appreciated.
Thanks!
Cool, you can use Visibility:
floatingActionButton: Visibility(
child: FloatingActionButton(...),
visible: false, // set it to false
)
Alternatively, you could use NotificationListener (more elegante but sophisticated).
Please check this example from another publication
Edit: maybe controlling it directly in onPressed.
According to official docs:
"If the onPressed callback is null, then the button will be disabled and by default will resemble a flat button in the disabledColor."
FloatingActionButton(
onPressed: shouldButtonBeDisabled() ? null : () => whatToDoOnPressed,
child: Text('blablabla')
);

Flutter Bloc Listener rebuilding even though there is no state change

I have an App which uses a bottom navigation bar to switch between pages. To do this, I'm using Bloc.
On one of the tab pages, I render a list with some items in it. This list is built when the State changes to SchedulesLoaded(see picture).
The problem I have is that when I'm changing pages using the bottom navigation bar(Which is using a completely different Bloc) the list in the picture is being rebuilt. The Listener is actually redrawing the widget without a change in the Bloc State it's listening to. I can't get my head around why it is happening. Does anyone have a clue?
I found this link discussing the issue, but I got nothing useful out of it.
For anyone looking at this now, you can call buildWhen after building Builder to provide some condition when to build.
From docs:
An optional [buildWhen] can be implemented for more granular control over how often [BlocBuilder] rebuilds. [buildWhen] will be invoked on each [cubit] state change. [buildWhen] takes the previous state and current state and must return a [bool] which determines whether or not the [builder] function will be invoked.
The previous state will be initialized to the state of the [cubit] when the [BlocBuilder] is initialized.
[buildWhen] is optional and if omitted, it will default to true.
Example:
return Scaffold(
appBar: AppBar(
title: BlocBuilder<Bloc, State>(
buildWhen: (p, c) => p.isEditing != c.isEditing,
builder: (context, state) {
return Text(state.isEditing ? 'Edit' : 'Create');
},
),

InheritedWidget update cause problems

I use the inherited widget at the top of my app to update my application whenever a new location is setted. This results in a refresh of my location coordinates at every possible place in my app.
However I also have a textfield. When i tap on the textfield some seconds later
the keyboard will be hidden by the update of the inherited widget.
Is there a way to prevent flutter to hide the keyboard or to reinitialize the state so that the update of the inherited widgets works together with my search field?
It should be also possible that when i enter some text that this trigger the inherited widget for a new update but the search bar and keyboard should stay open.
new TextField(
controller: _controller,
autocorrect: false,
autofocus: true
...
)
Without seeing all of your code, it's a little bit difficult to know what's going on.
My best guess though is that you're using a context somewhere above the TextField to register for updates from the inherited widget.
What I'd advise you to do though is go up the widget tree from your TextField and make sure that you're not using the inherited widget in a context anywhere above it. It might be worth putting some debug statements at the beginning of your build methods to determine exactly where the build is being triggered from (the inherited widget shouldn't trigger a rebuild immediately below it if you're using it right, but stranger things have happened).
This includes if you have something like this:
MyWidget extends StatelessWidget {
Widget build(BuildContext context) {
Location location = MyInheritedWidget.of(context).location;
return new Row(
children: [
new LocationDisplayer(location),
new TextField( ..... ),
],
);
}
}
The reason I say this is that from my understanding of how inherited widgets work; when it changes, whichever widgets whose contexts were used to get the inherited widget get rebuilt.
That means that even though your textfield technically isn't changing any properties, it might actually be a new textfield depending on how the build went (there's a bit of flutter magic I don't fully understand around how they decide when to make new vs re-build things) and therefore it hasn't requested focus.
Rather than having to write a bunch of new widgets to enclose whatever is using MyInheritedWidget, I believe you could use something like this:
MyWidget extends StatelessWidget {
Widget build(BuildContext context) {
return new Row(
children: [
new Builder(
builder: (context) {
Location location = MyInheritedWidget.of(context).location;
return new LocationDisplayer(location);
},
),
new TextField( ..... ),
],
);
}
}
If you're 100% sure you're not doing this anywhere, then you could go for the non-flutter way of doing things... your location class could expose a subscribe and unsubscribe method. All of the widgets where you're actually using the location call subscribe (which should also be stateful widgets) with a callback in their initState() and unsubscribe in their dispose(). The location class would simply call each of the callbacks instead of changing state as you're doing now, and within each of the callbacks you should call setState for the widget that actually shows the location.