Hide circle progress inside RefreshIndicator - flutter

I am trying to use RefreshIndicator in my flutter app so i use this builtin library:
child: SafeArea(
child: RefreshIndicator(
onRefresh: () => _onRefreshData(),
child: Column(
children: <Widget>[
Expanded(...
In my page i have 2 list.when this page appear I shows a dialog and I get data from server and show these data inside of lists:
Future<void> _onRefreshData() async {
getMyChan();
}
void getMyChan() async {
Future.delayed(Duration.zero, () => _showProgressDialog());
_myChannel = await MyToolsProvider().getMe(_testToken);
getTools();
setState(() {
_closeDialog();
});
}
Now i want to use RefreshIndicator to refresh my lists but i have a question:
I just want to use swap of RefreshIndicator and don't need circle progress because as you can see i am using progressDialog in getMyChan() method so i do not need circle progress.
How can i hide circle progress inside RefreshIndicator?

Unfortunately (or not), the RefreshIndicator indicator don't have an option to hide the RefreshProgressIndicator widget present inside.
The only way is to copy the Widget in your project and replace the RefreshProgressIndicator with an empty Container here :
https://github.com/flutter/flutter/blob/f3d95cd734ad23b7f9e15e7d0bc182d40965e05f/packages/flutter/lib/src/material/refresh_indicator.dart#L459

Related

Flutter Tooltip on One Tap / Hold Down

My app has several textfields and I want to have a tooltip so that users know can see the definition of each field.
I came across this answer, but it wasn't helpful: Flutter Tooltip on One Tap. Therefore I decided to try and fix it myself.
Here is how to do it:
First add GestureDetector as child for Tooltip,
TooltipTriggerMode.manual for triggerMode.
add onTapDown, onTapUp, and onTapCancel as follows
Widget build(BuildContext context) {
final tooltipkey = GlobalKey<TooltipState>();
return Tooltip(
key: tooltipkey,
message: message,
triggerMode: TooltipTriggerMode.manual, // make it manual
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (_) => _onTapDown(tooltipkey), // add this
onTapUp: (_) => _onTapUpAndCancel(tooltipkey), // add this
onTapCancel: () => _onTapUpAndCancel(tooltipkey), // add this
child: Icon(EvaIcons.questionMarkCircleOutline),
),
);
}
and the helper functions shown inside the code above:
void _onTapDown(GlobalKey<TooltipState> tooltipkey) {
tooltipkey.currentState?.ensureTooltipVisible();
}
void _onTapUpAndCancel(GlobalKey<TooltipState> tooltipkey) {
tooltipkey.currentState?.deactivate();
}
Hooray, it works. Now you can hold down the icon to display the tooltip immediately instead of holding it down for a while (the default configuration of tooltip).

How to check if screen is fully loaded?

Problem: One of screen in my app has bunch of network images that are being fetched from an API. When user navigates to that screen some images load faster than others, hence users sees a screen that is not fully loaded.
Expected behaviour: I want to show a CircularProgressIndicator until all the network images are fully loaded.
P.S. Below code doesn't do what I wanted, as it executes the function while images are still loading.
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => yourFunction(context));
}
Also I am using SvgPicture.network from flutter_svg package.
final Widget networkSvg = SvgPicture.network(
'https://site-that-takes-a-while.com/image.svg',
semanticsLabel: 'A shark?!',
placeholderBuilder: (BuildContext context) => Container(
padding: const EdgeInsets.all(30.0),
child: const CircularProgressIndicator()),
);
Maybe this could help Flutter image preload

How to programmatically call multiple widget under a stack in flutter

I've a screen with several buttons and I would like to show a sliding panel for each button (passing some information to show in the panel).
I've used this widget:
https://pub.dev/packages/sliding_up_panel
I would like to understand how I can show a widget that is under a Stack passing programmatically some information once I click on a specific button.
It is possible?
Following a brief snipped of code in which we can see the Stack that contains the SlidingPanel. I would like to be able to show the Sliding panel clicking on a specific button and passing an information to it programmatically.
The only solution that I've found up to now is adding all the possible sliding panel to the Stack and then based on the click on the button showing only the one I need, but I hope there is a better way to do this.
Thank you
return Stack(
children: [
Scaffold(
.....
),
SlidingUpPanel(
panelController: panelController,
nameTEController: nameTEPanel,
platform: 'Instagram',
)
]
Just populate your list of Widgets inside a List. If you are using a StatefullWidget, then just call setState(() => )
You could do something like this:
List<Widget> _myWidgetList = [];
[...]
return Stack(
children: _myWidgetList);
List<Widget> _buildMyWidgetList() {
final List<Widget> tmpList = [];
tmpList..add(Widget1)
..add(Widget2);
setState(() => _myWidgetList = tmp);
}
Then just call your buildWidgets functions on the Buttons.
Another way would be to use Bloc: https://pub.dev/packages/flutter_bloc

flutter - android back button does not call onWillPop of WillPopScope

I would like to exit my application. I have implemented a WillPopScope, but it looks like the onWillPop function is not being called at all. I tried many things like swap WillPopScope with Scaffold, changing the return value of the function, but it just looks like it is not working as expected.
My code:
Future<bool> _willPopCallback() async {
exit(0);
// await showDialog or Show add banners or whatever
// then
return true; // return true if the route to be popped
}
return Scaffold(
appBar: MyAppBar(
leading: DrawerAction(),
title: Text(AppLocalizations.of(context).textCapitalized('home_page')),
onSearch: (searchTerms) => this.search(searchTerms, context),
),
body: new WillPopScope(
onWillPop: _willPopCallback, // Empty Function.
child: //my screen widgets
I am not sure if this is a bug I should report to flutter or I am doing something wrong. Happy to provide more code on request.
I have tried:
exit(0);
Navigator.of(context).pop();
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
Thanks in advance!
I managed to solve my problem and I think it is a very particular case, but it still might be helpful to someone.
TL;DR: Ensure that you dont have multiple Scaffolds in your widgets
I was using IndexedStack in my menu navigator, obviously wrapped with a Scaffold. The pages of the stack had Scaffold as well, and with this combination WillPopScope was not working neither in the navigator page neither in its stack pages. I solved by removing all the Scaffolds in the stack pages and having only one in the controller. In this way I managed to use WillPopScope correctly.
First of all do not ever use exit(0). It may be fine in Android environment, but apple won't allow the app on app store if it programmatically shuts down itself.
Here in the docs of onWillPop it clearly mentions that function should resolves to a boolean value.
Future<bool> _willPopCallback() async {
// await showDialog or Show add banners or whatever
// then
return Future.value(true);
}
This only works if your current page is the root of navigation stack.
Modify the code to return WillPopScope, and have Scaffold as a child.
return new WillPopScope(
onWillPop: _willPopCallback,
child: new Scaffold(
//then the rest of your code...
i know i am too late, but the problem still exists.
maybe i found the right solution.
make sure you are passing MaterialApp to the runApp method like this:
runApp(MaterialApp(home: MyFirstPage()));
this works for me for all my application's widgets. if you do not want to use it just wrap your widget in MaterialApp but do not forget that in every MaterialApp instance a new Navigator is created, so for me i just created one as above and in all my pages i just used scaffold and everything is ok.
I also stuck in the same problem but after a lot of searching, I found that this error is related to my parent container.
return WillPopScope(
onWillPop: () => _onWillPop(),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
...
],
),
Another possible reason: my implementation of _onWillPop() was throwing an exception and the code inside _onWillPop() was ignored. The exception did not appear in the log.
I resolved it by using a TRY/CATCH inside _onWillPop(), and handling all code paths.
I have been battling this and initially thought it had something to do with the nested Scaffold widgets as the OP had mentioned in their answer above. I tested this though and still had the same problem. The answer for me was that my root Scaffold was a child of a Navigator. It worked as soon as I removed the Scaffold as a child of the Navigator. Thankfully I didn't need a Navigator at the root level anyway as I was using an IndexedStack which has multiple Navigator widgets in it.
This is a late answer but I hope can helps someone.
The #Gicminos answer was right. If you have nested scaffold willPopScope not worked.
I wanna add some info in case you need.
I have a Scaffold containing bottomNavBar. Every Item in bottomNav is a Navigator which children are Scaffold (you notice that in this moment there are scaffolds innested).
This is my MainScaffold containing the bottom bar:
...
_navigatorKeys = {
TabItem.tabOne: tabOneKey,
TabItem.tabTwo: GlobalKey<NavigatorState>(),
};
...
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
//check if there are pages in stack so it can pop;
var navigatorState =(_navigatorKeys.values.toList([_selectedIndex]as GlobalKey<NavigatorState>).currentState;
if ( navigatorState !=null) {
if (!await navigatorState
.maybePop()) return true;
}
return false;
},
child: Scaffold(
body: SafeArea(
child: IndexedStack(
index: _selectedIndex,
children: _pages,
),
),
resizeToAvoidBottomInset: true,
bottomNavigationBar: Container(...)
...
}
If you wrap with a WillPopScope widget also your children like in the code below:
#override
Widget build(BuildContext context) {
var t = AppLocalizations.of(context)!;
return WillPopScope(
onWillPop: () async {
debugPrint("test");
return true;
},
child: Scaffold(...)
}
both onWillPop will be called (in main scaffold and children scaffold).
In the example the first one will pop only if can (there are page in navigator stack), the second one will be called immediatly after the first one and it will call the debugPrint function before returned
I my case onWillPop didn't call because I had a custom AppBar and tried to call Navigator.pop(context) instead of Navigator.maybePop(context).

which widget can be used to explain functionality in app

I want to explain something in my app and add a widget which looks like a notification or chat. I want this widget to be visible for some time and then get dismissed. I tried using tooltip but it is visible only when I click it.
Which widget can I use?
The Dart package intro_views_flutter is what you need, but one of its main limitations is that it is displayed on full screen, if that is not an issue to you, then you should take a look at it. Or you can use a showDialog method inside a Future function this way :
Future showNotification() async {
showDialog<String>(
context: context,
child: new AlertDialog(
title: Text('Note!') ,
contentPadding: const EdgeInsets.all(16.0),
content: //any widget you want to display here
),
);
await new Future.delayed(const Duration(seconds: 5), () {
Navigator.of(context).pop(); // this will dismiss the dialog automatically after five seconds
}
}
then when you need it call:
showNotificaion();