As my first Flutter project I'm building an app for a newspaper. There are a number of news categories. For those categories, I have created a generic Widget
, in the home screen that Widget
will be shown multiple times for multiple categories in a Listview
, those category Widgets
have Listview
in them too as I bring multiple news from those categories. The Widget
class that has this generic Widget
is Newsfeed.dart
which will be given below.
This generic Widget
is called from a another Widget
class WidgetFactory.dart
which actually calls API and builds the home screen by using the above mentioned generic Widget
for categories. This class uses a Listview.builder
which is inside FutureBuilder
.
The problem is, when I open the app in the screen the news appears but I can't scroll, it stays fixed. I have checked if the API is actually bringing the news, in console I have printed the API response, all of the news are fetched but still I can't scroll.
the flow is main.dart -> WidgetFactory() -> Newsfeed()
WidgetFactory()
class WidgetFactory extends StatefulWidget {
@override
_WidgetFactoryState createState() => _WidgetFactoryState();
}
class _WidgetFactoryState extends State<WidgetFactory> {
List homeScreenCategories = [4, 14, 13, 23, 8015, 22];
Future<List> newsPostList;
List<List<NewsPost>> categoryNewsPostList;
@override
void initState() {
super.initState();
newsPostList = fetchNews();
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Container(
alignment: Alignment.center,
child: Container(
child: RefreshIndicator(
child: FutureBuilder(
future: newsPostList,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if(snapshot.data == null) {
return Container(
child: CircularProgressIndicator()
);
} else {
return ListView.builder(
shrinkWrap: true,
physics: const AlwaysScrollableScrollPhysics(),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return _getCategoryNews(snapshot, index);
},
);
}
},
),
onRefresh: () {
fetchNews();
}
),
),
);
}
Future<List> fetchNews() async {
String url = "url";
Response response = await Dio().get(url);
if(response.statusCode == 200) {
List newsPostList = [];
for(int i=0; i<response.data.length; i++) {
newsPostList.add(response.data[i]);
}
return newsPostList;
} else {
throw Exception("Failed to fetch category");
}
}
Widget _getCategoryNews(snapshot, int index) {
List<NewsPost> newsPostList = [];
for(var c in snapshot.data[index]['items']) {
NewsPost newsPost = NewsPost.getNewsPostFromAPI(c);
newsPostList.add(newsPost);
}
return Newsfeed(newsPostList, "National");
}
}
Newsfeed()
class Newsfeed extends StatefulWidget {
String categoryName;
List<NewsPost> newsPostList;
Newsfeed(this.newsPostList, this.categoryName);
@override
_NewsfeedState createState() => _NewsfeedState(this.newsPostList, this.categoryName);
}
class _NewsfeedState extends State<Newsfeed> {
final GlobalKey<ScaffoldState> _scaffoldKeyTwo = new GlobalKey<ScaffoldState>(debugLabel: '_MainScreenKey');
String categoryName;
_NewsfeedState(this.newsPostList, this.categoryName);
List<NewsPost> newsPostList;
var dio = new Dio();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Container(
alignment: Alignment.center,
child: ListView.builder(
shrinkWrap: true,
itemCount: newsPostList.length,
itemBuilder: (BuildContext context, int index) {
print(newsPostList[index]);
return _getNewsPostWidgets(index);
}
),
);
}
Widget _getNewsPostWidgets(int index) {
var newsPost = newsPostList[index];
if(index < 5) {
if(index == 0) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
ScaleTransitionRoute(
page: NewsPostDetails(newsPostList, index)
)
);
},
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
//constraints: BoxConstraints(minWidth: double.infinity, maxWidth: double.infinity),
constraints: BoxConstraints.expand(
width: double.infinity,
height: 40
),
color: const Color(0xFF2b4849),
child: Text(
this.categoryName,
style: TextStyle(
fontSize: 33,
color: Colors.white
),
),
),
BlockHeadline(newsPost)
],
)
);
}
else {
return GestureDetector(
onTap: () {
Navigator.push(
context,
ScaleTransitionRoute(
page: NewsPostDetails(newsPostList, index)
)
);
},
child: ListedNews(newsPost),
);
}
}
else {
return Container(
color: const Color(0xFF2b4849),
child: index == 5 ? FlatButton(
child: Text(
"See More",
style: TextStyle(
color: Colors.white
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => NewsFeedForSpecificCategory(newsPostList)
)
);
},
) : Container(),
);
}
}
openNewsPostDetails(List<NewsPost> newsPostList, int index) {
Navigator.push(
context,
ScaleTransitionRoute(
page: NewsPostDetails(newsPostList, index)
)
);
}
}
What I have tried
I found some questions that relates to this problem a bit. Tried those.
- I used
shrinkwrap=true
in myListview.builder
, but of no use. - Tried using
Column
insideSingleChildScrollView()
, still did not work. - Inside the
Listview.builder
addedphysics
asAlwaysScrollable()
, also in vain.
As I'm new to flutter what I tried might seem dumb.
One more thing is, the news that shows up in the home screen, that takes me to the details page fine and there swiping left right takes me to other news also. It's the home screen that is causing trouble, not scrolling.
It would be great help if you could kindly give some clues.