flutter :Inkwell not working in stack widget - flutter

I created a stack viewpager by this reference :
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
Positioned.fill(
child: Align(
alignment: Alignment.centerLeft,
child: SizedBox(
width: _itemWidth,
child: FractionallySizedBox(
child: InkWell(
onTap: () => debugPrint("clicked"), ///this part not works
child: PageViewItem(
index: _firstItemIndex,
width: _itemWidth,
url: model[_firstItemIndex],
),
),
),
),
),
),
SizedBox(
height: 250,
child: PageView.builder(
padEnds: false,
controller: _controller,
itemBuilder: (context, index) {
return Opacity(
opacity: index <= _firstItemIndex ? 0 : 1,
child: PageViewItem(
index: index,
width: _itemWidth,
url: model[index],
),
);
},
itemCount: model.length,
),
),
],
),
],
in this part :
InkWell(
onTap: () => debugPrint("clicked"), ///this part not works
child: PageViewItem(
index: _firstItemIndex,
width: _itemWidth,
url: model[_firstItemIndex],
),
),
onTap Not working because is under PageView.builder . do you have any idea to fix this issue?

That's because top widget in the stack, stack works as a layers, the last child in the children list will be the greatest zIndex one, so any widget below it is not accessible, you need to bring it to front to activate the click, swap the children and making the InkWell's positioned Widget the last child in the children will solve your issue
Stack(
children: [
SizedBox(
height: 250,
child: PageView.builder(
padEnds: false,
controller: _controller,
itemBuilder: (context, index) {
return Opacity(
opacity: index <= _firstItemIndex ? 0 : 1,
child: PageViewItem(
index: index,
width: _itemWidth,
url: model[index],
),
);
},
itemCount: model.length,
),
),
Positioned.fill(
child: Align(
alignment: Alignment.centerLeft,
child: SizedBox(
width: _itemWidth,
child: FractionallySizedBox(
child: InkWell(
onTap: () => debugPrint("clicked"), ///this part not works
child: PageViewItem(
index: _firstItemIndex,
width: _itemWidth,
url: model[_firstItemIndex],
),
),
),
),
),
),
],
),

Related

When keyboard open/close at that time ChangeNotifierProvider call multiple time

I am facing issue When keyboard open/close at that time ChangeNotifierProvider call multiple time so my full screen reload multiple time. In this widget I have attach video so widget is calling so many times then my instance is fail.
return Scaffold(
backgroundColor: ColorManager.colorBackgroundGray,
body: ChangeNotifierProvider<CreateRouteStep2ViewModel>(
create: (BuildContext context) => modelProvider,
builder: (context, snapshot) {
printValue(label: "ChangeNotifierProvider", value: "");
return Consumer<CreateRouteStep2ViewModel>(
builder: (context, provider, c) {
return SizedBox(
height: double.infinity,
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
provider.viewType == CreateRouteStep2ViewType.map
? SizedBox(
height: 300,
child: GoogleMapForCreateRoute(
modelProvider: modelProvider),
)
: const SizedBox(),
],
),
)
],
),
Expanded(
flex: 1,
child: Container(
color: ColorManager.colorWhite,
child: SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
physics:
const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 10),
itemCount: provider.listRouteName.length,
itemBuilder: (BuildContext context, index) {
return CreateStepsItem(
routeModel:
provider.listRouteName[index],
modelProvider: modelProvider,
index: index,
removeIndex: () {
// Todo Remove index from marker pin and location array.
modelProvider
.removeIndexFromPinAndList(index);
},
edtLocationNameFocus: () {
modelProvider.focusMap(index);
},
edtAudioFocus:
(mainPosition, subPosition) {
modelProvider.focusAudioComponent(
index, subPosition);
},
edtVideoFocus:
(mainPosition, subPosition) {
modelProvider.focusVideoComponent(
index, subPosition);
},
);
},
scrollDirection: Axis.vertical,
),
),
)),
Visibility(
visible:
MediaQuery.of(context).viewInsets.bottom == 0,
child: Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(
left: 24.0, right: 24.0, bottom: 20.0),
child: CommonButton(
onPressed: () {},
lable: AppStrings.constTourSpichern,
isEnable: false,
),
),
),
)
],
),
),
const SizedBox(
height: 20,
)
],
),
);
});
}),
);
Is there any widget behaviour is attach with keyboard?. If any one know that then please let me know.

How to control widget after listview in stack

I build a flutter app with ads as a carousel slider as a bottom layer of the stack widget, and I have I list view in the top layer of the stack widget
and when the list is scrolled vertically it overlays the ads on the screen.
now I have a problem with the carousel slider, I can't scroll it manually and I can't click any
how to solve it?
demo code:
Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Stack(
children: [
CarouselSlider(
options: CarouselOptions(
autoPlay: true,
),
items: imgList
.map((item) => Center(
child: Image.network(
item,
fit: BoxFit.cover,
)))
.toList(),
),
ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.only(top: 210),
itemBuilder: (context, index) => Container(
color: Colors.white,
child: Text(
'ITEM $index',
textAlign: TextAlign.center,
),
))
],
));
It depends on how you want to lay your widgets out.
If you want to keep the ads persistent (not to scroll away with list) then keep the layout like :
Scaffold(
body: Column(
children: [
CarouselSlider(),
Expanded(
child: ListView.builder(),
),
],
),
)
Using positioned widget inside stack you can easily position the widgets.
Maybe this will help you.
Stack(
children: [
Positioned(
top: 0,
bottom: 250,
left: 0,
right: 0,
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) => Container(
color: Colors.white,
child: Text(
'ITEM $index',
textAlign: TextAlign.center,
),
)),
),
Positioned(
bottom: 8,
right: 0,
left: 0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: CarouselSlider(
items: imgList.map((i) {
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.symmetric(horizontal: 5.0),
decoration: const BoxDecoration(color: Colors.amber),
child: GestureDetector(
child: Image.network(i, fit: BoxFit.fill),
onTap: () {
print("hey");
}));
},
);
}).toList(),
options: CarouselOptions(),
)),
),
],
)

ListView with Expanded when not scrollable

I want to make a menu with list of ExpansionTile and a footer, when the ExpansionTile is not expanded (not scrollable) the footer stay on the bottom of screen, but when the ExpansionTile is expanded (scrollable) the children of ExpansionTile push the footer out of screen.
For a clearer illustration, please see the following image
this my current code, but it's not a best way I think
checking is scrollable or not
checkIsScrollable(BuildContext context) {
if (Scrollable.of(context).position.minScrollExtent >=
Scrollable.of(context).position.maxScrollExtent) {
setState(() {
scrollable = false;
});
} else {
setState(() {
scrollable = true;
});
}
this the listview
ListView(
padding: EdgeInsets.symmetric(horizontal: 16),
children: [
LimitedBox(
maxHeight: !scrollable
? MediaQuery.of(context).size.height - 84
: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 24,
),
Text(
"Account".toUpperCase(),
style: ThemeApp.appBarTextStyle(),
),
SizedBox(
height: 24,
),
photoProfile(),
SizedBox(
height: 40,
),
menuProfile(),
SizedBox(
height: 40,
),
AccountContent.customerCare1(
context: context,
onExpansionChanged: (_) {
Future.delayed(
Duration(milliseconds: 101),
() {
checkIsScrollable(context);
},
);
},
),
AccountContent.sellWithUs(
context: context,
onExpansionChanged: (_) {
Future.delayed(
Duration(milliseconds: 101),
() {
checkIsScrollable(context);
},
);
},
),
AccountContent.customerCare2(
context: context,
onExpansionChanged: (_) {
Future.delayed(
Duration(milliseconds: 101),
() {
checkIsScrollable(context);
},
);
},
),
!scrollable
? Expanded(
child: Container(),
)
: Container(),
Container(
padding: EdgeInsets.symmetric(vertical: 16),
child: Column(
children: [
InkWell(
child: Row(
children: [
Container(
height: 18,
width: 18,
color: ThemeApp.borderColor,
),
SizedBox(width: 10),
Text(
"LOGOUT",
style: ThemeApp.subTitleTextStyle(),
),
],
),
onTap: () {},
),
SizedBox(
height: 20,
),
Row(
children: [
Expanded(
child: BorderedButton(
child: SvgPicture.asset(
"assets/icons/icon_whatsapp.svg",
color: ThemeApp.primaryColor,
),
onTap: () {
openWhatsapp();
},
),
),
SizedBox(
width: 17,
),
Expanded(
child: BorderedButton(
child: SvgPicture.asset(
"assets/icons/icon_instagram.svg",
color: ThemeApp.primaryColor,
),
onTap: () {
openInstagram();
},
),
),
SizedBox(
width: 17,
),
Expanded(
child: BorderedButton(
child: SvgPicture.asset(
"assets/icons/icon_mail.svg",
color: ThemeApp.primaryColor,
),
onTap: () {
openMail();
},
),
),
],
),
],
),
)
],
),
),
],
);
You should use a Column inside of LayoutBuilder and with a ConstrainedBox, set The minHeight of the Column to maxHeight of LayoutBuilder:
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
YourListView(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
),
YourFooter(),
],
),
),
);
},
);
}
I didn't get your question correctly but i guess you need too use Stack widget which always stays your footer on it's place even your page is Scrollable.
The footer you don't want to scroll, make the Column having two children and inside the column add another column and put the scrollable data inside that and wrap that with the SingleChildScrolView.
Column(
children: [
SingleChildScrollView(
child: Column(
children: [
// your scrollable data here
],
Column(
children: [
// Footer not scrollable
],),
],

Flutter - Container width and height fit parent

I have a Card widget which includes Column with several other Widgets. One of them is Container.
Widget _renderWidget() {
return Column(
children: <Widget>[
Visibility(
visible: _isVisible,
child: Container(
width: 300,
height: 200,
decoration:
BoxDecoration(border: Border.all(color: Colors.grey)),
child: ListView.builder(
itemCount: titles.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Icon(icons[index]),
title: Text(titles[index]),
),
);
},
)),
),
],
);
}
Here, if I don't specify width and height I get error. But, is there a way to make them to fit parent element?
EDIT
Full code:
return ListView(
children: <Widget>[
Center(
child: Container(
child: Card(
margin: new EdgeInsets.all(20.0),
child: new Container(
margin: EdgeInsets.all(20.0),
width: double.infinity,
child: Column(
children: <Widget>[
FormBuilder(
key: _fbKey,
autovalidate: true,
child: Column(
children: <Widget>[
FormBuilderDropdown(
onChanged: (t) {
setState(() {
text = t.vrsta;
});
},
validators: [FormBuilderValidators.required()],
items: user.map((v) {
return DropdownMenuItem(
value: v,
child: ListTile(
leading: Image.asset(
'assets/img/car.png',
width: 50,
height: 50,
),
title: Text("${v.vrsta}"),
));
}).toList(),
),
],
),
),
Container(child: _renderWidget()),
text.isEmpty
? Container()
: RaisedButton(
child: Text("Submit"),
onPressed: () {
_fbKey.currentState.save();
if (_fbKey.currentState.validate()) {
print(_fbKey.currentState.value.toString());
print(formData.startLocation);
getAutocomplete();
}
},
)
],
),
)),
),
),
],
);
}
Just set the height and width property of your Container to double.infinity
Solution Code:
Widget _renderWidget() {
return Column(
children: <Widget>[
Visibility(
visible: _isVisible,
child: Container(
width: double.infinity,
height: double.infinity,
decoration:
BoxDecoration(border: Border.all(color: Colors.grey)),
child: ListView.builder(
itemCount: titles.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Icon(icons[index]),
title: Text(titles[index]),
),
);
},
)),
),
],
);
}
You are using ListView inside Column which is why you need to specify height in your Container to prevent errors.
The best way is to use Expanded or Flexible as parent of your ListView
Expanded(
child: ListView.builder(...)
)
Update:
Widget _renderWidget() {
return Column(
children: <Widget>[
Visibility(
visible: _isVisible,
child: Expanded(
child: ListView.builder(
itemCount: titles.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Icon(icons[index]),
title: Text(titles[index]),
),
);
},
),
),
),
],
);
}

How to make ListView Items align at bottom of a container with a fixed height without using reverse in Flutter?

In my Flutter project, I have a container with a fixed height. Inside that container I have a Listview.
Here's the code-
return new Scaffold(
appBar: AppBar(
title: Text("All Values"),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
height: isLoading ? 50.0 : 0,
color: Colors.white70,
child: Center(
child: new CircularProgressIndicator(),
),
),
Expanded(
child: Container(
height: 350,
color: Colors.red,
alignment: Alignment.bottomLeft,
child:
new ListView.builder(
itemCount: data.length-8,
itemBuilder: (BuildContext cxtx, int index) {
return Padding(
padding: const EdgeInsets.fromLTRB(10, 0.0, 10, 0),
child: Container(
child: showCard(index, radius),
),
);
},
controller: _scrollController,
),
),),
],
),
resizeToAvoidBottomPadding: false,
);
The code outputs like below-
So, the problem is I want to align these items at bottom left of the container. I could have done that using reverse: true but I need the list items with the same sequence. So, I need suggestion how can I do that?
You need those items in a row or a column? Follow with a row possibility:
Try this:
return new Scaffold(
appBar: AppBar(
title: Text("All Values"),
),
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
if(isLoading)
Container(
height: 50.0 ,
color: Colors.white70,
child: Center(
child: new CircularProgressIndicator(),
),
),
Expanded(
child: Container(
height: 350,
color: Colors.red,
alignment: Alignment.bottomLeft,
child: new ListView.builder(
itemCount: data.length - 8,
itemBuilder: (BuildContext cxtx, int index) {
return Padding(
padding: const EdgeInsets.fromLTRB(10, 0.0, 10, 0),
child: Container(
child: Text('asdf'),
),
);
},
controller: _scrollController,
),
),
),
],
),
resizeToAvoidBottomPadding: false,
);
StoreConnector<_ViewModel, List<Message>>(
converter: (store) {
// check mark ,reverse data list
if (isReverse) return store.state.dialogList;
return store.state.dialogList.reversed.toList();
},
builder: (context, dialogs) {
// Add a callback when UI render after. then change it direction;
WidgetsBinding.instance.addPostFrameCallback((t) {
// check it's items could be scroll
bool newMark = _listViewController.position.maxScrollExtent > 0;
if (isReverse != newMark) { // need
isReverse = newMark; // rebuild listview
setState(() {});
}
});
return ListView.builder(
reverse: isReverse, // 反转列表,insert数据时,刷新到0,加载更多时,滚动偏移不变
controller: _listViewController,
itemBuilder: (context, index) => _bubbleItem(context, dialogs[index], index),
itemCount: dialogs.length,
);
},
)