I am working on a Flutter Application where I need to show an AdMob's Banner Ad. I have noticed that the banner overlaps my list view. I tried to search for the solution but I did not find anything much useful.
One solution I found is to provide fix margin of 50px at the bottom. I feel a little uncomfortable with this solution as I read somewhere that the screen size may affect this solution.
Also when I put a fake bottom bar then it also overlaps my bottom tab bar and bottom sheets.
Please see the below image for more details.
Thank you for your time.
I found one solution for you my cast Banner bottom Flutter Application little bit padding. Fix it with below code.
var paddingBottom = 48.0;
new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Name',
home: new MyHomePage(
title: "NMame",
),
builder: (context, widget) {
final mediaQuery = MediaQuery.of(context);
return new Padding(
child: widget,
padding: new EdgeInsets.only(bottom: paddingBottom),
);
},
routes: <String, WidgetBuilder>{
'/HomeScreen': (BuildContext context) =>
new MyHomePage(title: 'UPSC Question Papers')
})
handle when the app is not getting loaded Ads
if(event == MobileAdEvent.failedToLoad){
setState(() {
paddingBottom = 0.0;
});
}
Thank you
If you're using a Scaffold Widget, try using the persistentFooterButtons: parameter. Tutorial here: http://cogitas.net/show-firebase-admob-banner-ad-in-flutter/
Set following params in the banner ad show() function:
bannerAd = Utils().myBanner
..load()
..show(
anchorType: AnchorType.bottom,
anchorOffset: 55.0);
And also need to set margin: const EdgeInsets.only(bottom: 55) on the container
Related
i'm still new in using flutter driver in testing, but as far as i know there are few identifiers that we can use to locate / identify elements, like By Text, By Type, etc
But the problem is, the app that i want to test doesn't have the identifier that i can use to locate them (please correct me if i'm wrong).. the widget code of the app looks like this
Widget _buildNextButton() {
return Align(
alignment: Alignment.bottomRight,
child: Container(
child: IconButton(
icon: Icon(Icons.arrow_forward),
onPressed: () => _controller.nextPage(),
),
),
);
}
where that widget is on a class that extends StatefulWidget.
How can i locate that icon in my test script and click it? can i use something like this? And what type of finder should i use? (byValueKey? bySemanticLabel? byType? or what?)
static final arrowKey = find.byValueKey(LoginKey.nextButton);
TestDriverUtil.tap(driver, arrowKey);
We have text and value checks here in Flutter Driver but if you don't have that you can always go the the hierarchy of app.
what I mean by hierarchy is so button has fix or specific parent right?
Let's take your example here, We have Align > Container > IconButton > Icon widget hierarchy which will not be true for others like there might be IconButton but not with the Container parent.
or StreamBuilder or anything that we can think of.
Widget _buildNextButton() {
return Align(
alignment: Alignment.bottomRight,
child: Container(
child: IconButton(
icon: Icon(Icons.arrow_forward),
onPressed: () => print("clicked button"),
),
),
);
}
This hierarchy should be atleast ideal for top bottom or bottom top approach.
Now what I mean by Top to bottom approach is Align must have IconButton and for bottom to up approach we are saying IconButton must have Align widget as parent.
Here i have taken top down approach so what I'm checking from below code is finding IconButton who is decendent of Align Widget.
also i added firstMatchOnly true as I was checking what happens if same hierarchy appears for both so
test('IconButton find and tap test', () async {
var findIconButton = find.descendant(of: find.byType("Align"), matching: find.byType("IconButton"), firstMatchOnly: true);
await driver.waitFor(findIconButton);
await driver.tap(findIconButton);
await Future.delayed(Duration(seconds: 3));
});
to check for multiple IconButtons with same Align as parent, we need to have some difference like parent should be having Text view or other widget.
find.descendant(of: find.ancestor(
of: find.byValue("somevalue"),
matching: find.byType("CustomWidgetClass")), matching: find.byType("IconButton"), firstMatchOnly: true)
usually I go something like above where I have split the code in seperate file and check for that widget.
But ultimately find something unique about that widget and you can work on that.
**In Lib directory dart class for connecting that widget**
class Testing extends StatelessWidget {
Testing();
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: YourClass(), // Next button containing class that need to test
);
}
}
**In Test directory**
testWidgets('Next widget field test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(Testing());
// find Widget
var buttonFind = find.byIcon(Icons.arrow_forward);
expect(buttonFind, findsOneWidget);
IconButton iconButton = tester.firstWidget(buttonFind);
expect(iconButton.color, Colors.blue);
});
I'm building an apps, that contain floatingactionbutton which I made with my own custom, when it pressed it shows 3 menu icons below it.
There are 2 problems:
When the orientation change to landscape, and we press floatingactionbutton it won't show instead of it will show when we press long, continue no 2
In current landscape it shows with long press like I said in no 1, and when we back again to portrait it need long press again to make it show
I've been trying some ways to make it fix, but it still doesn't work.
Here's the code and screenshot
When portrait menu show up
When changing to landscape, menu icons are missing and need long press to make it show
for floatingActionButton
floatingActionButton: OrientationBuilder(
builder: (BuildContext context, Orientation orientation){
return orientation == Orientation.landscape
? _buildMenu(context)
: _buildMenu(context);
},
),
_buildMenu() that call floatingActionButton
Widget _buildMenu(BuildContext context){
final icons = [ Icons.swap_vert, Icons.check_circle_outline, Icons.filter_list ];
var nowOrientation = MediaQuery.of(context).orientation;
var b = Container(
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints){
return OverlayBuilder(
showOverlayTrue: true,
overlayBuild: (BuildContext overlayContext){
RenderBox box = context.findRenderObject() as RenderBox;
final center = box.size.center(box.localToGlobal(const Offset(0.8, 0.8)));
return new Positioned(
top: Offset(center.dx, center.dy - icons.length * 35.0).dy,
left: Offset(center.dx, center.dy - icons.length * 35.0).dx,
child: new FractionalTranslation(
translation: const Offset(-0.5, -0.6),
child: FabIcons(
icons: icons,
),
),
);
},
);
},
),
);}
To make it simple in viewing I put some code on github
OverlayBuilder Class https://github.com/ubaidillahSriyudi/StackOverflowhelp/blob/master/OverlayBuilderClass
Fabicons Class
https://github.com/ubaidillahSriyudi/StackOverflowhelp/blob/master/FabIcons
Thanks so much to someone that could help it
Happens because every time you change orientation, your FloatingActionButton rebuilds and loses state.
You should find a way to save the state of FabIcons widget.
Simple solution :
Constructing FabIcons widget with
icons,
iconTapped;
These variables should be saved in the Parent Widget, so every time you call _buildMenu(context); you pass in those variables
I am having an issue trying to location information on how to set the initial size and position of a Flutter desktop applications window.
Upon searching, I came across some code within the C++ files, but does anyone know if there is a way to set this from within Dart, or can it only be done in the C++ files?
A method of modifying by platform code. You can modify these two properties through the code in this path:windows/runner/main.cpp.
Here is the code you want to modify:
Win32Window::Point origin(kFlutterWindowOriginX, kFlutterWindowOriginY);
Win32Window::Size size(kFlutterWindowWidth, kFlutterWindowHeight);
The initial value is here:windows/runner/window_configuration.cpp
It can currently only be done from the platform code, because the window is created before the engine.
See this issue for a possible solution to this problem; if you are familiar enough with the platform toolkits on the platform(s) you are developing for, you could implement the solution described there manually in your own runner(s), by adding a custom MethodChannel and changing the initial creation details of the native windows.
This package can be helpful: Bitsdojo Window.
It makes it easy to customize and work with your Flutter desktop app window on Windows, macOS and Linux.
Watch the tutorial to get started.
Features of this package:
Custom window frame - remove standard Windows/macOS/Linux titlebar and buttons
Hide window on startup
Show/hide window
Move window using Flutter widget
Minimize/Maximize/Restore/Close window
Set window size, minimum size and maximum size
Set window position
Set window alignment on screen (center/topLeft/topRight/bottomLeft/bottomRight)
Set window title
There is a very simple way to do this. With this library desktop_window, you can set the window size and so on. Examples are as follows
import 'package:desktop_window/desktop_window.dart';
import 'package:flutter/material.dart';
void main() async {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: const Text('desktop_window example app'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
child: Text("setMinWindowSize(300,400)"),
onPressed: () async {
await DesktopWindow.setMinWindowSize(Size(300, 400));
},
),
RaisedButton(
child: Text("setMaxWindowSize(800,800)"),
onPressed: () async {
await DesktopWindow.setMaxWindowSize(Size(800, 800));
},
),
],
),
),
),
);
}
}
In my case i need arrange window on right bottom corner and i hotfix CreateAndShow(...) method(${dir project}\windows\runner\win32 window.cpp) like this:
bool Win32Window::CreateAndShow(const std::wstring& title,
const Point& origin,
const Size& size) {
Destroy();
const wchar_t* window_class =
WindowClassRegistrar::GetInstance()->GetWindowClass();
const POINT target_point = {static_cast<LONG>(origin.x),
static_cast<LONG>(origin.y)};
HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
double scale_factor = dpi / 96.0;
int monitor_width = GetSystemMetrics(SM_CXSCREEN);
int monitor_hight = GetSystemMetrics(SM_CYSCREEN);
int new_x_position = monitor_width - size.width;
int new_y_position = monitor_hight - size.height;
HWND window = CreateWindow(
window_class, title.c_str(), WS_POPUP|WS_VISIBLE|WS_SYSMENU,
Scale(new_x_position, scale_factor), Scale(new_y_position, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this);
if (!window) {
return false;
}
return OnCreate();
}
I want a standard AppBar when the app starts, however, once the user begins scrolling I want the app bar to slide up and off the screen. However, when that happens, the status bar (on iOS) doesn't have a background. I don't want to set a constant background directly to the status bar using something like flutter_statusbarcolor because that leaves a solid color, which isn't a widget.
The only solution I have right now is to just keep the AppBar pined.
However, what I really want to do is what Google News does. The AppBar slides up almost all the way, however, it stays under the app bar with some opacity.
How Google News does it:
Is there any way to do this with Flutter and SliverAppBar without doing it a hacky way? The only thing I'm thinking is doing it with a stack, however, how would I know how to keep it under the status bar, as Android already has some opacity under the status bar.
Scroll widgets in flutter have controllers that inform what's going on with the scroll. You can get how much the sliver has been scrolled and change it's opacity, content and size accordingly. It's not going to be simple though, but take a look at ScrollController, used by the CustomScrollView.
I used OrientationBuilder widget to listen to changes in orientation, as when there are changes to the orientation the status bar hight can change.
Then I used FlutterStatusbarManager package to get the height of the status bar. FlutterStatusbarManager.getHeight is a future so it needed to be wrapped with a FutureBuilder
Here is the full example code
import 'package:flutter/material.dart';
import 'package:flutter_statusbar_manager/flutter_statusbar_manager.dart';
class FixedStatusbarBackground extends StatelessWidget {
final Widget child;
const FixedStatusbarBackground({Key key, this.child}) : super(key: key);
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
child,
OrientationBuilder(
builder: (context, Orientation orientation) => FutureBuilder<double>(
future: FlutterStatusbarManager.getHeight,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Container(
height: snapshot.data,
color: Theme.of(context)
.appBarTheme
.color
.withOpacity(.7) //Colors.white.withOpacity(.7),
);
} else {
return Container();
}
}),
),
],
);
}
}
The child widget that is passed in is the entire CustomScrollView.
I have a Flutter app that is functioning properly in all respects except when I select a TextField (or TextFormField). When I select the TextField, the cursor blinks in the TextField, but I can't type anything AND all other buttons like the floatingActionButton and the back button in the AppBar quit working. Essentially, the app appears to be frozen, but I don't get any error messages.
After numerous attempts to fix the problem in two different pages that contain FocusNodes and TextEditingControllers, I went back to square one by incorporating a new page with code straight from Flutter's website, but the TextField in this barebones code still locks up the app.
import 'package:flutter/material.dart';
class EventDetailForm extends StatefulWidget {
static const String routeName = "/events/event-detail-form";
#override
_EventDetailFormState createState() => _EventDetailFormState();
}
class _EventDetailFormState extends State<EventDetailForm> {
final myController = TextEditingController();
#override
void dispose() {
myController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Event Detail')),
body: Padding(
padding: const EdgeInsets.all(16),
child: TextField(
controller: myController,
)),
floatingActionButton: FloatingActionButton(
onPressed: () {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(myController.text),
);
});
},
child: Icon(Icons.text_fields),
),
);
}
}
Unfortunately, I am not getting any error messages. The cursor just blinks in the TextField and everything else loses function and I have to quit and restart. I am not sure what else I should be considering. Does anyone have any ideas on what might be causing this?
Simulator -> Device -> Erase All Content And Settings works for me.
Had same problem when I upgraded Xcode to ios 13.1. I switched to a different simulator, and the problem went away.
This maybe late, but it happened to me too just today. I also changed the channel to beta but unfortunately did not work too. Apparently what worked for me is when I restarted the simulator after I put back the channel to stable.
I had the same bug, solved by switching to the beta channel of Flutter.
In your terminal use
flutter channel beta
flutter upgrade
About channels you can read here https://github.com/flutter/flutter/wiki/Flutter-build-release-channels
I did not change channel, a simple flutter upgrade was enough to fix this problem. I also closed Android Studio and all simulators and when I restarted, the problem was gone.
I think I am late to the party but the issue still exists in 2021.
I tried all the solutions but couldn't fix it. Whatever I was typing in TextField or TextFormField or autocomplete_textfield, the characters were not visible.
I fixed it by opening the Widget as a showGeneralDialog() instead of using Navigator.of(...). Here is the sample code.
await showGeneralDialog(
barrierColor: AppStyle.primaryColor.withOpacity(0.3),
transitionBuilder: (context, a1, a2, widget) {
return Transform.scale(
scale: a1.value,
child: Opacity(opacity: a1.value, child: WidgetScreenToOpen()),
);
},
transitionDuration: Duration(milliseconds: 500),
barrierDismissible: true,
barrierLabel: 'Label',
context: context,
pageBuilder: (context, animation1, animation2) {
return Container();
}).then((result) {
return result;
});