Single Child Scoll View doesn't scroll up screens when soft keyboard appears in Flutter Webview Plugin - flutter

Here is my main.dart
class _MyHomePageState extends State {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: const WebviewController(),
),
),
);
}
Does anyone who know this answer???
plz.. tell me your solutions...
I used Single child scroll view to scoll up my screens when soft keyboard appears in android..
Also use Adjust Resizing but doesn't work.
IOS device has no problem but only in android device...
ps. If you needed, I'll attach webview_controller.dart too..

I also cant make it scrollable using SingleChildScrollView only but I found a workaround to do that. I kept a flag when keyboard opens and modified my widgets accordingly. Here is the example.
class _MyHomePageState extends State {
bool _keyboardOpen = false;
#override
void initState() {
super.initState();
FocusManager.instance.primaryFocus?.unfocus();
}
#override
Widget build(BuildContext context) {
_keyboardOpen = MediaQuery.of(context).viewInsets.bottom == 0;
return Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Visibility(
visible: _keyboardOpen,
child: const SizedBox(
height: 10,
),
),
),
),
);
}
Here you can make non-visible sizedBox when keyboard opens, you can also decrease the text's size when keyboard appears like this.
Text('your text', textAlign: TextAlign.center,
style: TextStyle(fontSize: (_keyboardOpen)? 22 : 9, fontWeight:
FontWeight.w500)
),
Let me know if this helps.

Related

Flutter Card child content height is larger than its parent

I'm trying to use a GridView to handle displays for multiple Card, each Card contains of an Image. Unfortunately it turns out that the Image is taking a larger height than its parent (see attached picture for the details).
I'm pretty new to Flutter layout so any ideas why this is happening and how I can resolve this? I want the layout to be something like this:
Display 2 cards on each line.
The Card width or height should not be fixed.
The Image height should be scaled according to its width.
class SquadSelectionScreen extends StatelessWidget {
final List<Team> teams;
const SquadSelectionScreen({super.key, required this.teams});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Squads'),
),
body: GridView.count(
crossAxisSpacing: 10,
crossAxisCount: 2,
padding: const EdgeInsets.all(16),
children: teams
.map(
(team) => SquadView(team: team),
)
.toList(),
),
);
}
}
class SquadView extends StatelessWidget {
final Team team;
const SquadView({super.key, required this.team});
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
context.push('/squads/${team.code}');
},
child: Card(
elevation: 1,
child: Column(
children: [
Image(
image: NetworkImage(team.imageUrl),
),
const SizedBox(
height: 8,
),
Center(
child: Text(team.name),
),
],
),
),
);
}
}
Using GridView.count has a very visible drawback, namely the size of the aspect ratio of the grid will always be one (1:1 or Square) and can't be changed.
So if you look at the code above, you can't set an image with the same aspect ratio because the text will sink.
The first suggestion for me if you still want to use GridView.count is
Wrapping your Image with AspectRatio that has value higher than one (example set Ratio to 4/3, 5/3, 16/9, or landscape looks). Note: 4/3 = is higher than 1, 16/9 = is higher than 1, etc..
Then wrap the Text Widget with Expanded()
Example code:
class SquadView extends StatelessWidget {
final Team team;
const SquadView({super.key, required this.team});
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {},
child: Card(
elevation: 1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
AspectRatio(
aspectRatio: 4/3, // you can set the value to 16/9 or anything that result is higher than one
child: Image(
image: NetworkImage(team.imageUrl),
fit: BoxFit.cover, // set How the image looks to Fit
),
),
const SizedBox(
height: 8,
),
Expanded(
child: Center(
child: Text(team.name, overflow: TextOverflow.ellipsis),
),
),
],
),
),
),
);
}
}
I suggest you try GridView.builder or another GridView. You can look at the documentation here
or this third package this will be good for to try flutter_staggered_grid_view. The flutter_staggered_grid_view is more flexible to create GridView with various size.

RenderListWheelViewport object was given an infinite size during layout

I am using ListWheelScrollView Widget to give a wheeling effect to my list item but getting the error as mentioned. I just want to show Stacked Items with some image and texts in individual list item and give a 3D Wheeling effect to them.
Below is my code ->
class ExploreWidget extends StatefulWidget {
#override
State<StatefulWidget> createState() => _ExploreState();
}
class _ExploreState extends State<ExploreWidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: null,
body: Column(
children: <Widget>[
_header(),
_exploreList()
],
)
);
}
Widget _header(){
return SizedBox(
height: 200,
width: 800,
);
}
Widget _exploreList(){
return ListWheelScrollView.useDelegate(
itemExtent: 75,
childDelegate: ListWheelChildBuilderDelegate(
builder:(context,index){
return Container(
height: 500,
width: 800,
child: Stack(
children: <Widget>[
Image(image: AssetImage(
_products[index].image
)),
Text(_products[index].name,style: Style.sectionTitleWhite,),
Text('70% off',style: Style.cardListTitleWhite,),
],
),
);
}
),
);
}
}
The error was occuring due to the way _exploreList() widget is implemented. This widget is wrapped inside Column which doesn't scroll in itself. Moreover, you are returning a ScrollView that has an infinite size. Hence it was throwing the said error. To resolve this issue, wrap _exploreList() widget inside Flexible which takes only minimum available space to render and scroll. Working sample code below:
body: Column(
children: <Widget>[
_header(),
Flexible(
child: _exploreList()
)
],
)
Now you should be able to use WheelScrollView properly.

Color of a widget inside a Stack is always slightly transparent

I display a custom-made bottom app bar in a Stack because of keyboard padding reasons. The custom widget is fully opaque as it should be until it's a child of a Stack in which case, the content behind it starts to be visible since the color's opacity somehow changes.
As you can see, it's only the "main" color that's transparent. Icons remain opaque.
This is the build method of my custom BottomBar widget which is then just regularly put into a Stack. I have tried using a Material and even a simple Container in place of the BottomAppBar widget but the results are the same.
#override
Widget build(BuildContext context) {
return BottomAppBar(
color: Colors.blue.withOpacity(1),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(MdiIcons.plusBoxOutline),
onPressed: () {},
),
Text('Edited 11:57'),
IconButton(
icon: Icon(MdiIcons.dotsVertical),
onPressed: () {},
),
],
),
);
}
Can you interact with the BottomAppBar ? It looks like an order problem. Try to put the BottomAppBar as last in the Stack children.
Note that BottomAppBar doesn't have a constant size, if you did not add it to Scaffold bottomNavigationBar named parameter has a size if this is not null. Below is peace of code in Scaffold dart file:
double bottomNavigationBarTop;
if (hasChild(_ScaffoldSlot.bottomNavigationBar)) {
final double bottomNavigationBarHeight = layoutChild(_ScaffoldSlot.bottomNavigationBar, fullWidthConstraints).height;
bottomWidgetsHeight += bottomNavigationBarHeight;
bottomNavigationBarTop = math.max(0.0, bottom - bottomWidgetsHeight);
positionChild(_ScaffoldSlot.bottomNavigationBar, Offset(0.0, bottomNavigationBarTop));
}
You can even develop your own Widget without BottomAppBar but if you want things like centerDocked and things like circular notched, you will have to do more stuff (anyway you have flexibility to custom design the way you want).
Here is a simple example to do that(one way to do that):
import 'package:flutter/material.dart';
class CustomBottomBar extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 50),
color: Colors.greenAccent, // if you want this color under bottom bar add the margin to list view
child: ListView.builder(
itemCount: 100,
itemBuilder: (_, int index) => Text("Text $index"),
),
),
Positioned(
bottom: 0,
child: Container(
color: Colors.amber.withOpacity(.5),
width: MediaQuery.of(context).size.width,
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(4, (int index) => Text("Text $index")), // you can make these clickable by wrapping with InkWell or any gesture widget
),
),
),
],
),
);
}
}

Interact with lower widget in Stack

I have a Stack that has a GoogleMap and an overlapping SingleChildScrollView, filled with Widgets.
However, the SCSV now block the map, and I can't interact with it? What I am trying to do, is a map as "upper" widget on the page and then the scrollview can be scrolled over the map.
Stack(children: <Widget>[
Container(
height: 400,
child: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition:
CameraPosition(target: _center, zoom: 13.0),
)),
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(0, 300, 0, 0),
child: Container(
decoration: BoxDecoration(color: Colors.white),
child: Column(children: _offers))))
])
Any idea how I can make this happen? Other suggestions than my existing layout are more than welcome, as long as the results is the same :)
I think you had the same problem as I solved in my application. I created a stack of two interactive widgets in my photo preview — pan/draw — and wanted to allow users to switch the interaction between them. As they are all full-screen widgets, I need to make the "top" one be sometimes transparent for the user's clicks, depends on a boolean flag (panEnable in my case).
I solved that with the IgnorePointer widget:
class PhotoPreviewScreen extends StatefulWidget {
_PhotoPreviewScreen createState() => _PhotoPreviewScreen();
}
class _PhotoPreviewScreen extends State<PhotoPreviewScreen> {
bool panEnable = true; // THAT IS THE enable/disable flag
final String imagePath = 'my_image.jpg'; // image to show and interact with
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
InteractiveViewer( // This is the "lower widget"
panEnabled: panEnable, // THAT IS THE enable/disable flag
scaleEnabled: panEnable, // THAT IS THE enable/disable flag
boundaryMargin: EdgeInsets.all(double.infinity),
minScale: 1,
maxScale: 16,
child: Image.file(
File(imagePath), // imagePath — local path to an image in Preview
),
),
Center(
child: Stack(
children: <Widget>[
IgnorePointer(
ignoring: panEnable, // THAT IS THE enable/disable flag
child:
SomeFullScreenActionWidget( // AN UPPER ACTION
onPressed: () => <SOME ACTION>,
), // SomeFullScreenActionWidget
), // IgnorePointer
// <here might be some "passive" widgets that are not use pointers
], // children of Stack widget
), // Stack
), // Center
IconButton( // wrap it in Align/Positioned or any other widget to arrange the widgets switch button on the screen
iconSize: 33.0,
color: Colors.white,
icon: Icon(!panEnable? CupertinoIcons.pencil_outline: CupertinoIcons.pencil_slash), // I use some stylish icons, you may choose standard
onPressed: () {
setState(() {
panEnable = !panEnable; // HERE IS THE SWITCH enable/disable flag
}); // SetState
}, // onPressed
), // IconButton
], // children of Stack
), // Stack
); // Scaffold
That is important to mention that I use a StatefulWidget class to use setState(). In the case of a StatelessWidget class, it would not work.

Flutter ReorderableListView doesn't work with TextFields

The widgets in my ReorderableListView are essentially TextFields. When long pressing on a widget, after the time when the long press should cause the widget to "hover," instead the TextField receives focus. How can I make the drag & drop effect take precedence over the TextField? I would still like a normal tap to activate the TextField.
The code below demonstrates my issue.
I also tried to use this unofficial flutter_reorderable_list package. (To test this one, replace the Text widget on this line of the example code with a TextField.)
I'm willing to use any ugly hacks to get this working, including modifying the Flutter source code!
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final children = List<Widget>();
for (var i = 0; i < 5; i++) {
children.add(Container(
color: Colors.pink, // Only the pink area activates drag & drop
key: Key("$i"),
height: 50.0,
child: Container(
color: Colors.grey,
margin: EdgeInsets.only(left: 50),
child: TextField(),
),
));
}
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: ReorderableListView(
children: children,
onReorder: (oldIndex, newIndex) => null,
),
),
),
);
}
}
You need to do multiple things in there to fix this.
First disable the default handler in ReorderableListView by setting buildDefaultDragHandles: false in its properties.
Wrap you child widget inside ReorderableDragStartListener widget like this
ReorderableDragStartListener(
index: i,
child: Container(
color: Colors.grey,
margin: EdgeInsets.only(left: 50),
child: TextFormField(initialValue: "Child $i", ),
),
),
Then inside this ReorderableDragStartListener wrap your child in InkWell and AbsorbPointer. Then use FocusNode to focus inner TextField on single tap.
Like this
InkWell(
onTap: () => _focusNode.requestFocus(),
onLongPress: () {
print("long pressed");
},
child: AbsorbPointer(
child: TextFormField(initialValue: "Child $i", focusNode: _focusNode,),
),
),
You need to create multiple FocusNode for all the items in list. You can do this by using List or by simpling creating a new FocusNode inside the loop.
Complete code example here https://dartpad.dev/?id=e75b493dae1287757c5e1d77a0dc73f1