I'm Having a List view in my app, and the problem is it does not scroll when touching the middle of the list view but only when touching the edges of the list.
and here is my View Code.
Widget build(BuildContext context) {
const horizontalPadding = EdgeInsets.symmetric(horizontal: 10);
final controller = Get.put(UnitsListController());
return Scaffold(
appBar: AppBar(
),
body: Padding(
padding: horizontalPadding,
child: GetX<UnitsListController>(
builder: (controller) {
return controller.isBusy.value
?const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.grey,
color: Colors.blue,
strokeWidth: 5,
),
): ListView.builder(
shrinkWrap: true,
itemCount: controller.unitsList.length,
itemBuilder: (context, index) {
var item = controller.unitsList[index];
String address ='${item.country},${item.state},${item.area},${item.block},${item.plot},'
'${item.lane},${item.buildingName},${item.buildingNumber}';
return GestureDetector(
onTap: () {
controller.selectedUnit = item;
controller.onUnitTap();
},
child: AppUnitCard(
type: item.type,
address: address,
rooms: item.roomsNum??0,
rent: item.rent,
bathrooms: item.bathsNum,
space: item.unitSpace,
),
);
},
);
}),
),
);
}
Note
that i was wrapping the Scaffold body with a SingleChildScrollView and removed it both ways it didn't work.
Wrap the listview with a SingleChildScrollView and add NeverScrollableScrollPhysics to the listview
SingleChildScrollView (
child : ListView.builder(
shrinkWrap: true,
physics : NeverScrollableScrollPhysics()
)
),
ListView doesn't scroll when wrapped by Column & SingleChildScrollView on all the browsers on Android. For further details and code examples check the link:
https://github.com/flutter/flutter/issues/80794#issuecomment-823961805
If this link didn't help you can find more information on this link:
All solutions for the problem
Related
Scaffold(
appBar: AppBar(
title: Text("Design test..."),
),
body: Container(
margin:EdgeInsets.fromLTRB(0, MediaQuery.of(context).padding.top, 0, 0
),
child: Column(
children: [
Container(//for Some Kind of design at top),
Column(
children: [
ListView.builder(
itemCount: listLength.length,
itemBuilder: (BuildContext buildContext, int index) {
return ListTile(title: Text("hello world")
);
}),
//i want to add some design here after the list view for advertisement and comment
],
),
],
),
),
);
my listview.builder() item length is dynamic so i want to expand my list view as much as it requied and when it ends i need some design just like youtube privious design where on the top video player after that video list and at the end comment part.thank you.
Yes you can achieve this, Refer to this code.
use the build method like this.
#override
Widget build(BuildContext context) {
return Scaffold(
body : ListView(
//Base Listview, it can be scrollable if content is large also
children:[
Container(
//Sample widget you can use your own
child:Text("Here is some design At Top")
),
ListView.builder(
//use shrinkWrap:true and physics:NeverScrollableScrollPhysics()
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: 10, //it can be dynamic and null checks can be appield,
itemBuilder: (context, index){
return Text("ListItem $index");
},
),
Container(
//Sample widget you can use your own
child: Text("Some Design for Ads")
),
Container(
//Sample widget you can use your own
child: Text("Some Design for Commentes")
)
]
)
);
}
Mark answer as right if it helped !!
I want to show Listview underneath my two widgets but when i hot reload, nothing happens and if i run again, UI shows blank screen. If i remove Listview.builder it works fine.
Below is my code.
import 'package:flutter/material.dart';
import 'package:plant_clone/constants.dart';
import 'package:plant_clone/model/model.dart';
import 'package:plant_clone/screens/home/components/header_with_searchbox.dart';
import 'package:plant_clone/screens/home/components/title_with_more_btn.dart';
import 'package:plant_clone/viewmodel/recommended_plants_viewmodel.dart';
class Body extends StatelessWidget {
RecommendedPlantViewModel recommendedPlantViewModel =
new RecommendedPlantViewModel();
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
recommendedPlantViewModel.setWidgetsData();
return SingleChildScrollView(
child: Column(
children: [
HeaderWithSearchBox(size: size),
TitleWithMoreButton(
title: "Recommended",
press: () {},
),
ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: (context, index) {
return Card(
child: ListTile(
onTap: (){},
title: Text('Hello'),
),
);
})
],
),
);
}
}
It doesn't look like there's any other way than setting height constraint using a SizedBox that's wrapping a ListView.
Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: size.height,
child: ListView.builder(
...
),
),
],
)
https://flutter.dev/docs/cookbook/lists/horizontal-list
i think it happened because the list view should have a height,,
the esiest way is to test that put it inside a container and give a height to it..
and the second way is wrap the listview inside a Expanded widget and it will fix ..
if not then post the error from debug log
In order to make this to work, you must wrap your ListView with a Container and define the height property as it is part of a Column. You also need to wrap the widget returned by the itemBuilder with a Container and define the width property as the scrollDirection is set to Axis.horizontal.
Container(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: (context, index) {
return Container(
width: 100,
child: Card(
child: ListTile(
onTap: () {},
title: Text('Hello'),
),
),
);
},
),
)
I am trying to create an app with a scroll view and the objects are clickable like the google news app. Can anyone answer how to animate the container to have a white glow on holding the tile?
Here is the list view builder I have for the app
Container(
padding: EdgeInsets.only(top: 16),
child: ListView.builder(
physics: ClampingScrollPhysics(),
itemCount: article.length,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, index) {
return news_tile(
imageurl: article[index].urlToimage,
news_title: article[index].title,
news_desc: article[index].description,
web_url: article[index].url
);
}),
)
and this is the contents of the tile which the list view builder calls
class news_tile extends StatelessWidget {
String imageurl, news_title, news_desc,web_url;
news_tile({this.imageurl, this.news_title, this.news_desc,this.web_url});
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => article_view(
web_url: web_url,
)
));
},
child: Container(
margin: EdgeInsets.only(bottom: 16),
child: Column(
children: <Widget>[
ClipRRect(borderRadius: BorderRadius.circular(6), child: Image.network(imageurl)),
SizedBox(
height: 8,
),
Text(news_title, style: TextStyle(fontSize: 17,fontWeight: FontWeight.w600)),
SizedBox(
height: 8,
),
Text(news_desc, style: TextStyle(color: Colors.black54))
],
),
),
);
}
}
You could go with the InkWell Widget. It provides a tapping/holding color effect similar to that. Have a look at the official docs here:
https://api.flutter.dev/flutter/material/InkWell-class.html
Note that you need a Material Widget as an ancestor of your InkWell, but the docs explain that more.
Hope it works for you!
Edit: Sorry, since you are working with a Container, Ink is also important for you:
https://api.flutter.dev/flutter/material/Ink-class.html
Check the docs section "The ink splashes aren't visible!" for why that is.
As in the image shown above, I want widget 2 to always be at least the height of the remaining space available.
But widget 2 might contain so many ListTiles so that they can not be displayed without scrolling. But scrolling should affect widget 1 and widget 2. What is the best way to implement something like this?
Wrap Widget 2 in an Expanded Widget.
To scroll both Widget 1 and Widget 2, wrap both of them in a SingleChildScrollView Widget.
If you can distinguish between the case with a few and many elements (for example during loading), you can use CustomScrollView with SliverFillRemaining for this:
var _isLoading = true;
#override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
_buildWidget1(),
_buildWidget2(),
],
);
}
Widget _buildWidget1() {
return SliverToBoxAdapter(
child: Container(height: 400, color: Colors.blue),
);
}
Widget _buildWidget2() {
if(_isLoading) {
return SliverFillRemaining(
hasScrollBody: false,
child: Center(child: const CircularProgressIndicator()),
);
} else {
return SliverFixedExtentList(
delegate: SliverChildBuilderDelegate(
_buildItem,
childCount: childCount,
),
itemExtent: 56,
);
}
}
A simple way to do that would be to place your widgets in Column and wrap it with a single child scroll view. For the ListView use shrinkWrap as true and physics you can set to NeverScrollableScrollPhysics
Here is an example
SingleChildScrollView(
child: Column(
children: [
Container(
height: MediaQuery.of(context).size.height / 2,
color: Colors.red,
),
ListView.builder(
shrinkWrap:true,
physics:NeverScrollableScrollPhysics(),
itemCount: 100,
itemBuilder: (context, index) => Text("$index"),
),
],
),
);
Hope this helps!
var widgetHeight = MediaQuery.of(context).size.height - fixedSize;
return SingleChildScrollView(
child: Container(
height: widgetHeight,
child: Widget2
)
)
In this code, I am trying to make a list of buttons or tiles "as buttons do not work well for me " at the very top of the page. Thus, when one is clicked it returns a value in the rest of the page.
The issue is The tile here toke around more than half of the page which makes it looks inconsistent. I want to limit the height of the tile, I have tried putting them in a row and a container and it doesn't work. Any HELP will be appreciated.
the result after running the code is:
this is the error after runing the code :
class HomePage extends StatefulWidget {
// const HomePage({Key key}) : super(key: key);
#override
HomePageState createState() {
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
List<String> temp=new List();
List<String> temp1=['Nile University', 'Smart Village', 'Zewail'];
Map<String,String> map1={};
#override
void initState() {
super.initState();
getplaces(temp);
getuser(map1,'1jKpg81YCO5PoFOa2wWR');
}
Future<List> getuser(temp,String place) async{
List<String> userids=[];
QuerySnapshot usersubs= await Firestore.instance.collection('tempSubs').getDocuments();
QuerySnapshot userid= await Firestore.instance.collection('users').where('place',isEqualTo: place).getDocuments();
userid.documents.forEach((DocumentSnapshot doc,){
usersubs.documents.forEach((DocumentSnapshot doc1){
if(doc.documentID==doc1.documentID){
doc1.data['products'].forEach((k,v){
if( DateTime.fromMillisecondsSinceEpoch(v).day==DateTime.now().day){
int x= DateTime.fromMillisecondsSinceEpoch(v).day;
print('keey equal $k and v is $x');
print('dy is $x');
userids.add(
doc.documentID);
}
});
}
} ); }
);
print('doc.documentID');
print (userids);
setState(() {});
return userids;
}
Future<List> getplaces(temp) async{
QuerySnapshot place= await Firestore.instance.collection('places').getDocuments();
place.documents.forEach((DocumentSnapshot doc){
temp.add(
doc.data['name']
);
// print(doc.data['name']);
});
// print(temp);
setState(() {});
return temp;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home Page"),
),
body: !temp.isNotEmpty?
CircularProgressIndicator():
Row(mainAxisSize:MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children:<Widget>[
Container(
height: 100.0,
child:
ListView.builder(
scrollDirection: Axis.horizontal,
itemExtent: 100.0,
itemCount:temp.length,
itemBuilder:(BuildContext context, int index) {
return ListTile(title: Text(temp[index]),onTap:
(){
print(temp[index]);
}
);}
),),
Container(child:Text('data'),)
],),
);
}
}
Applying VisualDensity allows you to expand or contract the height of list tile. VisualDensity is compactness of UI elements. Here is an example:
// negative value to contract
ListTile(
title: Text('Tile title'),
dense: true,
visualDensity: VisualDensity(vertical: -3), // to compact
onTap: () {
// tap actions
},
)
// positive value to expand
ListTile(
title: Text('Tile title'),
dense: true,
visualDensity: VisualDensity(vertical: 3), // to expand
onTap: () {
// tap actions
},
)
The values ranges from -4 to 4 and default is 0 as of writing this answer.
However, you cannot use this method for specific width or height size.
Just remove the Expanded Widget to avoid fill the space available and use a parent Container with a fixed height, the same as the itemExtent value:
Column(
children: <Widget>[
Container(
height: 100.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemExtent: 100.0,
itemCount: temp.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(temp[index]),
onTap: () {
print(temp[index]);
});
}),
),
Container(
child: Text('data'),
)
],
),
You should use a Container or Padding instead of ListTile if you need more customization.
You cannot set the height, but you can make it smaller by setting the dense property to true:
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(list[index].name,style: TextStyle(fontSize: 20.0),),
contentPadding: EdgeInsets.symmetric(vertical: 0.0, horizontal: 16.0),
dense:true,
);
},
);
ListTile:
A single fixed-height row that typically contains some text as well as
a leading or trailing icon.
To be accessible, tappable leading and trailing widgets have to be at
least 48x48 in size. However, to adhere to the Material spec, trailing
and leading widgets in one-line ListTiles should visually be at most
32 (dense: true) or 40 (dense: false) in height, which may conflict
with the accessibility requirement.
For this reason, a one-line ListTile allows the height of leading and
trailing widgets to be constrained by the height of the ListTile. This
allows for the creation of tappable leading and trailing widgets that
are large enough, but it is up to the developer to ensure that their
widgets follow the Material spec.
https://api.flutter.dev/flutter/material/ListTile-class.html
Since there's no height property in ListTile you can limit the size of a tile by placing it inside a SizedBox:
SizedBox(
height: 32,
child: ListTile(..))