I'm trying to make an application like Instagram. But I can't fully view the zoomed picture because of other pictures.
Codes:
List colors = [
Colors.green,
Colors.blue,
Colors.red,
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Demo"),
),
body: ListView.builder(
itemCount: 3,
itemBuilder: (_, int index) {
TransformationController controller = TransformationController();
return Container(
child: InteractiveViewer(
transformationController: controller,
onInteractionEnd: (_) {
setState(() {
controller.toScene(Offset.zero);
});
},
child: ColorFiltered(
colorFilter: ColorFilter.mode(colors[index], BlendMode.color),
child: FlutterLogo(),
),
),
height: 200,
width: 200,
);
},
),
);
}
Note: I can't use widgets like stack because of listview.builder
You could either use Visibility widget or Opacity widget to change the visibility of images not being currently panned. Please see the code below I'm using AnimatedOpacity just so that the disappearance of the images does not look too sudden, but you may use Opacity widget as well.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Flutter Demo")),
body: MyStatefulWidget(),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
static List colors = [
Colors.green,
Colors.blue,
Colors.red,
];
final List<double> _opacity = List.generate(colors.length, (index) => 1);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Demo"),
),
body: ListView.builder(
itemCount: 3,
itemBuilder: (_, int index) {
final TransformationController controller =
TransformationController();
return AnimatedOpacity(
opacity: _opacity[index],
duration: const Duration(milliseconds: 100),
child: Container(
child: InteractiveViewer(
transformationController: controller,
onInteractionStart: (details) {
for (int i = 0; i < _opacity.length; i++) {
_opacity[i] = i == index ? 1 : 0;
}
setState(() {});
},
onInteractionEnd: (_) {
setState(() {
_opacity.fillRange(0, _opacity.length, 1);
controller.toScene(Offset.zero);
});
},
child: ColorFiltered(
colorFilter: ColorFilter.mode(colors[index], BlendMode.color),
child: const FlutterLogo(),
),
),
height: 200,
width: 200,
),
);
},
),
);
}
}
Related
I am currently working in a page where I have to show a list of apps in the device which should be half a screen only, for that i have a used a bottom drawer widget to display that ,
the main problem is every time i open the app it needs to get pulled, i don't want to do it so can some help me to display the apps without pulling the bottom drawer widget ? or else is there any other widget to do that ?
You can try bottom modal sheet or draggableScrollableSheet which has a min size
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatelessWidget(),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
child: const Text('showModalBottomSheet'),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('Modal BottomSheet'),
ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () => Navigator.pop(context),
)
],
),
),
);
},
);
},
),
);
}
}
draggableScrollableSheet
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('DraggableScrollableSheet'),
),
body: SizedBox.expand(
child: 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'));
},
),
);
},
),
),
);
}
}
You can use DraggableScrollableSheet with minChildSize: .5, on this case.
return Scaffold(
bottomNavigationBar: DraggableScrollableSheet(
minChildSize: .5,
maxChildSize: 1,
builder: (context, scrollController) {
return Column(
children: [
Center(
child: Text("Title"),
),
Expanded(
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text('Item $index'));
},
),
),
],
);
},
));
More about DraggableScrollableSheet
I have a ListView containing string items. I want to make it so that ListView's items show one by one with delay. And after each item appears, I want to wait about 2 seconds with a typing indicator and then the next item will appear. How will I do? Please give me the solution. Thanks!
You can use AnimatedListView like this code below
https://www.youtube.com/watch?v=ZtfItHwFlZ8
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Test',
theme: ThemeData(
primaryColor: Colors.green,
colorScheme:
ColorScheme.fromSwatch().copyWith(secondary: Colors.greenAccent)),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// Items in the list
final _items = ["Item 0"];
// The key of the list
final GlobalKey<AnimatedListState> _key = GlobalKey();
// Add a new item to the list
// This is trigger when the floating button is pressed
void _addItem() {
_items.insert(0, "Item ${_items.length + 1}");
_key.currentState!.insertItem(0, duration: const Duration(seconds: 1));
}
// Remove an item
// This is trigger when an item is tapped
void _removeItem(int index, BuildContext context) {
AnimatedList.of(context).removeItem(index, (_, animation) {
return FadeTransition(
opacity: animation,
child: SizeTransition(
sizeFactor: animation,
child: SizedBox(
height: 150,
child: Card(
margin: const EdgeInsets.symmetric(vertical: 20),
elevation: 10,
color: Colors.red[400],
child: const Center(
child: Text("I am going away",
style: const TextStyle(fontSize: 28)),
),
),
),
),
);
}, duration: const Duration(seconds: 1));
_items.removeAt(index);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Test list'),
actions: [
IconButton(
onPressed: _addItem,
icon: const Icon(Icons.plus_one_outlined),
)
],
),
body: AnimatedList(
key: _key,
initialItemCount: 1,
padding: const EdgeInsets.all(10),
itemBuilder: (context, index, animation) {
return SlideTransition(
key: UniqueKey(),
position: Tween<Offset>(
begin: const Offset(-1, -0.5),
end: const Offset(0, 0),
).animate(animation),
child: RotationTransition(
turns: animation,
child: SizeTransition(
axis: Axis.vertical,
sizeFactor: animation,
child: SizedBox(
height: 150,
child: InkWell(
onTap: () => _removeItem(index, context),
child: Card(
margin: const EdgeInsets.symmetric(vertical: 20),
elevation: 10,
color: Colors.primaries[
(index * 100) % Colors.primaries.length][300],
child: Center(
child: Text(_items[index],
style: const TextStyle(fontSize: 28)),
),
),
),
),
),
),
);
},
),
);
}
}
Try wrapping your widget around this widget https://pub.dev/packages/delayed_display. Please confirm if this works.
I'm trying to remove the debug banner from my application and I added debugShowCheckedModeBanner: false in my main.dart and every activity but still showing the debug banner.
Main.dart
void main() async {
runApp(MaterialApp(home:SplashScreen(), debugShowCheckedModeBanner: false,));
}
class SplashScreen extends StatefulWidget {
#override
_SplashScreenState createState() => new _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
startTime() async {
var _duration = new Duration(seconds: 1);
return new Timer(_duration, navigationPage);
}
void navigationPage() {
Navigator.pushReplacement(
context,
new CupertinoPageRoute(
builder: (BuildContext context) => MyHomesApp()));
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Stack(
children: <Widget>[
Container(
decoration: new BoxDecoration(color: colorGreen),
),
Container(
padding: EdgeInsets.all(30.0),
child: Center(
child: new Image.asset('assets/green_h_logo.png',color: Colors.white,height: 150,width: 150,)
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 50,
child:new Image.asset('assets/h.gif')),
),
],
),
);
}
}
The above code is my main.dart, it loads a splash screen and after a second it navigates to myhomesapp which has bottomnavigationbar as below:
home.dart
class MyHomesApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'App Name',
theme: ThemeData(
primarySwatch: Colors.green,
fontFamily: "Montserrat", //my custom font
),
builder: (context, child) {
return ScrollConfiguration(
behavior: MyBehavior(),
child: child,
);
},
home: Homes(),
);
}
}
class Homes extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Homes> {
int _currentIndex;
List<Widget> _children;
#override
void initState() {
_currentIndex = 0;
_children = [
MyDealApp(),
MyRedemptionApp(),
MyProfileApp()
];
_loadCounter();
super.initState();
}
_loadCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
myInt = prefs.getInt('id') ?? 0;
_email = (prefs.getString('email') ?? '');
_fullname = (prefs.getString('fullname') ?? '');
currentTabs = prefs.getInt('currentTab') ?? 0;
debugPrint("currentTabMain:$currentTabMain");
debugPrint("emailr:$_email");
});
}
#override
Widget build(BuildContext context) {
const assetHome = 'assets/home_off.svg';
const assetRedemptions = 'assets/redeemed_off.svg';
const assetCommunity = 'assets/community_off.svg';
const assetProfile = 'assets/profile_off.svg';
const assetHome1 = 'assets/home_on.svg';
const assetRedemptions1 = 'assets/redeemed_on.svg';
const assetCommunity1 = 'assets/community_on.svg';
const assetProfile1 = 'assets/profile_on.svg';
return Container(
height: 30,
child:CupertinoTabScaffold(
tabBar: CupertinoTabBar(
backgroundColor: colorGreen,
currentIndex: _currentIndex,
onTap: onTabTapped,
items: [
BottomNavigationBarItem(
icon: _currentIndex == 0 ?SvgPicture.asset(assetHome1,
color: Colors.white,
width: 20,
height: 20,
semanticsLabel: 'Home'):SvgPicture.asset(assetHome,
color: Colors.white,
width: 20,
height: 20,
semanticsLabel: 'Home'),
),
BottomNavigationBarItem(
icon: _currentIndex == 1 ?SvgPicture.asset(assetRedemptions1,
color: Colors.white,
width: 20,
height: 20,
semanticsLabel: 'Redemptions'):SvgPicture.asset(assetRedemptions,
color: Colors.white,
width: 20,
height: 20,
semanticsLabel: 'Redemptions'),
),
BottomNavigationBarItem( icon: _currentIndex == 2 ? SvgPicture.asset(assetProfile1,
color: Colors.white,
width: 20,
height: 20,
semanticsLabel: 'Profile'):SvgPicture.asset(assetProfile,
color: Colors.white,
width: 20,
height: 20,
semanticsLabel: 'Profile'),
),
],
),
tabBuilder: (BuildContext context, int index) {
return CupertinoTabView(
builder: (BuildContext context) {
return SafeArea(
top: false,
bottom: false,
child: CupertinoApp(
home: CupertinoPageScaffold(
resizeToAvoidBottomInset: false,
child: _children[_currentIndex],
),
),
);
},
);
}
));
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
debugPrint("tabbottom:$_currentIndex");
});
}
}
I used the same for MyRedemptionApp() and MyProfileApp() respectively. The major issue is debugShowCheckedModeBanner: false is not removing the debug banner because the debug banner shows on every page. How to remove the debug banner?
This normally happens when you have multiple MaterialApp widgets used. If you don't think you can reduce to one just use debugShowCheckedModeBanner:false whenever you use MaterialApp widgets throughout your application.
you can see the details in video
I don't know how to work out this problem.Compared with Android Native ViewPager,the animation of the PageView in Flutter seems to be slower and users only to wait this slow animation to completely stop , they can drag the internal ListView.I feel that the user experience is worse than native android ViewPager.Hoping a perfect solution.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/reactive_page_view/reactive_page_view.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Page(),
);
}
}
class Page extends StatefulWidget {
#override
_PageState createState() => _PageState();
}
PageView view;
class _PageState extends State<Page> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: CupertinoNavigationBar(
middle: Text("Demo"),
),
body: PageView.builder(
physics: BouncingScrollPhysics(),
itemCount: 3,
itemBuilder: (context, index) {
return ItemPage();
}),
);
}
}
class ItemPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: 30,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text('这是第$index', style: TextStyle(fontSize: 30)),
);
});
}
}
You can define your own instance of PageController and use its methods nextPage() and previousPage(). They have "duration" argument that controls how fast the page view scrolls.
final PageController controller = PageController(
viewportFraction: 0.9,
);
void nextPage() async {
await controller.nextPage(
duration: Duration(milliseconds: 200),
curve: Curves.easeOut,
);
}
void prevPage() async {
await controller.previousPage(
duration: Duration(milliseconds: 200),
curve: Curves.easeOut,
);
}
Then apply this controller to your Page View:
return PageView.builder(
physics: NeverScrollableScrollPhysics(),
controller: controller,
...
);
The full code of main.dart:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyPageViewExample(),
);
}
}
class MyPageViewExample extends StatelessWidget {
MyPageViewExample({Key key}) : super(key: key);
final PageController controller = PageController(
viewportFraction: 0.9,
);
void nextPage() async {
await controller.nextPage(
duration: Duration(milliseconds: 200),
curve: Curves.easeOut,
);
}
void prevPage() async {
await controller.previousPage(
duration: Duration(milliseconds: 200),
curve: Curves.easeOut,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
color: Colors.grey[100],
),
Padding(
padding: EdgeInsets.only(top: 20.0 + MediaQuery.of(context).padding.top, bottom: 20.0),
child: _buildCarousel(context),
),
],
),
);
}
Widget _buildCarousel(BuildContext context) {
return PageView.builder(
physics: NeverScrollableScrollPhysics(),
controller: controller,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int itemIndex) {
return _buildItem(context, itemIndex);
},
itemCount: 5,
);
}
Widget _buildItem(BuildContext context, int itemIndex) {
return Padding(
padding: EdgeInsets.only(left: 4.0, top: 10.0, right: 4.0, bottom: 10.0),
child: GestureDetector(
onPanUpdate: (details) {
if (details.delta.dx < 0) {
nextPage();
}
if (details.delta.dx > 0) {
prevPage();
}
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(35.0)),
),
child: Center(
child: Text(
'Item ' + (itemIndex + 1).toString(),
),
),
),
),
);
}
}
You can control the general physics of the scroll animation.
PageView(
physics: CustomPageViewScrollPhysics(),
Control the scroll behavior:
class CustomPageViewScrollPhysics extends ScrollPhysics {
const CustomPageViewScrollPhysics({ScrollPhysics? parent})
: super(parent: parent);
#override
CustomPageViewScrollPhysics applyTo(ScrollPhysics? ancestor) {
return CustomPageViewScrollPhysics(parent: buildParent(ancestor)!);
}
#override
SpringDescription get spring => const SpringDescription(
mass: 50,
stiffness: 100,
damping: 0.8,
);
}
You should also be able to calculate the duration with mass, stiffness, damping, but I believe having those options is even better suited for your problem. Source
I'm using Flutter for first time for one of my projects which is a Newspaper App.
The problem takes place when I try to navigate from main.dart to newsfeed_for_other_category.dart using MaterialPageRoute from my Drawer. In that screen it shows the news but with a black background. But in the screen newsfeed_screen.dart which is called in the body in my main.dart it shows perfectly.
I'm posting the codes below.
main.dart
import 'package:flutter/material.dart';
import './SizeConfig.dart';
import './screens/newsfeed_screen.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import 'factory/widget_factory.dart';
import 'widgets/top_news_widget.dart';
import 'package:splashscreen/splashscreen.dart';
import './widgets/drawer.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Newspaper App',
theme: ThemeData(
primarySwatch: Colors.blue,
//backgroundColor: Colors.lightGreenAccent,
),
home: MyHomePage(title: 'The Business Standard'),
routes: <String, WidgetBuilder> {
'/screen1': (BuildContext context) => new NewsFeedScreen(216, 5, "Top News"),
'/screen2' : (BuildContext context) => new NewsFeedScreen(4, 7, "National"),
'/screen3' : (BuildContext context) => new NewsFeedScreen(13, 70, "International"),
/*'/screen4' : (BuildContext context) => new Screen4()*/
},
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: '_MainScreenKey');
Widget build(BuildContext context) {
return SplashScreen(
seconds: 3,
navigateAfterSeconds: AfterSplash(),
title: Text(
'The Business Standard',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0
),
),
image: Image.asset(
'assets/TBS_logo.jpg',
),
backgroundColor: Colors.white,
styleTextUnderTheLoader: TextStyle(),
photoSize: 100.0,
onClick: ()=>print("Flutter Egypt"),
loaderColor: Colors.red
);
}
}
class AfterSplash extends StatefulWidget {
#override
_AfterSplashState createState() => _AfterSplashState();
}
class _AfterSplashState extends State<AfterSplash> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: '_MainScreenKey');
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
backgroundColor: Colors.white,
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Image.asset(
'assets/TBS.png',
fit: BoxFit.cover,
height: 45,
)
],
),
leading: IconButton(
icon: Icon(Icons.dehaze),
color: Colors.black,
onPressed: () => _scaffoldKey.currentState.openDrawer(),
),
),
drawer: SideDrawer(),
body: NewsFeedScreen(22, 71, "Sports"),
bottomNavigationBar: CurvedNavigationBar(
backgroundColor: const Color(0xFF2b4849),
items: <Widget>[
Icon(Icons.bookmark, size: 30,),
Icon(Icons.perm_identity, size: 30,),
Icon(Icons.settings, size: 30,),
],
onTap: (index) {
if(index == 2) {
_scaffoldKey.currentState.showSnackBar(const SnackBar(
content: const Text('Will open Settings menu')));
} else if(index == 0) {
_scaffoldKey.currentState.showSnackBar(const SnackBar(
content: const Text('Implement Bookmark function')));
} else {
_scaffoldKey.currentState.showSnackBar(const SnackBar(
content: const Text('Will show User profile and information')));
}
},
),
);
}
}
newsfeed_for_other_category.dart, the page to which I'm navigating and this is where the black background shows up.
import 'package:flutter/material.dart';
import '../SizeConfig.dart';
import '../widgets/headlines.dart';
import '../widgets/secondary_headlines.dart';
import '../widgets/listed_news.dart';
import '../models/NewsPost.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:developer';
import '../screens/newsPost_details.dart';
import '../screens/newsfeed_for_specific_category.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import '../transition_animation_routes/ScaleTransitionRoute.dart';
import '../widgets/top_news_widget.dart';
class NewsfeedForOtherCategory extends StatefulWidget {
int categoryId;
int childrenCategoryId;
String categoryName;
NewsfeedForOtherCategory(this.categoryId, this.childrenCategoryId, this.categoryName);
#override
_NewsfeedForOtherCategoryState createState() => _NewsfeedForOtherCategoryState(this.categoryId, this.childrenCategoryId, this.categoryName);
}
class _NewsfeedForOtherCategoryState extends State<NewsfeedForOtherCategory> {
int categoryId;
int childrenCategoryId;
String categoryName;
_NewsfeedForOtherCategoryState(this.categoryId, this.childrenCategoryId, this.categoryName);
bool _isRequestSent = false;
List<NewsPost> newsPostList = [];
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
if(!_isRequestSent) {
_sendRequest();
}
return Container(
alignment: Alignment.center,
child: !_isRequestSent
? CircularProgressIndicator()
: Container(
child: ListView.builder(
itemCount: newsPostList.length,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
return _getNewsPostWidgets(index);
}
),
),
);
}
void _sendRequest() async {
String url = "https://tbsnews.net/json/category/news/"+this.categoryId.toString()+"/"+this.childrenCategoryId.toString()+"";
http.Response response = await http.get(url);
List<dynamic> decode = json.decode(response.body);
log('response: $response');
List results = decode[0]['items'];
for (var jsonObject in results) {
var post = NewsPost.getNewsPostFromAPI(jsonObject);
newsPostList.add(post);
print(post);
}
setState(() => _isRequestSent = true);
}
Widget _getNewsPostWidgets(int index) {
var newsPost = newsPostList[index];
if(index < this.newsPostList.length) {
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 == 3 ? FlatButton(
child: Text(
"Load 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)
)
);
}
}
drawer.dart
import 'package:flutter/material.dart';
import '../SizeConfig.dart';
import '../screens/newsfeed_for_other_category.dart';
class SideDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return SizedBox(
width: SizeConfig.safeBlockHorizontal*50,
child: Theme(
data: Theme.of(context).copyWith(canvasColor: const Color(0xFF2b4849)),
child: Drawer(
child: ListView(
children: <Widget>[
ListTile(
title: Text(
'Top News',
style: TextStyle(
fontSize: 20,
color: Colors.white
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => NewsfeedForOtherCategory(216, 5, "Top News")
)
);
},
),
],
),
),
),
);
}
}
In my home screen which is newsfeed_screen.dart called in the body of AfterSplashState widget in main.dart it looks like below, this is what it should look like.
But in the screen NewsfeedForOtherCategory to which I navigate using drawer looks like below with the black background.
I have tried using Navigator.of(context, rootNavigator: true).pushNamed('/route') and pushReplacementNamed() also instead of MaterialPageRoute. But of no use.
Here is a related question that I found, I tried the solutions they gave, but did not work for me.
Also to mention, the page I'm navigating to does not have MaterialApp widget, only the main.dart has it. So there should not be an issue.
I'm using a Ubuntu 16.04 machine.
Some clue from you would be priceless. Thanks a lot for your time.
NewsfeedForOtherCategory page is black because it doesn't have Material container.
You can simply wrap it with Material widget or Scaffold(which has some additional features like drawer, floating action button).
And from your screenshot I can see some widgets are overflowed by notification bar. You can use SafeArea inside Material or inside body of the Scaffold to overcome this.
Wrap the main Container in NewsfeedForOtherCategory with a scaffold and you have your solution.
...
return Scaffold(
body: Container(
alignment: Alignment.center,
child: !_isRequestSent
? CircularProgressIndicator()
: Container(
child: ListView.builder(
itemCount: newsPostList.length,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
return _getNewsPostWidgets(index);
}
),
),
);
);
...
In the build function of your NewsfeedForOtherCategory widget,
try wrapping what you have there in a Scaffold.
Like:
return Scaffold(
body: Container(
alignment: Alignment.center,
child: !_isRequestSent
? CircularProgressIndicator()
: Container(
child: ListView.builder(
itemCount: newsPostList.length,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
return _getNewsPostWidgets(index);
}),
),
),
),
when we navigate between two screen both screen parent should be scafold
if you don't want to use scaffold u can use container color property also
Try wrapping your container in scaffold in NewsfeedForOtherCategory screen Like this
...
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
),
);
}
...
Or u can set container color white like this
...
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child:
//enter code here
);
}
...