My transition animation doesn't apply to pages that have TextField.
when I remove TextField the animation works properly.
anybody know what's wrong?
this is my slider animation:
class SlideLeftRoute extends PageRouteBuilder {
final Widget page;
SlideLeftRoute({this.page})
: super(
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>
page,
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
SlideTransition(
position: Tween<Offset>(
begin: const Offset(1, 0),
end: Offset.zero,
).animate(animation),
child: child,
),
);
}
this is my page:
class VerifyAuthPage extends StatelessWidget {
final String phone;
final int expTime;
VerifyAuthPage({Key key, #required this.phone, #required this.expTime});
#override
Widget build(BuildContext context) {
return Scaffold(body: Container(color: Colors.red,
child: TextField(),
),);
}
this is my root app:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: BanijetColors.PRIMARY,
statusBarBrightness: Brightness.light,
));
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
fontFamily: 'IranSanse',
primaryColor: Colors.PRIMARY,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Splash(),
initialRoute: 'splash',
onGenerateRoute: (RouteSettings setting) {
return mapNamesToRoutes(setting);
},
);
}
}
this is mapNamesToRoute function:
SlideLeftRoute mapNamesToRoutes(RouteSettings setting) {
Widget destination;
final requestAuthCubit = sl<RequestAuthCubit>();
final verifyAuthCubit = sl<VerifyAuthCubit>();
switch (setting.name) {
case 'splash':
destination = Splash();
break;
case 'auth/request':
destination = MultiBlocProvider(providers: [
BlocProvider(
create: (_) => InputValidationCubit(
inputType: InputType.Phone,
inputValidator: sl<InputValidator>())),
BlocProvider.value(value: requestAuthCubit)
], child: RequestAuthPage());
break;
case 'auth/verify':
final Map<String, Object> bundle = setting.arguments;
destination = MultiBlocProvider(providers: [
BlocProvider(
create: (_) => InputValidationCubit(
inputType: InputType.VerificationCode,
inputValidator: sl<InputValidator>())),
BlocProvider.value(value: requestAuthCubit),
BlocProvider.value(value: verifyAuthCubit),
BlocProvider.value(value: sl<TimerCubit>()),
], child: VerifyAuthPage(phone: bundle['phone'], expTime: bundle['exp']));
break;
default:
destination = null;
}
return SlideLeftRoute(page: destination);
}
and this is my Splash page:
class Splash extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StatefulWrapper(
onInit: () async {
Future.delayed(const Duration(milliseconds: 2000), () {
Navigator.pushReplacementNamed(context, 'auth/verify',
arguments: {'phone': '**********', 'exp': 120});
});
},
child: Scaffold(
body: Container(
child: Center(child: Text('Splash Screen')
// child: Text('Splash Screen'),
),
),
));
}
}
Related
I am using firebase_auth to signup and login.
I am facing a problem with Streambuilder.
I would like to show page depends on User Logged in or not. It seems working fine.
But, the problem is that I can't use Get.off('/app'); in StreamBuilder and FutureBuilder.
if I can't use Getx.off('/app'); user can get back just pressing the back button, and
I would like to avoid this, so I am trying to use Get.off page route.
But, as vs code shows that FutureBuilder and StreamBuilder's builder return Widget,
and I have no idea how to code.
Any suggestion for this matter?
// main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
title: 'Karrot Market Clone',
theme: ThemeData(
primaryColor: Colors.black,
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
appBarTheme: AppBarTheme(
color: Colors.white,
),
),
initialBinding: InitBinding(),
initialRoute: '/',
getPages: [
GetPage(
name: '/',
page: () => BridgeFirebase(),
),
GetPage(
name: '/bridge_page',
page: () => BridgePage(),
),
GetPage(
name: '/app',
page: () => App(),
transition: Transition.rightToLeft,
),
GetPage(
name: '/start',
page: () => Start(),
),
GetPage(
name: '/login',
page: () => Login(),
transition: Transition.rightToLeft,
),
GetPage(
name: '/signup',
page: () => SignUp(),
transition: Transition.rightToLeft,
),
],
);
}
}
class BridgeFirebase extends StatelessWidget {
const BridgeFirebase({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: Firebase.initializeApp(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(child: Text('Firebase load fail'));
}
if (snapshot.connectionState == ConnectionState.done) {
return BridgePage();
}
return Center(
child: CircularProgressIndicator(
color: ColorsKM.primary,
),
);
},
);
}
}
class BridgePage extends StatelessWidget {
const BridgePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (BuildContext context, AsyncSnapshot<User?> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Splash();
}
if (snapshot.hasData) {
return App();
} else {
return Start();
}
},
);
}
}
// app.dart
class App extends GetView<AppController> {
const App({Key? key}) : super(key: key);
Widget _bodyWidget() {
switch (RouteName.values[controller.currentIndex.value]) {
case RouteName.HOME:
return Home();
break;
case RouteName.MYLOCAL:
return MyLocal();
break;
case RouteName.NEARBY:
return Nearby();
break;
case RouteName.CHATS:
return Chats();
break;
case RouteName.MYKARROT:
return MyKarrot();
break;
}
return Container();
}
BottomNavigationBarItem _bottomNavigationBarItem(
String iconName, String label) {
return BottomNavigationBarItem(
icon: Padding(
padding: EdgeInsets.only(bottom: 5.0),
child: SvgPicture.asset('assets/svg/${iconName}_off.svg', width: 22),
),
activeIcon: Padding(
padding: EdgeInsets.only(bottom: 5.0),
child: SvgPicture.asset('assets/svg/${iconName}_on.svg', width: 22),
),
label: label,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Obx(
() {
return _bodyWidget();
},
),
bottomNavigationBar: Obx(
() => BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: controller.currentIndex.value,
selectedFontSize: 12.0,
showSelectedLabels: true,
selectedItemColor: Colors.black,
selectedLabelStyle: TextStyle(color: Colors.black),
onTap: controller.changePageIndex,
items: [
_bottomNavigationBarItem('home', 'home'),
_bottomNavigationBarItem('notes', 'neighbor'),
_bottomNavigationBarItem('location', 'nearby'),
_bottomNavigationBarItem('chat', 'chat'),
_bottomNavigationBarItem('user', 'my karrot'),
],
),
),
);
}
}
// app_controller.dart
enum RouteName {
HOME,
MYLOCAL,
NEARBY,
CHATS,
MYKARROT,
}
class AppController extends GetxService {
static AppController get to => Get.find();
late RxInt currentIndex = 0.obs;
void changePageIndex(int index) {
currentIndex(index);
}
}
Because the build method is not completed when you navigate in Streambuilder so you can delay some time to the build method complete then navigate. do this when you want to navigate in Streambuilder :
Future.delayed(Duration.zero).then((value) => Get.off('/app'));
or just navigate in your controller or bloc class.
I'm trying to use the Navigator to navigate between named routes.
Despite the fact that a question exists here of similar nature, I did not find the answers to be particularly helpful. Additionally when I tried to implement some of the proposed solutions none of them worked.
The relevant error is:
Navigator operation requested with a context that does not include a Navigator.
The context used to push or pop routes from the Navigator must be that of a widget that is a
descendant of a Navigator widget.
I tried removing and adding the providers and that doesnt seem to be the cause of the problem, I have tested that access to the Provider.of<T>(context) interface works as expected.
I also tried implementing the Builder widget but that was also ineffective.
For clarification, Naigator.of(context).pushNamed('/home') appears within the build method of LandingPage for debugging purposes.
Code:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [Provider<LiraAnchor>(create: (_) => LiraAnchor())],
child: MaterialApp(
theme: ThemeData(
primaryColor: LiraColours.highlightGreen,
highlightColor: LiraColours.highlightGreen,
accentColor: LiraColours.highlightGreen,
cursorColor: LiraColours.highlightGreen,
indicatorColor: LiraColours.highlightGreen,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
debugShowCheckedModeBanner: false,
routes: {'/home': (ctx) => HomePage(), '/topup': (ctx) => TopUpPage()},
builder: (ctx, _) {
return LandingPage();
},
),
);
}
}
class LandingPage extends StatefulWidget {
LandingPage({Key key}) : super(key: key);
#override
_LandingPageState createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> {
final PageController _pageController = PageController();
#override
Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final double width = mediaQuery.size.width;
final double height = mediaQuery.size.height;
final List<Widget> onboarding = [
SplashPage(width: width, height: height, pageController: _pageController),
SignInPage(height: height, width: width)
];
Navigator.of(context).pushNamed('/home');
return Scaffold(
backgroundColor: Color(0xFFECF0F3),
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: SingleChildScrollView(
child: Container(
width: width,
height: height,
child: PageView.builder(
controller: this._pageController,
itemCount: onboarding.length,
itemBuilder: (ctx, index) {
return onboarding[index];
}),
),
),
));
}),
);
}
}
replace this line
routes: {'/home': (ctx) => HomePage(), '/topup': (ctx) => TopUpPage()},
with
initialRoute: RoutesLinks.main,
onGenerateRoute: RoutesProvider.provideRoutes,
and add this file
class RoutesProvider {
static Route<dynamic> provideRoutes(RouteSettings settings) {
// Getting arguments passed, in while calling Navigator.pushNamed
final arguments = settings.arguments;
switch (settings.name) {
case RoutesLinks.main:
return MaterialPageRoute(builder: (_) => MainPage());
case RoutesLinks.home:
return MaterialPageRoute(builder: (_) => HomeScreen());
default:
// If there is no such named route in the switch statement, e.g. /third
return _errorRoute();
}
}
static Route<dynamic> _errorRoute() {
return MaterialPageRoute(builder: (_) {
return Scaffold(
appBar: AppBar(
title: Text('Error'),
),
body: Center(
child: Text('ERROR'),
),
);
});
}
}
class RoutesLinks {
static const main = '/';
static const home = '/home';
}
I want to use animated page route on my flutter project. Now all of my routes are Named Route and I don't wanna change them. Is there any way I can use Page Route Animation with named route? Like: If I am going from PageOne() to PageTwo() using Navigator.of(context).pushNamed(PageTwo.routename), I don't wanna see default transition, May be I want to use scale animation or fade animation. Is there any way to do that?
onTap: () {
Navigator.of(context).pushNamed(
ProductsSearch.routeName,
arguments: ScreenArguments(null, null, null, null, null, null, true, false),
);
},
As your Question I have solved this demo answer try once it will work .
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: HomePage(),
onGenerateRoute: (RouteSettings settings) {
final SecondHome args = settings.arguments;
switch (settings.name) {
case '/':
return SlideRightRoute(widget:HomePage());
break;
case '/second':
return
SlideRightRoute(widget:SecondHome(args.data1,args.data2,args.boolvalue));
break;
}
},
),
);
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: new Center(
child: RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed(
'/second',
arguments:SecondHome("data1","data2",true),
);
},
child: Text('Second Home'),
),
),
);
}
}
class SecondHome extends StatelessWidget {
String data1;
String data2;
bool boolvalue;
SecondHome(this.data1,this.data2,this.boolvalue);
#override
Widget build(BuildContext context) {
print("Secoendhomedata${data1}");
return Scaffold(
appBar: AppBar(
title: Text('Second Home'),
),
body: new Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'),
),
),
);
}
}
class SlideRightRoute extends PageRouteBuilder {
final Widget widget;
SlideRightRoute({this.widget})
: super(
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return widget;
},
transitionsBuilder: (BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
return new SlideTransition(
position: new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: child,
);
},
);
}
How to make this page transaction effect on flutter
Example:
instagram stories
Edit
With package https://pub.dev/packages/swipedetector, you can detect SwipeDown
and In OnSwipeDown() execute your route change logical with PageRouteBuilder
SwipeDetector(
child: ... //You Widget Tree here
),
onSwipeUp: () {
setState(() {
_swipeDirection = "Swipe Up";
});
},
onSwipeDown: () {
setState(() {
_swipeDirection = "Swipe Down";
});
},
onSwipeLeft: () {
setState(() {
_swipeDirection = "Swipe Left";
});
},
onSwipeRight: () {
setState(() {
_swipeDirection = "Swipe Right";
});
},
)
please use PageRouteBuilder to build animation
full code
import 'package:flutter/material.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(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: HomePage(),
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/':
return SlideRightRoute(widget:HomePage());
break;
case '/second':
return SlideRightRoute(widget:SecondHome());
break;
}
}
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: new Center(
child: RaisedButton(
onPressed: () {
Navigator.pushNamed(context, '/second');
},
child: Text('Second Home'),
),
),
);
}
}
class SecondHome extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Home'),
),
body: new Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'),
),
),
);
}
}
class SlideRightRoute extends PageRouteBuilder {
final Widget widget;
SlideRightRoute({this.widget})
: super(
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return widget;
},
transitionsBuilder: (BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
return new SlideTransition(
position: new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: child,
);
},
);
}
In Method gotoThirdScreen(), I am tryiing to pass parameters to a class.
I believe the issue starts at:
//=========================================================
//=== please put PageRouteBuilderCode here.
The Class SecondPage has... widget.title. But not sure how to pass titel from _gotoThirdPage().
This code works
//===============================
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
// Added ===
routes: <String, WidgetBuilder>{
SecondPage.routeName: (BuildContext context) => new SecondPage(title: "SecondPage"),
},
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(28.0),
child: new RaisedButton(
onPressed: _gotoSecondPage,
child: new Text("Goto SecondPage- Normal"),
),
),
Padding(
padding: const EdgeInsets.all(38.0),
child: new RaisedButton(
onPressed: _gotoThirdPage,
child: new Text("goto SecondPage = with PRB"),
),
),
new Text(
'You have pushed the button this many times:',
),
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _gotoSecondPage() {
//=========================================================
// Transition - Normal Platform Specific
print('==== going to second page ===');
print( SecondPage.routeName);
Navigator.pushNamed(context, SecondPage.routeName);
}
void _gotoThirdPage() {
//=========================================================
// I believe this is where I would be adding a PageRouteBuilder
print('==== going to second page ===');
print( SecondPage.routeName);
//Navigator.pushNamed(context, SecondPage.routeName);
//=========================================================
//=== please put PageRouteBuilderCode here.
final pageRoute = new PageRouteBuilder(
pageBuilder: (BuildContext context, Animation animation,
Animation secondaryAnimation) {
// YOUR WIDGET CODE HERE
// I need to PASS title here...
// not sure how to do this.
// Also, is there a way to clean this code up?
return new SecondPage();
},
transitionsBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return SlideTransition(
position: new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: new SlideTransition(
position: new Tween<Offset>(
begin: Offset.zero,
end: const Offset(1.0, 0.0),
).animate(secondaryAnimation),
child: child,
),
);
},
);
Navigator.of(context).push(pageRoute);
}
}
class SecondPage extends StatefulWidget {
SecondPage({Key key, this.title}) : super(key: key);
static const String routeName = "/SecondPage";
final String title;
#override
_SecondPageState createState() => new _SecondPageState();
}
/// // 1. After the page has been created, register it with the app routes
/// routes: <String, WidgetBuilder>{
/// SecondPage.routeName: (BuildContext context) => new SecondPage(title: "SecondPage"),
/// },
///
/// // 2. Then this could be used to navigate to the page.
/// Navigator.pushNamed(context, SecondPage.routeName);
///
class _SecondPageState extends State<SecondPage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
//======== HOW TO PASS widget.title ===========
title: new Text(widget.title),
//title: new Text('==== second page ==='),
),
body: new Container(),
floatingActionButton: new FloatingActionButton(
onPressed: _onFloatingActionButtonPressed,
tooltip: 'Add',
child: new Icon(Icons.add),
),
);
}
void _onFloatingActionButtonPressed() {
}
}
you can use onGenerateRoute here the example
main.dart
void main() {
runApp(new App());
}
app.dart
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new HomeScreen(),
routes: <String, WidgetBuilder>{
'/home': (BuildContext context) => new HomeScreen(),
//other routes
},
//onGenerateRoute Custom
onGenerateRoute: getGenerateRoute);
}
}
Route<Null> getGenerateRoute(RouteSettings settings) {
final List<String> path = settings.name.split('/');
if (path[0] != '') return null;
if (path[1].startsWith('team')) {
if (path.length != 3) return null;
String _title = path[2];
return new MaterialPageRoute<Null>(
settings: settings,
builder: (BuildContext context) => new TeamScreen(
title: _title,
),
);
}
// The other paths we support are in the routes table.
return null;
}
home_screen.dart
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Home Screen'),
),
body: new Center(
child: new Column(
children: <Widget>[
new RaisedButton(
onPressed: () {
String _title = "Team 1";
Navigator.pushNamed(context, '/team/$_title');
},
child: new Text('Go Team 1'),
),
new RaisedButton(
onPressed: () {
String _title = "Team 2";
Navigator.pushNamed(context, '/team/$_title');
},
child: new Text('Go Team 2'),
)
],
),
),
);
}
}
team.dart
import 'package:flutter/material.dart';
class TeamScreen extends StatelessWidget {
final String title;
const TeamScreen({Key key, this.title}) : super(key: key);
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Team screen'),
),
body: new Center(
child: new Text(title),
),
);
}
}
Pass title value to SecondPage constructor:
void _gotoThirdPage() {
String page_title = "Yet Another Page";
final pageRoute = new PageRouteBuilder(
pageBuilder: (BuildContext context, Animation animation,
Animation secondaryAnimation) {
return new SecondPage(title: page_title);
},