'how to invoke parent component AppBar back in Flutter
I am a newbie in Flutter, today I encount a problem. I want to back to my app's list main page when user using right gustures in screen. Now I could recognize the right gestures. But next I did not know how to triggger parent componnet AppBar's back event. This is my chiild component code:
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html/style.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:Cruise/src/component/part_snippet.dart';
import 'package:Cruise/src/common/helpers.dart';
import 'package:Cruise/src/models/Item.dart';
import 'package:Cruise/src/page/profile.dart';
import 'package:Cruise/src/common/Repo.dart';
import 'package:url_launcher/url_launcher.dart';
final partsProvider = FutureProvider.family((ref, int id) async {
return await Repo.fetchItem(id);
});
class StoryInformation extends HookWidget {
const StoryInformation({
Key key,
@required this.item,
}) : super(key: key);
final Item item;
void launchUrl(url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
@override
Widget build(BuildContext context) {
final parts = item.parts.map((i) => useProvider(partsProvider(i))).toList();
Offset _initialSwipeOffset;
Offset _finalSwipeOffset;
void _onHorizontalDragStart(DragStartDetails details) {
_initialSwipeOffset = details.globalPosition;
}
void _onHorizontalDragUpdate(DragUpdateDetails details) {
_finalSwipeOffset = details.globalPosition;
}
void _onHorizontalDragEnd(DragEndDetails details) {
if (_initialSwipeOffset != null) {
final offsetDifference = _initialSwipeOffset.dx - _finalSwipeOffset.dx;
final direction = offsetDifference > 0 ? print('left') : print('right');
if (offsetDifference > 0) {
// detect the right gesture, then back to main list page
}
}
}
return Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: GestureDetector(
onHorizontalDragStart: _onHorizontalDragStart,
onHorizontalDragUpdate: _onHorizontalDragUpdate,
onHorizontalDragEnd: _onHorizontalDragEnd,
child: Padding(),
),
)
}
}
and this is the parent component:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:Cruise/src/component/comment_list.dart';
import 'package:Cruise/src/component/story_information.dart';
import 'package:Cruise/src/models/Item.dart';
import 'package:Cruise/src/common/Repo.dart';
class StoryPage extends HookWidget {
const StoryPage({
Key key,
@required this.item,
}) : super(key: key);
final Item item;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cruise'),
actions: [
if (item.parent != null)
IconButton(
icon: Icon(Feather.corner_left_up),
onPressed: () async {
Item parent = await Repo.fetchItem(item.parent);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StoryPage(item: parent)),
);
},
),
],
),
body: CustomScrollView(
slivers: [
SliverToBoxAdapter(child: StoryInformation(item: item)),
CommentList(item: item)
],
),
);
}
}
I want to do is that when recognizing the user's right gestures, then back to the main list page, how to trigger the back action in child's play _onHorizontalDragEnd
function?
Solution 1:[1]
You can pass the function of the app bar back button to the StoryInformation class as a callback function and use it from there normally
void appBarBack() async {
Item parent = await Repo.fetchItem(item.parent);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StoryPage(item: parent)),
);
},
and when calling StoryInformation
StoryInformation(item: item, backFunction: appBarBack);
and from StoryInformation class
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html/style.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:Cruise/src/component/part_snippet.dart';
import 'package:Cruise/src/common/helpers.dart';
import 'package:Cruise/src/models/Item.dart';
import 'package:Cruise/src/page/profile.dart';
import 'package:Cruise/src/common/Repo.dart';
import 'package:url_launcher/url_launcher.dart';
final partsProvider = FutureProvider.family((ref, int id) async {
return await Repo.fetchItem(id);
});
class StoryInformation extends HookWidget {
const StoryInformation({
Key key,
@required this.item,
this.backFunction,
}) : super(key: key);
final Item item;
final Function backFunction;
void launchUrl(url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
@override
Widget build(BuildContext context) {
final parts = item.parts.map((i) => useProvider(partsProvider(i))).toList();
Offset _initialSwipeOffset;
Offset _finalSwipeOffset;
void _onHorizontalDragStart(DragStartDetails details) {
_initialSwipeOffset = details.globalPosition;
}
void _onHorizontalDragUpdate(DragUpdateDetails details) {
_finalSwipeOffset = details.globalPosition;
}
void _onHorizontalDragEnd(DragEndDetails details) {
if (_initialSwipeOffset != null) {
final offsetDifference = _initialSwipeOffset.dx - _finalSwipeOffset.dx;
final direction = offsetDifference > 0 ? print('left') : print('right');
if (offsetDifference > 0) {
// detect the right gesture, then back to main list page
}
}
}
return Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: GestureDetector(
onHorizontalDragStart: _onHorizontalDragStart,
onHorizontalDragUpdate: _onHorizontalDragUpdate,
onHorizontalDragEnd: (details) => backFunction(),
child: Padding(),
),
)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | omar hatem |