Flutter: Inflate drawer in webview - flutter

I am using a Drawer in a Scaffold menu. When I make the window in the web-view smaller, the Drawer vanishes and a small button appears.
which opens the menu from the left.
I would like to keep the drawer in this deflated version for full window size, but I get a static menu. How do I change that?
Code:
Scaffold(
drawer: DrawerMenu(),
...
)
class DrawerMenu extends StatelessWidget {
const DrawerMenu({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: [
Container(
padding: EdgeInsets.all(appPadding),
child: Image.asset("assets/images/mylogo.png"),
),
DrawerListTile(
title: 'Something',
svgSrc: 'assets/icons/Dashboard.svg',
tap: () {Navigator.pop(context);}),
DrawerListTile(
title: 'Somethingelse',
svgSrc: 'assets/icons/BlogPost.svg',
tap: () {Navigator.pop(context);}),
],
),
);
}
}`

The usage of drawer property in Scaffold is to show & hide the drawer.
To make the drawer always visible in full window size, try create as a seperate widget based on width of the screen
#override
Widget build(BuildContext context) {
var isBig = MediaQuery.of(context).size.width > 600.0; // set width threshold
return Scaffold(
appBar: ...
drawer: isBig ? null : DrawerMenu(),
body: isBig
? Row(
children: [
DrawerMenu(),
Expanded(
child: bodyContent,
),
],
)
: bodyContent;
);

Related

Adding item to widget dynamically doesn't update widget's height

When I add a widget to a sliding_up_panel widget dynamically after the initial load, the panel's height does not increase, meaning that the bottom of the panel gets cut off and I get the A RenderFlex overflowed by 27 pixels on the bottom. error.
What can I do to ensure the panel updates its height in this case please?
To Reproduce
Add a widget to the panel dynamically via the condition ? widget : widget logic. For example:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("SlidingUpPanelExample"),
),
body: Stack(
children: <Widget>[
Center(child: Text("This is the Widget behind the sliding panel"),),
SlidingUpPanel(
panel: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
myFirstVariable ? Text("This is a sliding Widget") : Container(),
mySecondVariable ? Text("This is another sliding Widget") : Container(),
],
),
)
)
],
)
);
}
Thanks so much!
the SlidingUpPanel widget doesn't adjust its height according to its children.
A solution to your problem would be add a SingleChildScrollView to your panel content and use the panelBuilder instead of the panel property.
The panelBuilder takes the burden of managing scrolling and sliding conflicts by providing you a controller that you can feed to your SingleChildScrollView, your code will change to be like the following :
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("SlidingUpPanelExample"),
),
body: Stack(
children: <Widget>[
Center(child: Text("This is the Widget behind the sliding panel"),),
SlidingUpPanel(
panelBuilder:(sc) => SingleChildScrollView(
controller: sc,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
myFirstVariable ? Text("This is a sliding Widget") : Container(),
mySecondVariable ? Text("This is another sliding Widget") : Container(),
],
),
)
)
],
)
);
}
Like this, you won't have any overflow issues, and when the content of the panel overflows the SingleChildScrollView will become scrollable.
hope this helps:
use a controller,
You can control the height of the panel depending on the items on the list (0.0 to 1.0). Ensure to update the UI once you add a new item.
use a List
This will solve the renderOverflow you mentioned
/// just for the example
List<Widget> items = <Widget>[];
//adding items
addItem() {
items.add(Container(
constraints: BoxConstraints(maxHeight: 200, minHeight: 200),
color: Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0),
));
/// if you know in advance the height of the widgets been rendered: 200
/// if you know in advance the height of the panel: 500, or context.size.height / 2 (which would be 50% of screen) asume 600
///
/// increase panel height panel according to the number of items
///
_pc.panelPosition =
(items.length * 200) / 600 > 1.0 ? 1 : (items.length * 200) / 600;
/// Hey
/// SET State after adding the item
/// to refresh UI
}
Widget _scrollingList(ScrollController sc) {
return ListView.builder(
controller: sc,
itemCount: items.length,
itemBuilder: (context, index) {
return items[index];
},
);
}
PanelController _pc = new PanelController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("SlidingUpPanelExample"),
),
floatingActionButton: FloatingActionButton(
onPressed: addItem,
),
body: Stack(
children: <Widget>[
Center(
child: Text("This is the Widget behind the sliding panel"),
),
SlidingUpPanel(
controller: _pc,
panelBuilder: (ScrollController sc) => _scrollingList(sc),
),
],
));
Plugin has the methods: minHeight and maxHeight to do the work. I think is not posible change it dynamically without set that attributes.

How to place a Progress bar over or inside an App Bar in Flutter?

Does anyone have any idea whether or not I can include a progress bar within an app bar? See screenshot of what I am trying to achieve. I am trying to reuse code and if I can create an App Bar with a Progress Indicator and then the same without. This will enable the users to complete this screen on signup and then EDIT this screen without the progress bar once they have an account. Is this even possible?
Your best option here is to use the 'bottom' property of the appBar widget it would look something like this
class HomeScreen extends StatelessWidget {
// this is to hide the progress inidecator once the account is created
bool isSignUpComplete = false;
#override
Widget build(BuildContext context) {
// this is to retrieve the device screen size
final Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
bottom: !isSignUpComplete ? PreferredSize(
child: LinearProgressIndicator(
backgroundColor: Colors.red,
),
preferredSize: Size(size.width, 0),
) : null,
),
);
}
}
if you want to make a progress indicator in the app bar you can use the progress indicator in the title of the app bar but :
if you want to make it such as the image I will tell you how you can make a custom app bar below the progress indicator like this
class Myapplication extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
body: SafeArea(
child: Column(
children: [
LinearProgressIndicator(),
Row(
children: [
Icon(Icons.arrow_back_outlined, color: Colors.black),
],
),
],
),
),
);
}
}
I solved this by putting the progress bar in the body, extended the body behind the app bar and then made the app bar transparent.
class SignUpForm extends StatelessWidget {
double progress = 0.22;
#override
Widget build(BuildContext context) => Scaffold(
backgroundColor: Colors.white,
extendBodyBehindAppBar: true,
appBar: BasicFormAppBar(),
body: Column(
children: [
SizedBox(height: 45),
Container(
child: LinearProgressIndicator(
value: progress,
valueColor: AlwaysStoppedAnimation(Colors.Blue),
backgroundColor: Colors.Grey,
),
), //column & scaffold are not closed in this snippet

Using BackdropFilter affects other widgets in a Row Widget - Flutter Web

I am having an issue when trying to blur a container in a Row widget when the user hovers over it (on Chrome). I have a custom widget called PanelLink, which is supposed to shrink in size and blur the background when the cursor goes over it. It works, but for some reason when hovering over one it also blurs every widget to the left not just itself.
FrontPage.dart:
import 'package:flutter/material.dart';
import 'package:website_v2/CustomWidgets/PanelLink.dart';
class FrontPage extends StatefulWidget {
FrontPage();
#override
_FrontPageState createState() => _FrontPageState();
}
class _FrontPageState extends State<FrontPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Website'),
centerTitle: false,
backgroundColor: Colors.blue[900],
),
backgroundColor: Colors.blueGrey[900],
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
PanelLink(false, 'assets/education.jpg'),
PanelLink(true, 'assets/about.jpeg'),
PanelLink(false, 'assets/projects2.jpg'),
],
),
),
);
}
}
PanelLink.dart:
import 'package:flutter/material.dart';
import 'dart:ui';
class PanelLink extends StatefulWidget {
PanelLink(this._blur, this.imageLoc);
final bool _blur;
final String imageLoc;
#override
PanelLinkState createState() => PanelLinkState(_blur, imageLoc);
}
class PanelLinkState extends State<PanelLink> {
PanelLinkState(this._blur, this.imageLoc);
bool isHovering = false;
bool _blur;
String imageLoc;
Widget build(BuildContext context) {
return Expanded(
child: InkWell(
onTap: () => null,
onHover: (hovering) {
setState(() => {isHovering = hovering});
},
child: Stack(children: [
AnimatedContainer(
duration: const Duration(milliseconds: 1000),
curve: Curves.ease,
margin: EdgeInsets.all(isHovering ? 20 : 0),
decoration: BoxDecoration(
color: Colors.black,
image: DecorationImage(
image: AssetImage(imageLoc), fit: BoxFit.cover)),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: isHovering ? 5 : 0, sigmaY: isHovering ? 5 : 0),
child: Container(
color: Colors.black.withOpacity(0.1),
)),
),
Text('Test')
]),
));
}
}
Here is a picture of the issue occurring. I am hovering the mouse over panel 2, but both panel 1 and 2 are blurred but not panel 3. If I hover over panel 1 only panel 1 is blurred. If I hover over panel 3, all of them are blurred.
I experimented by only making panel two have the BackdropFilter Widget, but panel 1 still got blurred when hovering over panel 2.
Since your using AnimatedContainer widget the problem might be it cant identify the difference between his child widget. Try adding a key value identifier
AnimatedContainer(
child: Container(
key: ValueKey("imageA"), //make sure that this is different on every widget, its better to passed some value here thats different on the other refactored widget
Try experimenting it might work for you
),
),

Adding DraggableScrollableSheet to the bottom of a Sliver page

I’m working on the concept that you can see on the screenshot below:
design concept
Note: the arrows are not the part of the UI, but were added to demonstrate the draggable functionality.
The screen has a SliverAppBar that displays location title, Sliver body that contains location description, and has a DraggableScrollableSheet (or a similar alternative).
When the location description is scrolled up, the title collapses.
When the DraggableScrollableSheet is scrolled up it expands to the full height of the screen.
I tried many times to put it together, but something is always off.
My last attempt was to add DraggableScrollableSheet as a ‘bottom sheet:’ in Scaffold. Since I have a BottomAppBar, it breaks the UI, and looks the following way:
current UI behavior
Scaffold
#override
Widget build(BuildContext context) {
return Scaffold(
body: body,
extendBody: true,
appBar: appBar,
bottomSheet: hasBottomSheet
? DraggableScrollableSheet(
builder:
(BuildContext context, ScrollController scrollController) {
return Container(
color: Colors.blue[100],
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text('Item $index'));
},
),
);
},
)
: null,
backgroundColor: Colors.white,
floatingActionButtonLocation: fab_position,
floatingActionButton: hasActionButton ? ScannerFAB() : null,
bottomNavigationBar: AppBarsNav(hasNavButtons: hasNavButtons));
}
Scaffold body
class LocationPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ScaffoldWithNav(
hasBottomSheet: true,
body: CustomScrollView(
slivers: <Widget>[
SliverBar(
title: "Location",
hasBackground: true,
backgroundImagePath: 'assets/testImage.jpg'),
SliverToBoxAdapter(
child: Text("very long text "),
),
SliverPadding(
padding: EdgeInsets.only(bottom: 70),
),
],
),
);
}
}
BottomAppBar FAB
class ScannerFAB extends StatelessWidget {
#override
Widget build(BuildContext context) {
return FloatingActionButton(
child: WebsafeSvg.asset('assets/qr-code.svg',
color: Colors.white, height: 24, width: 24),
);
}
}
The FAB jumps, the content is hidden.
When I set a fixed-sized container, the content comes back, but the FAB is still living its own life:)
current UI behavior2
If anyone has any idea how to solve this issue/those issues please share, I’ll be very grateful!
You can try to add another Scaffold on current body and put the DraggableScrollableSheet inside it. Then the DraggableScrollableSheet won't affect the FAB outside.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Scaffold(
body: body,
bottomSheet: ... // move DraggableScrollableSheet to here
),
...
floatingActionButton: ... // keep FAB here
...
)
You can use Stack into Body, for example:
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children. [
SingleChildScrollView(),
DraggableScrollableSheet(),
]
),
...
floatingActionButton: ... // keep FAB here
...
)

flutter move floatingActionButton up 50 pixels

Is it possible to move the floatingActionButton up by 50 pixels?
I have a floatingActionButton in an App that uses firebase_admob and the Ads Banner is overlapping on top of the floatingActionButton.
How does one set the floatingActionButton to be 50 pixels from the bottom of the screen?
From the documentation of floatingActionButton I can not seem to pick out how to position the button.
Wrap your FloatingActionButton inside a Padding and add the size you want:
floatingActionButton: Padding(
padding: const EdgeInsets.only(bottom: 50.0),
child: FloatingActionButton(
child: Icon(Icons.remove),
onPressed: () => null,
),
),
It's simple.
class Test extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(),
floatingActionButton: Align(
child: FloatingActionButton(onPressed: null),
alignment: Alignment(1, 0.7)),
);
}
}
Use Alignment, as everything is a Widget in Flutter.