New to programming and dart/flutter .
Thank You.
So 2 buttons Me! and You! , I have to hide and show me! button clicking on You! button .
So can any one help me to find solution of my question.
and what if i have more numbers of buttons and show/hide all of them using a single button.
My 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(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
),
MaterialButton(
onPressed: () {},
child: Text('You!'),
color: Colors.red,
)
],
),
),
);
}
}
use a Visibility Widget.
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(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool isVisible = true; //will be visible for the first frame
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
Visibility(
visible: isVisible,
child: MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
),
),
MaterialButton(
onPressed: () {
setState(() {
isVisible = !isVisible;
});
},
child: Text('You!'),
color: Colors.red,
)
],
),
),
);
}
}
Here are 3 examples.
1
class _MyHomePageState extends State<MyHomePage> {
bool hide = false;
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
if(!hide)MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
),
MaterialButton(
onPressed: () {
setState((){
hide = !hide;
});
},
child: Text('${hide ? "Show" : "Hide"}'),
color: Colors.red,
)
],
),
),
);
}
}
2
class _MyHomePageState extends State<MyHomePage> {
bool hide = false;
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
Opacity(
opacity: hide ? 0 : 1,
child: MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
)
),
MaterialButton(
onPressed: () {
setState((){
hide = !hide;
});
},
child: Text('${hide ? "Show" : "Hide"}'),
color: Colors.red,
)
],
),
),
);
}
}
3 (Adding animation)
class _MyHomePageState extends State<MyHomePage> {
bool hide = false;
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
AnimatedOpacity(
opacity: hide ? 0 : 1,
duration: Duration(seconds: 2),
child: MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
)
),
MaterialButton(
onPressed: () {
setState((){
hide = !hide;
});
},
child: Text('${hide ? "Show" : "Hide"}'),
color: Colors.red,
)
],
),
),
);
}
}
Note: The first example will remove the button from the widget tree. For the second and third, the button will be in the widget tree but won't be visible.
So you can see it as:
First example: The button is GONE.
Second example: The button is INVISIBLE.
Related
Executed program picture I need help. I want to make the button click circular instead of rectangular.
This is the flutter dart code that I've provided, I want to know what attribute I should change or insert for making my question possible.
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(MaterialApp(
title: 'Ask me anything',
home: Scaffold(
appBar: AppBar(
title: Text('Ask me anything'),
centerTitle: true,
backgroundColor: Colors.blue[700],
),
backgroundColor: Colors.blue[800],
body: MyApp(),
),
));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int ballNumber = 1;
#override
Widget build(BuildContext context) {
return Center(
child: Expanded(
child: TextButton(
style: ButtonStyle(enableFeedback: true,shape: ),
onPressed: () => setState(() {
ballNumber = Random().nextInt(5) + 1;
}),
child: Image.asset(
'images/ball$ballNumber.png',
width: 400,
// height: 200,
),
),
));
}
}
You can either change button style, or just wrap the image with GestureDetector.
Round Button
ElevatedButton(
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(50),
),
onPressed: () {},
child: const FittedBox(
child: Text('Round Button'),
),
),
ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<CircleBorder>(
const CircleBorder(),
),
padding: MaterialStateProperty.all<EdgeInsets>(
const EdgeInsets.all(50),
),
),
onPressed: () {},
child: const FittedBox(
child: Text('Round Button'),
),
),
GestureDetector
GestureDetector(
onTap: () {
setState(() {
ballNumber = Random().nextInt(5) + 1;
});
},
child: Image.asset('images/ball$ballNumber.png'),
),
As shown in the below Image.
I want an image at the bottom of the stack, a container above it and a transparent text widget above them. I'm unable to figure out any solution, please help!
Found a solution, works like a charm
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
class Penumbra extends StatefulWidget {
Penumbra({Key key}) : super(key: key);
#override
_PenumbraState createState() => _PenumbraState();
}
class _PenumbraState extends State<Penumbra> {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
body: Stack(
children: [
Row(
children: [
Container(
width: size.width / 2,
height: double.maxFinite,
color: Color(0xff181818),
),
Container(
width: size.width / 2,
height: double.maxFinite,
color: Colors.white,
)
],
),
SingleChildScrollView(
child: Column(
children: [
Container(
height: size.height,
),
ImageShaderWidget(),
Container(
height: size.height,
),
],
),
),
],
));
}
}
class ImageShaderWidget extends StatelessWidget {
#override
Widget build(BuildContext context) => Container(
child: FutureBuilder<TextStyle>(
future: loadImage(
TextStyle(fontSize: 104.0, fontWeight: FontWeight.w900)),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else {
return Text(
"Penumbra",
style: snapshot.data,
);
}
},
),
);
Future<TextStyle> loadImage(TextStyle textStyle) async {
final imageBytes = await rootBundle.load('../assets/images/background.jpg');
ui.Image img = await decodeImageFromList(imageBytes.buffer.asUint8List());
Float64List matrix4 = new Matrix4.identity().storage;
return textStyle.copyWith(
foreground: Paint()
..shader =
ImageShader(img, TileMode.mirror, TileMode.mirror, matrix4));
}
}
I'm relatively new to Flutter and have tried to find similar postings to help me but haven't had any luck in getting them to work for me unfortunately. I have an Android Studio program that's basically a game which involves a grid of flip cards. I have the flip cards in one dart file and the app bar in another. I have an iconbutton on the app bar which currently reduces the point count to zero, but I would also like for it to flip all of the flip cards back to their original positions when pressed. I have a global variable called resetBool that I've been trying to use, something like if resetBool == true then toggleCard() maybe. I think I might need to use a key but am having trouble implementing one properly.
Here is the code in the file which contains my appbar:
import 'package:flip_card/flip_card.dart';
import 'package:flutter/material.dart';
import 'gridone.dart' as gridone;
import 'globalVariables.dart';
import 'statenames.dart';
int count;
StateNames stateObject = new StateNames();
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home>with SingleTickerProviderStateMixin {
TabController controller;
#override
void initState() {
controller = new TabController(length: 1, vsync: this);
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
void changeCount() {
setState(() {
counter += 1;
});
}
void decreaseCount() {
setState(() {
counter -= 1;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title:new Text("License plate game"),
backgroundColor: Colors.greenAccent,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.autorenew,
color: Colors.white,
),
onPressed: () {
setState(() {
counter = 0;
resetBool = true;
});
},
),
Center(
child: Container(
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
child: Text('points: $counter', textAlign: TextAlign.center, style: TextStyle(fontSize: 15),
)
),
),
],
bottom: new TabBar(
controller: controller,
indicatorWeight: 5.0,
indicatorColor: Colors.green,
tabs: <Widget> [
new Tab(icon: new Icon(Icons.image),),
],
),
),
body: new TabBarView(
controller: controller,
children: <Widget>[
new gridone.GridOne(changeCount, decreaseCount),
],
)
);
}
}
And here is the code in the file which contains my flip cards:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flip_card/flip_card.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'statenames.dart';
import 'globalVariables.dart';
import 'Home.dart';
import 'gridtwo.dart' as gridTwo;
StateNames stateObject = new StateNames();
Home homeObject = new Home();
class GridOne extends StatefulWidget {
final Function updateCounter;
final Function decreaseCount;
GridOne(this.updateCounter, this.decreaseCount);
#override
_GridOneState createState() => _GridOneState();
}
class _GridOneState extends State<GridOne>
with AutomaticKeepAliveClientMixin {
#override
bool get wantKeepAlive => true;
int points = 0;
#override
Widget build(BuildContext context) {
super.build(context);
return new Scaffold(
body: new Column(
children: <Widget> [
new Expanded(
child: GridView.count(
crossAxisCount: 5,
children: List.generate(52, (index){
return Card(
elevation: 0.0,
margin: EdgeInsets.only(left: 3.0, right: 3.0, top: 9.0, bottom: 0.0),
color: Color(0x00000000),
child: FlipCard(
direction: FlipDirection.HORIZONTAL,
speed: 1000,
//(resetBool == true) ? cardKey.currentState.toggleCard() : null,
onFlipDone: (status) {
setState(() {
(status)
? widget.decreaseCount()
: widget.updateCounter();
});
if (counter == 25) {
Fluttertoast.showToast(
msg: "You've got 25 states! Wow!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM_LEFT,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
};
print(counter);
},
front: Container(
decoration: BoxDecoration(
color: Color(0xFF006666),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FittedBox(fit:BoxFit.fitWidth,
child: Text(stateObject.stateNames[index], style: TextStyle(fontFamily: 'Architects Daughter', color: Colors.white), )
//Theme.of(context).textTheme.headline
),
Text('',
style: Theme.of(context).textTheme.body1),
],
),
),
back: Container(
decoration: BoxDecoration(
color: Color(0xFF006666),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image(image: AssetImage(stateObject.licensePlatePaths[index])),
//Text('',
//style: Theme.of(context).textTheme.body1),
],
),
),
),
);
})
)
)
]
),
);
}
}
The solution is to use currentState.toggleCard(); for the cards that are facing Back when the IconButton is clicked.
Basically, what I did is I gave keys to each card at initState method.
List<GlobalKey<FlipCardState>> cardKeys = [];
#override
void initState() {
List.generate(52, (index) {
cardKeys.add(GlobalKey<FlipCardState>());
});
super.initState();
}
Don't forget to put the key to widget
FlipCard(key: cardKeys[index], ... )
Then, call resetCards method below when the button is clicked. If the card is facing back then toggle logic.
void resetCards() {
cardKeys.forEach((element) {
if (!element.currentState.isFront) {
element.currentState.toggleCard();
}
});
setState(() {});
}
You need to call a method on the parent widget, that would be triggered in the child widget. For that, please check this stackoverflow link
Full working code:
import 'package:flutter/material.dart';
import 'package:flip_card/flip_card.dart';
import 'package:fluttertoast/fluttertoast.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,
// This makes the visual density adapt to the platform that you run
// the app on. For desktop platforms, the controls will be smaller and
// closer together (more dense) than on mobile platforms.
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Home(),
);
}
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
TabController controller;
int counter = 0;
final GridOneController myController = GridOneController();
#override
void initState() {
controller = new TabController(length: 1, vsync: this);
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
void changeCount() {
setState(() {
counter += 1;
});
}
void decreaseCount() {
setState(() {
counter -= 1;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("License plate game"),
backgroundColor: Colors.greenAccent,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.autorenew,
color: Colors.white,
),
onPressed: () {
setState(() {
counter = 0;
myController.resetCards();
});
},
),
Center(
child: Container(
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
child: Text(
'points: $counter',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 15),
)),
),
],
bottom: new TabBar(
controller: controller,
indicatorWeight: 5.0,
indicatorColor: Colors.green,
tabs: <Widget>[
new Tab(
icon: new Icon(Icons.image),
),
],
),
),
body: new TabBarView(
controller: controller,
children: <Widget>[
new GridOne(counter, myController),
],
));
}
}
class GridOneController {
void Function() resetCards;
}
class GridOne extends StatefulWidget {
int counter;
final GridOneController controller;
GridOne(this.counter, this.controller);
#override
_GridOneState createState() => _GridOneState(controller);
}
class _GridOneState extends State<GridOne> {
_GridOneState(GridOneController _controller) {
_controller.resetCards = resetCards;
}
int points = 0;
void increaseCounter() {
widget.counter += 1;
}
void decreaseCounter() {
widget.counter -= 1;
}
void resetCards() {
cardKeys.forEach((element) {
if (!element.currentState.isFront) {
element.currentState.toggleCard();
}
});
setState(() {});
}
List<GlobalKey<FlipCardState>> cardKeys = [];
#override
void initState() {
List.generate(52, (index) {
cardKeys.add(GlobalKey<FlipCardState>());
});
super.initState();
}
#override
Widget build(BuildContext context) {
print(cardKeys.length);
return new Scaffold(
body: new Column(children: <Widget>[
new Expanded(
child: GridView.count(
crossAxisCount: 5,
children: List.generate(52, (index) {
return Card(
elevation: 0.0,
margin: EdgeInsets.only(
left: 3.0, right: 3.0, top: 9.0, bottom: 0.0),
color: Color(0x00000000),
child: new FlipCard(
key: cardKeys[index],
direction: FlipDirection.HORIZONTAL,
speed: 1000,
onFlipDone: (status) {
setState(() {
(status) ? decreaseCounter() : increaseCounter();
});
if (widget.counter == 25) {
Fluttertoast.showToast(
msg: "You've got 25 states! Wow!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM_LEFT,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
}
;
print(widget.counter);
},
front: Container(
decoration: BoxDecoration(
color: Color(0xFF006666),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FittedBox(
fit: BoxFit.fitWidth,
child: Text(
'FRONT',
style: TextStyle(color: Colors.white),
)
//Theme.of(context).textTheme.headline
),
Text(
'',
),
],
),
),
back: Container(
decoration: BoxDecoration(
color: Color(0xFF006666),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Text('BACK')],
),
),
),
);
})))
]),
);
}
}
I'd like to make a widget that sticks to the bottom of the page, and then is pinned to the top of the keyboard (when it appears).
Note how the input textfield is pinned to the keyboard in the image below:
How would I do this? I tried putting it in the bottomNavigationBar, but this (obviously) didn't work. Is there a builtin way to do this?
This is a working example of the thing you want. I think!
Just copy/paste/run
What's important in this example is the Expanded. A really nice widget that expands to as much space as it can get. And in result pushing the chat box down as much as possible
(Bottom of the screen or bottom of the keyboard)
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'),
);
}
}
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> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('49715760 Stackoverflow'),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Expanded(
child: new Material(
color: Colors.red,
child: new Text("Filled"),
),
),
new Container(
color: Colors.white,
padding: new EdgeInsets.all(10.0),
child: new TextField(
decoration: new InputDecoration(
hintText: 'Chat message',
),
),
),
],
),
);
}
}
The best way to resolve this is to use a dedicated widget.
MediaQuery.of(context).viewInsets.bottom will give you the value of the height covered by the system UI(in this case the keyboard).
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
var home = MyHomePage(title: 'Flutter Demo Home Page');
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: home,
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text(widget.title),
),
body: _getBody(),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
Widget _getBody() {
return Stack(children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/sample.jpg"), fit: BoxFit.fitWidth)),
// color: Color.fromARGB(50, 200, 50, 20),
child: Column(
children: <Widget>[TextField()],
),
),
Positioned(
bottom: MediaQuery.of(context).viewInsets.bottom,
left: 0,
right: 0,
child: Container(
height: 50,
child: Text("Hiiiii"),
decoration: BoxDecoration(color: Colors.pink),
),
),
]);
}
}
there is a lib for that:
https://pub.dev/packages/keyboard_attachable
Widget build(BuildContext context) => FooterLayout(
footer: MyFooterWidget(),
child: PageMainContent(),
);
use of bottomSheet option from Scaffold.
Scaffold(
bottomSheet: chatBar(),
body: Column(
children: [
Expanded(
child: ListView()
)
]
)
)
the chatBar is top of keyboard, when keyboard is open.
for transparent chatBar: can wrap Scaffold by
Theme(
data: ThemeData.light().copyWith(
bottomSheetTheme: BottomSheetThemeData(backgroundColor: Colors.transparent),
),
This worked for me,
showBottomSheet(
context: context,
builder: (context) => Container(
height: // YOUR WIDGET HEIGHT
child: // YOUR CHILD
)
showBottomSheet is a flutter inbuilt function.
How can I make a Card in Flutter that overlaps the AppBar? Negative margins are not possible as far as I know.
See the image for clarity.
For one card it could be easily done with Stack widget
E.g.
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
Home({Key key}) : super(key: key);
#override
HomeState createState() {
return new HomeState();
}
}
class HomeState extends State<Home> {
bool _hasCard;
#override
void initState() {
super.initState();
_hasCard = false;
}
#override
Widget build(BuildContext context) {
List<Widget> children = new List();
children.add(_buildBackground());
if (_hasCard) children.add(_buildCard());
return MaterialApp(
home: Stack(
children: children,
),
);
}
void _showCard() {
setState(() => _hasCard = true);
}
void _hideCard() {
setState(() => _hasCard = false);
}
Widget _buildCard() => new Container(
child: new Center(
child: new Container(
height: 700.0,
width: 200.0,
color: Colors.lightBlue,
child: new Center(
child: new Text("Card"),
),
),
),
);
Widget _buildBackground() => new Scaffold(
appBar: new AppBar(
title: new Text("AppBar"),
),
body: new Container(
child: _hasCard
? new FlatButton(
onPressed: _hideCard, child: new Text("Hide card"))
: new FlatButton(
onPressed: _showCard, child: new Text("Show card")),
),
);
}
void main() {
runApp(
new Home(),
);
}
If there are many cards, you can wrap them into ListView.
class Sample2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Material(
child: CustomScrollView(
slivers: [
SliverPersistentHeader(
delegate: MySliverAppBar(expandedHeight: 200),
pinned: true,
),
SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => ListTile(
title: Text("Index: $index"),
),
),
)
],
),
),
);
}
}
class MySliverAppBar extends SliverPersistentHeaderDelegate {
final double expandedHeight;
MySliverAppBar({#required this.expandedHeight});
#override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return Stack(
fit: StackFit.expand,
overflow: Overflow.visible,
children: [
Image.network(
"https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
fit: BoxFit.cover,
),
Center(
child: Opacity(
opacity: shrinkOffset / expandedHeight,
child: Text(
"MySliverAppBar",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontSize: 23,
),
),
),
),
Positioned(
top: expandedHeight / 2 - shrinkOffset,
left: MediaQuery.of(context).size.width / 4,
child: Opacity(
opacity: (1 - shrinkOffset / expandedHeight),
child: Card(
elevation: 10,
child: SizedBox(
height: expandedHeight,
width: MediaQuery.of(context).size.width / 2,
child: FlutterLogo(),
),
),
),
),
],
);
}
#override
double get maxExtent => expandedHeight;
#override
double get minExtent => kToolbarHeight;
#override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
}