how to unfocus texfield and hide keybaord on paste flutter - flutter

I have a textfield on which i mostly paste content so i want to unfocus textfield and hide keybaord on paste so i have achive to handle on paste using textfield selectionControls but the problem is focusing and keybaord which is reopening i have tired all focus methods to unfocus here is my code
import 'package:flutter/material.dart';
main() => runApp(const App());
class App extends StatelessWidget {
const App({super.key});
#override
Widget build(BuildContext context) {
return const MaterialApp(home: Home());
}
}
class Home extends StatelessWidget {
const Home({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(8),
child: Center(
child: TextField(
selectionControls: MySelectionControls(
onPaste: () {
print('onPaste');
// FocusManager.instance.primaryFocus?.unfocus();
// Focus.of(context).unfocus();
// FocusScope.of(context).unfocus();
// FocusScope.of(context).requestFocus(FocusNode());
// FocusScopeNode currentFocus = FocusScope.of(context);
// if (!currentFocus.hasPrimaryFocus) {
// currentFocus.focusedChild?.unfocus();
// }
},
),
),
),
),
),
);
}
}
class MySelectionControls extends MaterialTextSelectionControls {
final Function onPaste;
MySelectionControls({required this.onPaste});
#override
Future<void> handlePaste(TextSelectionDelegate delegate) {
onPaste();
return super.handlePaste(delegate);
}
}

Try this one
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Home(),
);
}
}
class Home extends StatefulWidget {
const Home({key});
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
TextSelectionControls? _textSelectionControls;
#override
void initState() {
// TODO: implement initState
super.initState();
_textSelectionControls = MySelectionControls(onPaste: onPaste);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(8),
child: Center(
child: Column(
children: [
TextField(
selectionControls: _textSelectionControls,
),
],
),
),
),
),
);
}
Future<void> onPaste(final TextSelectionDelegate? delegate) async {
Future.delayed(Duration(milliseconds: 100), () {
FocusScope.of(context).requestFocus(FocusNode());
});
}
}
class MySelectionControls extends MaterialTextSelectionControls {
MySelectionControls({required this.onPaste});
ValueChanged<TextSelectionDelegate> onPaste;
#override
Future<void> handlePaste(TextSelectionDelegate delegate) async {
onPaste(delegate);
return super.handlePaste(delegate);
}
}
I have tested this and its working

Related

How can I get my flutter video player to work for Chrome Web, correctly

I am getting videoplayer overflow. How do I resize my video player, so it correctly works. Error message "A RenderFlex overflowed by 93 pixels on the right" during window resizing.
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:provider/provider.dart';
class VolumeManager with ChangeNotifier{
var _volume=50.0;
double get volume=>_volume;
void setVolume({
required double volumeValue,
required VideoPlayerController controller
}){
_volume=volumeValue;
controller.setVolume(_volume);
notifyListeners();
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test Video',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home:
ChangeNotifierProvider(create:(context)=>VolumeManager(),child: Test_LoadVideoWidget()),
);
}
}
class Test_LoadVideoWidget extends StatefulWidget {
Test_LoadVideoWidget({Key? key}) : super(key: key);
#override
State<Test_LoadVideoWidget> createState() => _Test_LoadVideoWidgetState();
}
class _Test_LoadVideoWidgetState extends State<Test_LoadVideoWidget> {
late final VideoPlayerController controller;
late final Future<void>initVideo;
#override
void initState() {
// TODO: implement initState
super.initState();
controller=VideoPlayerController.asset("assets/video/butterfly.mp4");
controller.setLooping(true);
initVideo=controller.initialize();
}
#override
void dispose() {
// TODO: implement dispose
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return FutureBuilder<void>(
future:initVideo,
builder:(context,snapshot){
if (snapshot.connectionState==ConnectionState.done){
return Test_VideoWidget(controller);
}
return Center(child:CircularProgressIndicator());
}
);
}
}
class Test_VideoWidget extends StatelessWidget {
final VideoPlayerController controller;
Test_VideoWidget(this.controller);
void _play(){
if (!controller.value.isPlaying){
controller.play();
}
}
void _pause(){
if (controller.value.isPlaying){
controller.pause();
}
}
#override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title:Text("Test Video",style:Theme.of(context).textTheme.headline2)),
body:
Container(
width:MediaQuery.of(context).size.width,
//height:MediaQuery.of(context).size.height,
padding:EdgeInsets.all(20),child:
Column(
mainAxisAlignment:MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AspectRatio(aspectRatio: controller.value.aspectRatio,
child:VideoPlayer(controller),
),
Row(children: [
SizedBox(width:200,child:ElevatedButton(onPressed: (){_play();}, child: Text("Play!",style:Theme.of(context).textTheme.button))),
const SizedBox(height:50,width:200),
SizedBox(width:200,child:ElevatedButton(onPressed:(){_pause();}, child:Text("Pause",style:Theme.of(context).textTheme.button))),
],)
,Consumer<VolumeManager>(
builder:(context,manager,_)
=>Slider(
min: 0,
max: 100,
value: manager.volume,
onChanged: (value) =>
{
manager.setVolume(volumeValue: value, controller: controller)
}
),
)
],)
)
);
}
}
solution: I used SingleChildScrollView to solve the horizontal and vertical renderflex overflow errors. I changed the Consumer to use => notation rather than { return notation.
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:provider/provider.dart';
class VolumeManager with ChangeNotifier{
var _volume=50.0;
double get volume=>_volume;
void setVolume({
required double volumeValue,
required VideoPlayerController controller
}){
_volume=volumeValue;
controller.setVolume(_volume);
notifyListeners();
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test Video',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home:
ChangeNotifierProvider(create:(context)=>VolumeManager(),child: Test_LoadVideoWidget()),
);
}
}
class Test_LoadVideoWidget extends StatefulWidget {
Test_LoadVideoWidget({Key? key}) : super(key: key);
#override
State<Test_LoadVideoWidget> createState() => _Test_LoadVideoWidgetState();
}
class _Test_LoadVideoWidgetState extends State<Test_LoadVideoWidget> {
late final VideoPlayerController controller;
late final Future<void>initVideo;
#override
void initState() {
// TODO: implement initState
super.initState();
controller=VideoPlayerController.asset("assets/video/butterfly.mp4");
//..initialize().then((_){
//controller.play();
//controller.setLooping(true);
setState(() {
});
//});
initVideo = controller.initialize();
}
#override
void dispose() {
// TODO: implement dispose
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
//return Test_VideoWidget(controller);
return FutureBuilder<void>(
future:initVideo,
builder:(context,snapshot){
if (snapshot.connectionState==ConnectionState.done){
return Test_VideoWidget(controller);
}
return Center(child:CircularProgressIndicator());
}
);
}
}
class Test_VideoWidget extends StatelessWidget {
final VideoPlayerController controller;
Test_VideoWidget(this.controller);
void _play(){
if (!controller.value.isPlaying){
controller.play();
}
}
void _pause(){
if (controller.value.isPlaying){
controller.pause();
}
}
#override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title:Text("Test Video",style:Theme.of(context).textTheme.headline2)),
body:
// controller.value.isInitialized?
Container(
width:MediaQuery.of(context).size.width,
height:MediaQuery.of(context).size.height,
padding:EdgeInsets.all(20),child:
SingleChildScrollView(child:Column(
mainAxisAlignment:MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AspectRatio(aspectRatio: controller.value.aspectRatio,
child:VideoPlayer(controller),
),
SingleChildScrollView(scrollDirection: Axis.horizontal, child: Row(children: [
SizedBox(width:200,child:ElevatedButton(onPressed: (){_play();}, child: Text("Play!",style:Theme.of(context).textTheme.button))),
const SizedBox(height:50,width:200),
SizedBox(width:200,child:ElevatedButton(onPressed:(){_pause();}, child:Text("Pause",style:Theme.of(context).textTheme.button))),
],))
,Consumer<VolumeManager>(
builder:(context,manager,_)=>
Slider(
min: 0,
max: 50,
value: manager.volume,
onChanged: (value) =>
{
manager.setVolume(volumeValue: value, controller: controller)
}
),
)
],)
)
//:
// Center(child:CircularProgressIndicator()),
));
}
}

Flutter: Continuation of the future

I go from page 1 to page 2. The counting process starts on page 2. As this continues, I return to page 1. Even if I exit page 2, the process continues. Why is this happening? How can I prevent this?
Future.delayed keeps working when I return to page 1 from page 2.
This is page 1. There is only one button to go to page 2.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:untitled1/page2.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.black38,
),
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => Page2()));
},
child: Text(
'Page 2',
),
),
],
),
),
);
}
}
This is page 2.
import 'package:flutter/material.dart';
class Page2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage2(),
);
}
}
class MyHomePage2 extends StatefulWidget {
#override
_MyHomePage2State createState() => _MyHomePage2State();
}
class _MyHomePage2State extends State<MyHomePage2> {
int d=0;
#override
void initState() {
// TODO: implement initState
for (int c = 0; c < 25; c++) {
Future.delayed(Duration(seconds: c), () {
setState(() {
d++;
});
});
}
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
' $d',
),
],
),
),
);
}
}
if(!mounted){
return;
}
It happened thanks to the above. If I write one, it will probably suffice. I don't know if this is a valid solution.
void initState() {
// TODO: implement initState
for (int c = kk; c < 25; c++) {
if(!mounted){
return;
}
Future.delayed(Duration(seconds: c), () {
if(!mounted){
return;
}
setState(() {
d++;
});
});
if(!mounted){
return;
}
}
super.initState();
}

Skip a tab while switching among tabs in TabBarView

In my flutter app, I use a simple tab-bar. I used the code from the flutter website and updated to make sure that I can keep the state of each tab using AutomaticKeepAliveClientMixin.
I have 3 tabs and each tab is fetching a list of data (why I need to use AutomaticKeepAliveClientMixin) from my backend API.
The problem is that when I switch between first and 3rd tabs (Page1 and Page3), the middle tab keeps rebuilding over and over again until I switch to that tab (Page2) and only at that point it doesn't get rebuilt anymore.
Every rebuild results in fetching data from API and that's not desirable.
Below, i have included a simplified code to reproduce this issue.
You can see in the debug console once switching between 1st and 3rd tab (without switching to 2nd tab) that it keeps printing "p2" (in my real app, it keeps fetching data for the 2nd tab).
Is there a way to switch between tabs without other tabs in between being built/rebuilt?
This is my code.
import 'package:flutter/material.dart';
void main() {
runApp(TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
title: Text('Tabs Demo'),
),
body: TabBarView(
children: [
Page1(),
Page2(),
Page3(),
],
),
),
),
);
}
}
class Page1 extends StatefulWidget {
#override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1>
with AutomaticKeepAliveClientMixin<Page1> {
#override
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
super.build(context);
print('p1');
return Container(
child: Center(
child: Icon(Icons.directions_car),
),
);
}
}
class Page2 extends StatefulWidget {
#override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2>
with AutomaticKeepAliveClientMixin<Page2> {
#override
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
super.build(context);
print('p2');
return Container(
child: Center(
child: Icon(Icons.directions_transit),
),
);
}
}
class Page3 extends StatefulWidget {
#override
_Page3State createState() => _Page3State();
}
class _Page3State extends State<Page3>
with AutomaticKeepAliveClientMixin<Page3> {
#override
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
super.build(context);
print('p3');
return Container(
child: Center(
child: Icon(Icons.directions_bike),
),
);
}
}
I believe this isn't a bug with flutter, but ultimately comes down to your implementation.
Please take a look at the code I wrote for you.
import 'package:flutter/material.dart';
import 'dart:async';
class FakeApi {
Future<List<int>> call() async {
print('calling api');
await Future.delayed(const Duration(seconds: 3));
return <int>[for (var i = 0; i < 100; ++i) i];
}
}
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp() : super(key: const Key('MyApp'));
#override
Widget build(BuildContext context) => const MaterialApp(home: MyHomePage());
}
class MyHomePage extends StatelessWidget {
const MyHomePage() : super(key: const Key('MyHomePage'));
static const _icons = [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
];
#override
Widget build(BuildContext context) => DefaultTabController(
length: _icons.length,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: [for (final icon in _icons) Tab(icon: icon)],
),
title: Text('Tabs Demo'),
),
body: TabBarView(
children: [
Center(child: _icons[0]),
StaggeredWidget(_icons[1]),
Center(child: _icons[2]),
],
),
),
);
}
class StaggeredWidget extends StatefulWidget {
const StaggeredWidget(this.icon)
: super(key: const ValueKey('StaggeredWidget'));
final Icon icon;
#override
_StaggeredWidgetState createState() => _StaggeredWidgetState();
}
class _StaggeredWidgetState extends State<StaggeredWidget> {
Widget _child;
Timer _timer;
#override
void initState() {
super.initState();
_timer = Timer(const Duration(milliseconds: 150), () {
if (mounted) {
setState(() => _child = MyApiWidget(widget.icon));
}
});
}
#override
void dispose() {
_timer.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) => _child ?? widget.icon;
}
class MyApiWidget extends StatefulWidget {
const MyApiWidget(this.icon, [Key key]) : super(key: key);
final Icon icon;
#override
_MyApiWidgetState createState() => _MyApiWidgetState();
}
class _MyApiWidgetState extends State<MyApiWidget>
with AutomaticKeepAliveClientMixin {
final _api = FakeApi();
#override
Widget build(BuildContext context) {
print('building `MyApiWidget`');
super.build(context);
return FutureBuilder<List<int>>(
future: _api(),
builder: (context, snapshot) => !snapshot.hasData
? const Center(child: CircularProgressIndicator())
: snapshot.hasError
? const Center(child: Icon(Icons.error))
: ListView.builder(
itemBuilder: (context, index) => ListTile(
title: Text('item $index'),
),
),
);
}
#override
bool get wantKeepAlive => true;
}

Focus first focusable element below a Focus widget

I am trying to focus the first focusable element below a Focus widget. Consider the following artifical example. It contains a BarWidget with some TextField.
The FooWidget wraps it into a Focus widget with the given focusNode. After one second, I'd like to focus the first element of BarWidget. Please not that I don't want to pass a FocusNode down into BarWidget.
import 'package:flutter/material.dart';
void main() {
runApp(Foo());
}
class Foo extends StatefulWidget {
#override
State createState() => FooState();
}
class FooState extends State<Foo> {
final focusNode = FocusNode();
void initState() {
super.initState();
Future.delayed(
const Duration(seconds: 1),
focusNode.requestFocus,
);
}
#override
Widget build(BuildContext context) => MaterialApp(
home: Scaffold(
body: Focus(
focusNode: focusNode,
child: BarWidget(),
),
),
);
}
class BarWidget extends StatelessWidget {
#override
Widget build(BuildContext context) => Column(
children: [
Text("Foo"),
TextField(),
Text("Bar"),
],
);
}
It is in theory possible by using FocusTraversalPolicy.sortDescendants. However, that method is declared as #protected. See: https://github.com/flutter/flutter/issues/70534
Full example:
import 'package:flutter/material.dart';
void main() {
runApp(Foo());
}
class Foo extends StatefulWidget {
#override
State createState() => FooState();
}
class FooState extends State<Foo> {
final focusNode = FocusNode(canRequestFocus: false);
void initState() {
super.initState();
void f() {
final policy = FocusTraversalGroup.of(focusNode.context);
// ignore: invalid_use_of_protected_member
final node = policy.sortDescendants(focusNode.traversalDescendants, null).first;
node.requestFocus();
}
Future.delayed(
const Duration(seconds: 1),
f,
);
}
#override
Widget build(BuildContext context) => MaterialApp(
home: Scaffold(
body: Focus(
focusNode: focusNode,
child: BarWidget(),
),
),
);
}
class BarWidget extends StatelessWidget {
#override
Widget build(BuildContext context) => Column(
children: [
Text("Foo"),
TextField(),
Text("Bar"),
],
);
}

Flutter switch between fragments by supporting back to previous fragment

in this link in SF, #martinseal1987 show us how can we use separated widgets link with android fragments.
I implemented this solution on my project and after running project i dont have any problem to show first widgets as an Fragment, but when i press to back button my screen goes to black and couldn't back to previous widgets as an fragment
i think that is should be this:
Problem is on navigateBack and customPop methods and i can attach fragment by pressing on button
import 'package:flutter/material.dart';
void main()
{
runApp(MaterialApp(
title: 'AndroidMonks',
home: Scaffold(
appBar: AppBar(
title: Text('Androidmonks'),
backgroundColor: Colors.orangeAccent,
),
body: Home(),
),
));
}
class Home extends StatefulWidget {
Home({
Key key,
}) : super(key: key);
#override
State<Home> createState()=>_Home();
}
class _Home extends State<Home> {
String title = "Title";
int _currentIndex = 0;
final List<int> _backstack = [0];
#override
Widget build(BuildContext context) {
navigateTo(_currentIndex);
//each fragment is just a widget which we pass the navigate function
List<Widget> _fragments =[Fragment1(),Fragment2(),Fragment3()];
//will pop scope catches the back button presses
return WillPopScope(
onWillPop: () {
customPop(context);
},
child: Scaffold(
body: Column(
children: <Widget>[
RaisedButton(
child:Text('PRESS'),
onPressed: (){
_currentIndex++;
navigateTo(_currentIndex);
},
),
Expanded(
child: _fragments[_currentIndex],
),
],
),
),
);
}
void navigateTo(int index) {
_backstack.add(index);
setState(() {
_currentIndex = index;
});
_setTitle('$index');
}
void navigateBack(int index) {
setState(() {
_currentIndex = index;
});
_setTitle('$index');
}
customPop(BuildContext context) {
if (_backstack.length - 1 > 0) {
navigateBack(_backstack[_backstack.length - 1]);
} else {
_backstack.removeAt(_backstack.length - 1);
Navigator.pop(context);
}
}
//this method could be called by the navigate and navigate back methods
_setTitle(String appBarTitle) {
setState(() {
title = appBarTitle;
});
}
}
class Fragment2 extends StatefulWidget {
#override
State<Fragment2> createState() => _Fragment2();
}
class _Fragment2 extends State<Fragment2> {
#override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text("_Fragment2"),
onPressed: (){
}),
);
}
}
class Fragment1 extends StatefulWidget {
#override
State<Fragment1> createState() => _Fragment1();
}
class _Fragment1 extends State<Fragment1> {
#override
Widget build(BuildContext context) {
return Center(
child: Text("_Fragment1"),
);
}
}
class Fragment3 extends StatefulWidget {
#override
State<Fragment3> createState() => _Fragment3();
}
class _Fragment3 extends State<Fragment3> {
#override
Widget build(BuildContext context) {
return Center(
child: Text("_Fragment3"),
);
}
}
I fixed some logic in your code please carefully check the changes, if you have any question don't hesitate, here is the working code
import 'package:flutter/material.dart';
void main()
{
runApp(MaterialApp(
title: 'AndroidMonks',
home: Scaffold(
appBar: AppBar(
title: Text('Androidmonks'),
backgroundColor: Colors.orangeAccent,
),
body: Home(),
),
));
}
class Home extends StatefulWidget {
Home({
Key key,
}) : super(key: key);
#override
State<Home> createState()=>_Home();
}
class _Home extends State<Home> {
String title = "Title";
List<Widget> _fragments =[Fragment1(),Fragment2(),Fragment3()];
int _currentIndex = 0;
final List<int> _backstack = [0];
#override
Widget build(BuildContext context) {
//navigateTo(_currentIndex);
//each fragment is just a widget which we pass the navigate function
//will pop scope catches the back button presses
return WillPopScope(
onWillPop: () {
return customPop(context);
},
child: Scaffold(
body: Column(
children: <Widget>[
RaisedButton(
child:Text('PRESS'),
onPressed: (){
_currentIndex++;
navigateTo(_currentIndex);
},
),
Expanded(
child: _fragments[_currentIndex],
),
],
),
),
);
}
void navigateTo(int index) {
_backstack.add(index);
setState(() {
_currentIndex = index;
});
_setTitle('$index');
}
void navigateBack(int index) {
setState(() {
_currentIndex = index;
});
_setTitle('$index');
}
Future<bool> customPop(BuildContext context) {
print("CustomPop is called");
print("_backstack = $_backstack");
if (_backstack.length > 1) {
_backstack.removeAt(_backstack.length - 1);
navigateBack(_backstack[_backstack.length - 1]);
return Future.value(false);
} else {
return Future.value(true);
}
}
//this method could be called by the navigate and navigate back methods
_setTitle(String appBarTitle) {
setState(() {
title = appBarTitle;
});
}
}
class Fragment2 extends StatefulWidget {
#override
State<Fragment2> createState() => _Fragment2();
}
class _Fragment2 extends State<Fragment2> {
#override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text("_Fragment2"),
onPressed: (){
}),
);
}
}
class Fragment1 extends StatefulWidget {
#override
State<Fragment1> createState() => _Fragment1();
}
class _Fragment1 extends State<Fragment1> {
#override
Widget build(BuildContext context) {
return Center(
child: Text("_Fragment1"),
);
}
}
class Fragment3 extends StatefulWidget {
#override
State<Fragment3> createState() => _Fragment3();
}
class _Fragment3 extends State<Fragment3> {
#override
Widget build(BuildContext context) {
return Center(
child: Text("_Fragment3"),
);
}
}
You can achieve this type of navigation using LocalHistoryRoute.of(context).addLocalHistoryEntry and Navigator.pop().