Related
i am currently using the hero widget for flutter. my issue is that the hero is only working when i go from profile screen to chat screen and not from chat screen to profile screen. the tags are the same but i just cannot wrap my head around why is it not working. tia for all inputs
chat screen
class _AppBarTitle extends StatelessWidget {
const _AppBarTitle({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final channel = StreamChannel.of(context).channel;
return Row(
children: [
Hero(
tag: 'community-profile-picture',
child: Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Avatar.medium(
url: Helpers.randomPictureUrl(), // can be a random image url
onTap: () {
Navigator.of(context).push(
PersonalDevelopmentProfileScreen.routeWithChannel(
channel));
}),
),
),
const SizedBox(
width: 16,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
Helpers.getChannelName(channel, context.currentUser!),
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 16,
),
),
const SizedBox(height: 2),
],
)),
Padding(
padding: const EdgeInsets.all(8),
child: IconBackground(
icon: CupertinoIcons.info_circle,
onTap: () => showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: Center(
child: Text(
'About ${Helpers.getChannelName(channel, context.currentUser!)}'),
),
content: Text(
'${Helpers.getChannelName(channel, context.currentUser!)} Description'),
actions: <Widget>[
TextButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
primary: AppColors.accent),
onPressed: () => Navigator.pop(context, 'OK'),
child: const Text('OK',
style: TextStyle(color: AppColors.secondary)),
),
],
),
),
))
],
);
}
}
scaffold for chat screen
return Scaffold(
appBar: AppBar(
leadingWidth: 54,
leading: Align(
alignment: Alignment.centerRight,
child: IconBackground(
icon: CupertinoIcons.chevron_back,
onTap: () => Navigator.of(context).push(CustomPageRoute(
child: const HomeScreen(), direction: AxisDirection.right)),
),
),
title: const _AppBarTitle(),
),
profile screen
class _AppBarTitle extends StatelessWidget {
const _AppBarTitle({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Members Of Community',
style: GoogleFonts.lato(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.black)),
const SizedBox(height: 2),
],
)),
const SizedBox(
width: 16,
),
Hero(
tag: 'community-profile-picture',
child: Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Avatar.medium(
url: Helpers.randomPictureUrl(), // can be a random image url
onTap: () => Navigator.of(context).pop()),
),
),
],
);
}
}
scaffold for profile screen
return Scaffold(
appBar: AppBar(
leadingWidth: 54,
leading: Align(
alignment: Alignment.centerRight,
child: IconBackground(
icon: CupertinoIcons.chevron_back,
onTap: () => Navigator.of(context).pop()),
),
title: const _AppBarTitle(),
),
avatar
class Avatar extends StatelessWidget {
const Avatar({
Key? key,
this.url,
required this.radius,
this.onTap,
}) : super(key: key);
const Avatar.small({
Key? key,
this.url,
this.onTap,
}) : radius = 18,
super(key: key);
const Avatar.medium({
Key? key,
this.url,
this.onTap,
}) : radius = 26,
super(key: key);
const Avatar.large({
Key? key,
this.url,
this.onTap,
}) : radius = 34,
super(key: key);
final double radius;
final String? url;
final VoidCallback? onTap;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: _avatar(context),
);
}
Widget _avatar(BuildContext context) {
if (url != null) {
return CircleAvatar(
radius: radius,
backgroundImage: CachedNetworkImageProvider(url!),
backgroundColor: Theme.of(context).cardColor,
);
} else {
return CircleAvatar(
radius: radius,
backgroundColor: Theme.of(context).cardColor,
child: Center(
child: Text(
'?',
style: TextStyle(fontSize: radius),
),
),
);
}
}
}
Provide hero top level on second widget and follow this pattern,
chat screen
class _AppBarTitle extends StatelessWidget {
const _AppBarTitle({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: row(context),
),
);
}
Row row(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Hero(
tag: 'community-profile-picture',
child: Padding(
padding: const EdgeInsets.only(bottom: 4),
child: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => _2AppBarTitle(),
),
);
},
child: Material(
child: Container(
height: 100,
width: 100,
color: Colors.green,
child: Text("tap")),
),
),
),
),
],
);
}
}
profile screen
class _2AppBarTitle extends StatelessWidget {
const _2AppBarTitle({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Hero(
tag: 'community-profile-picture',
child: Scaffold(
body: Padding(
padding: const EdgeInsets.only(bottom: 4),
child: GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: Text("pop"),
),
),
),
);
}
}
how can I show a widget (for example some more buttons) when a button is clicked.
FlatButton(
onPressed: () {
//render the new widgets
},
child: Icon(
Icons.close,
color: Colors.white,
),
));
This is the parent class
class StopStream extends StatelessWidget
You can conditionally show / hide a widget(s) with a help of a variable.
You need a StatefulWidget to change the state of a widget i.e to dynamically show / hide (widgets).
Please see the following code, I use a bool showWidget to show or hide more FlatButton's in a Row :
import 'package:flutter/material.dart';
final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
bool showWidget = false;
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
showWidget
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FlatButton(
onPressed: () {},
child: const Icon(Icons.ac_unit),
),
FlatButton(
onPressed: () {},
child: const Icon(Icons.accessible),
),
FlatButton(
onPressed: () {},
child: const Icon(Icons.backpack),
),
FlatButton(
onPressed: () {},
child: const Icon(Icons.cached),
),
],
)
: Container(),
FlatButton(
onPressed: () {
setState(() {
showWidget = !showWidget;
});
},
child: const Icon(
Icons.close,
color: Colors.white,
),
),
],
);
}
}
Have a state variable (either in State or in something like Provider or Riverpod) that will be toggled by your onPressed: callback. Then allow that variable to control whether or not the widget in question is shown or omitted from the widget tree.
You can use a bool variable Forexample in my case isSwitched and set its value to false. When the user clicks on the button, set its value to true and use conditional operator to show more widgets as follows:
class CoverScreen extends StatefulWidget {
#override
_CoverScreenState createState() => _CoverScreenState();
}
class _CoverScreenState extends State<CoverScreen> {
bool isSwitched = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 70,
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
child: Text('WELCOME'),
),
],
)),
body: Padding(
padding: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(children: <Widget>[
Container(
padding: const EdgeInsets.all(15),
child: Text(
'COVER LETTER:',
style: TextStyle(
color: Colors.teal,
fontSize: 25,
fontWeight: FontWeight.w500),
)),
Container(
child: Switch(
value: isSwitched,
onChanged: (value) {
setState(() {
isSwitched = value;
print(isSwitched);
});
},
activeTrackColor: Colors.teal,
activeColor: Colors.white,
)),
]),
Column(children: <Widget>[
isSwitched
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(10),
child: Text(
'NAME:',
style: TextStyle(
color: Colors.teal,
fontSize: 20,
fontWeight: FontWeight.w500),
)),
Container(
child: TextField(
decoration: new InputDecoration(
contentPadding:
const EdgeInsets.all(20.0),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.teal, width: 2.0),
),
hintText: 'Enter NAME'),
),
),
])
: Container(),
])
])),
);
}
}
The output for the above code is as follows:
Before button click
After Button click
I need create a card, when the FAB is clicked, like a list or just create a card into Column, like this image:
enter image description here
Here's one way:
import 'package:flutter/material.dart';
void main() async {
runApp(MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()));
}
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Widget> cardWidget = [];
buildCard() {
setState(() {
cardWidget.add(
Card(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.all(20.0),
child: TextFormField(),
),
Padding(
padding: EdgeInsets.all(20.0),
child: TextFormField(),
),
RaisedButton(
onPressed: () {},
padding: EdgeInsets.only(left: 20.0, right: 20.0, top: 10.0, bottom: 10.0),
color: Colors.green,
child: Text(
'Criar',
style: TextStyle(
color: Colors.white
),
),
)
],
),
)
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue[900],
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.blue[900]
),
floatingActionButton: FloatingActionButton(
onPressed: buildCard,
backgroundColor: Colors.green,
child: Icon(
Icons.add,
color: Colors.white,
),
),
body: Column(
children: cardWidget.map((data) {
return data;
}).toList()
),
);
}
}
This method may not be the best way for you so I encourage you to try something new on your own!
I have a Stateful widget:
class PractiseInterview extends StatefulWidget {
#override
_PractiseInterviewState createState() => _PractiseInterviewState();
}
class _PractiseInterviewState extends State<PractiseInterview> {
String outputText = '0';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Practise'),
),
body: Container(
child: Column(
children: <Widget>[
Text(
outputText, //**outputText is here**
),
Expanded(
child: Divider(),
),
Column(
children: <Widget>[
Row(
children: <Widget>[
ChnageText(text: 'changed',),
],
),
],
)
],
),
),
);
}
}
NOTICE that my outputText = '0' here.
Then I have a stateless widget for my OutlineButton in stateful widget:
class ChnageText extends StatelessWidget {
const ChnageText({ this.text});
final String text;
buttonPressed(String text) {
if (text == 'changed') {
//TODO: change outputText value to 'changed' at the click of this button
}
}
#override
Widget build(BuildContext context) {
return Expanded(
child: OutlineButton(
onPressed: () {
buttonPressed(text);
},
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Text(
text,
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
}
I have mentioned TODO in my stateless widget, there at the click of the button I want to change outputText = '0' to outputText = 'changed'. I don't know how to do this
I am new to flutter and I am not able to understand this. Basically I am making a calculator where when a button is clicked, then the value of the button should be displayed.
Pass a callback to ChnageText from the parent that changes outputText and calls setState.
class ChnageText extends StatelessWidget {
const ChnageText({this.text, this.callback});
final String text;
final VoidCallback callback;
buttonPressed(String text) {
if (text == 'changed') {
callback();//Call callback here
}
}
#override
Widget build(BuildContext context) {
return Expanded(
child: OutlineButton(
onPressed: () {
buttonPressed(text);
},
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Text(
text,
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
}
class _PractiseInterviewState extends State<PractiseInterview> {
String outputText = '0';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Practise'),
),
body: Container(
child: Column(
children: <Widget>[
Text(
outputText, //**outputText is here**
),
Expanded(
child: Divider(),
),
Column(
children: <Widget>[
Row(
children: <Widget>[
ChnageText(text: 'changed', callback: () {setState((){outputText = 'changed';});}),// Pass callback here
],
),
],
)
],
),
),
);
}
}
Ideally, you wouldn't have to do this at all. What's in ChnageText doesn't need to be in its own StatelessWidget. Putting all of that directly in the parent removes this problem.
class _PractiseInterviewState extends State<PractiseInterview> {
String outputText = '0';
buttonPressed(String text) {
if (text == 'changed') {
setState(() {
outputText = 'changed';
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Practise'),
),
body: Container(
child: Column(
children: <Widget>[
Text(
outputText, //**outputText is here**
),
Expanded(
child: Divider(),
),
Column(
children: <Widget>[
Row(
children: <Widget>[
//Put ChnageText directly into the build of the parent
Expanded(
child: OutlineButton(
onPressed: () {
buttonPressed('changed');
},
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Text(
'changed',
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
),
],
)
],
),
),
);
}
}
I am having trouble inserting navigation links within my code below. I would like to learn how to insert navigation links within the second
onPressed: () {
//TODO(implement).
}
The ListView Widgets: Approved, Pending etc are the items that should contain links to other pages. The pages will be accessed by clicking on the FontAwesome.chevronRight
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class AppTab2 extends StatefulWidget {
#override
_AppTab2State createState() => _AppTab2State();
}
class _AppTab2State extends State<AppTab2> {
PageController _pageController = PageController(initialPage: 2);
#override
build(BuildContext context) {
final Map<String, Widget> pages = <String, Widget>{
'My Music': Center(
child: Text('My Music not implemented'),
),
'Shared': Center(
child: Text('Shared not implemented'),
),
'Feed': Feed(),
};
TextTheme textTheme = Theme.of(context).textTheme;
return Stack(
children: [
Container(
decoration: BoxDecoration(
// Gradient color the background
gradient: LinearGradient(
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
colors: [
const Color.fromARGB(255, 253, 72, 72),
const Color.fromARGB(255, 87, 97, 249),
],
stops: [0.0, 1.0],
)),
// child: Align(
// alignment: FractionalOffset.bottomCenter,
// child: Container(
// padding: const EdgeInsets.all(10.0),
// child: Text(
// 'Demo',
// style: textTheme.headline.copyWith(
// color: Colors.grey.shade800.withOpacity(0.8),
// fontWeight: FontWeight.bold,
// ),
// ),
// ),
// ),
),
Scaffold(
backgroundColor: Colors.white,
// appBar: AppBar(
// backgroundColor: const Color(0x00000000),
// elevation: 0.0,
// leading: Center(
// child: ClipOval(
// child: Image.network(
// 'http://i.imgur.com/TtNPTe0.jpg',
// ),
// ),
// ),
// actions: [
// IconButton(
// icon: Icon(Icons.add),
// onPressed: () {
// // TODO: implement
// },
// ),
// ],
//// title: const Text('tofu\'s songs'),
// bottom: CustomTabBar(
// pageController: _pageController,
// pageNames: pages.keys.toList(),
// ),
// ),
body: PageView(
controller: _pageController,
children: pages.values.toList(),
),
),
],
);
}
}
class CustomTabBar extends AnimatedWidget implements PreferredSizeWidget {
CustomTabBar({this.pageController, this.pageNames})
: super(listenable: pageController);
final PageController pageController;
final List<String> pageNames;
#override
final Size preferredSize = Size(0.0, 40.0);
#override
Widget build(BuildContext context) {
TextTheme textTheme = Theme.of(context).textTheme;
return Container(
height: 40.0,
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.symmetric(horizontal: 20.0),
decoration: BoxDecoration(
color: Colors.grey.shade800.withOpacity(0.5),
borderRadius: BorderRadius.circular(20.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(pageNames.length, (int index) {
return InkWell(
child: Text(pageNames[index],
style: textTheme.subhead.copyWith(
fontSize: 30.0,
fontFamily: 'OpenSans',
color: Colors.white.withOpacity(
index == pageController.page ? 1.0 : 0.2,
),
)),
onTap: () {
pageController.animateToPage(
index,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 300),
);
});
}),
),
);
}
}
class Feed extends StatefulWidget {
#override
_FeedState createState() => _FeedState();
}
class _FeedState extends State<Feed> {
#override
Widget build(BuildContext context) {
return ListView(
children: [
Content(
title: 'Approved',
),
Content(
title: 'Pending',
),
Content(
title: 'Published',
),
Content(
title: 'Withdrawn',
),
Content(
title: 'Declined',
),
Content(
title: 'Content Rights',
),
],
);
}
}
class Content extends StatefulWidget {
const Content({
this.title,
});
final String title;
#override
_ContentState createState() => _ContentState();
}
class _ContentState extends State<Content> {
#override
Widget build(BuildContext context) {
TextTheme textTheme = Theme.of(context).textTheme;
return Container(
margin: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
decoration: BoxDecoration(
color: Colors.grey.shade300.withOpacity(0.5),
borderRadius: BorderRadius.circular(5.0),
),
child: IntrinsicHeight(
child: Row(
children: <Widget>[
// Container(
// margin:
// const EdgeInsets.only(top: 4.0, bottom: 4.0, right: 10.0),
// child: CircleAvatar(
// backgroundImage: NetworkImage(
// 'http://thecatapi.com/api/images/get?format=src'
// '&size=small&type=jpg#${title.hashCode}'),
// radius: 20.0,
// ),
// ),
SizedBox(
height: 15.0,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(widget.title, style: textTheme.subhead),
],
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 5.0),
child: InkWell(
child: Icon(
FontAwesomeIcons.chevronRight,
size: 25.0,
color: Colors.deepPurpleAccent,
),
onTap: () {
// TODO(implement)
},
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 5.0),
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// Icon(Icons.favorite, size: 25.0),
// Text('${likes ?? ''}'),
],
),
onTap: () {
// TODO(implement)
},
),
),
],
),
));
}
}
There are some bug in your code. for demo purpose, I modify some of your code.
you can see full demo code and picture below
code snippet
child: ListView(
children: [
Content(
title: 'Approved',
screenPage: Approved(),
),
Content(
title: 'Pending',
screenPage: Pending(),
),
...
class Content extends StatefulWidget {
const Content({
this.title,
this.screenPage,
});
final String title;
final Widget screenPage;
...
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => widget.screenPage),
);
},
full code
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.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: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Feed(),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class AppTab2 extends StatefulWidget {
#override
_AppTab2State createState() => _AppTab2State();
}
class _AppTab2State extends State<AppTab2> {
PageController _pageController = PageController(initialPage: 2);
#override
build(BuildContext context) {
final Map<String, Widget> pages = <String, Widget>{
'My Music': Center(
child: Text('My Music not implemented'),
),
'Shared': Center(
child: Text('Shared not implemented'),
),
'Feed': Feed(),
};
TextTheme textTheme = Theme.of(context).textTheme;
return Stack(
children: [
Container(
decoration: BoxDecoration(
// Gradient color the background
gradient: LinearGradient(
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
colors: [
const Color.fromARGB(255, 253, 72, 72),
const Color.fromARGB(255, 87, 97, 249),
],
stops: [0.0, 1.0],
)),
// child: Align(
// alignment: FractionalOffset.bottomCenter,
// child: Container(
// padding: const EdgeInsets.all(10.0),
// child: Text(
// 'Demo',
// style: textTheme.headline.copyWith(
// color: Colors.grey.shade800.withOpacity(0.8),
// fontWeight: FontWeight.bold,
// ),
// ),
// ),
// ),
),
Scaffold(
backgroundColor: Colors.white,
// appBar: AppBar(
// backgroundColor: const Color(0x00000000),
// elevation: 0.0,
// leading: Center(
// child: ClipOval(
// child: Image.network(
// 'http://i.imgur.com/TtNPTe0.jpg',
// ),
// ),
// ),
// actions: [
// IconButton(
// icon: Icon(Icons.add),
// onPressed: () {
// // TODO: implement
// },
// ),
// ],
//// title: const Text('tofu\'s songs'),
// bottom: CustomTabBar(
// pageController: _pageController,
// pageNames: pages.keys.toList(),
// ),
// ),
body: PageView(
controller: _pageController,
children: pages.values.toList(),
),
),
],
);
}
}
class CustomTabBar extends AnimatedWidget implements PreferredSizeWidget {
CustomTabBar({this.pageController, this.pageNames})
: super(listenable: pageController);
final PageController pageController;
final List<String> pageNames;
#override
final Size preferredSize = Size(0.0, 40.0);
#override
Widget build(BuildContext context) {
TextTheme textTheme = Theme.of(context).textTheme;
return Container(
height: 40.0,
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.symmetric(horizontal: 20.0),
decoration: BoxDecoration(
color: Colors.grey.shade800.withOpacity(0.5),
borderRadius: BorderRadius.circular(20.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(pageNames.length, (int index) {
return InkWell(
child: Text(pageNames[index],
style: textTheme.subhead.copyWith(
fontSize: 30.0,
fontFamily: 'OpenSans',
color: Colors.white.withOpacity(
index == pageController.page ? 1.0 : 0.2,
),
)),
onTap: () {
pageController.animateToPage(
index,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 300),
);
});
}),
),
);
}
}
class Approved extends StatefulWidget {
#override
_ApprovedState createState() => _ApprovedState();
}
class _ApprovedState extends State<Approved> {
#override
Widget build(BuildContext context) {
return Text('Approved');
}
}
class Pending extends StatefulWidget {
#override
_PendingState createState() => _PendingState();
}
class _PendingState extends State<Pending> {
#override
Widget build(BuildContext context) {
return Text('Pending');
}
}
class Feed extends StatefulWidget {
#override
_FeedState createState() => _FeedState();
}
class _FeedState extends State<Feed> {
#override
Widget build(BuildContext context) {
return Container(
height: 300,
child: ListView(
children: [
Content(
title: 'Approved',
screenPage: Approved(),
),
Content(
title: 'Pending',
screenPage: Pending(),
),
Content(
title: 'Published',
),
Content(
title: 'Withdrawn',
),
Content(
title: 'Declined',
),
Content(
title: 'Content Rights',
),
],
),
);
}
}
class Content extends StatefulWidget {
const Content({
this.title,
this.screenPage,
});
final String title;
final Widget screenPage;
#override
_ContentState createState() => _ContentState();
}
class _ContentState extends State<Content> {
#override
Widget build(BuildContext context) {
TextTheme textTheme = Theme.of(context).textTheme;
return Container(
margin: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
decoration: BoxDecoration(
color: Colors.grey.shade300.withOpacity(0.5),
borderRadius: BorderRadius.circular(5.0),
),
child: IntrinsicHeight(
child: Row(
children: <Widget>[
Text("this is Content"),
// Container(
// margin:
// const EdgeInsets.only(top: 4.0, bottom: 4.0, right: 10.0),
// child: CircleAvatar(
// backgroundImage: NetworkImage(
// 'http://thecatapi.com/api/images/get?format=src'
// '&size=small&type=jpg#${title.hashCode}'),
// radius: 20.0,
// ),
// ),
SizedBox(
height: 15.0,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(widget.title, style: textTheme.subhead),
],
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 5.0),
child: InkWell(
child: Icon(
FontAwesomeIcons.chevronRight,
size: 25.0,
color: Colors.deepPurpleAccent,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => widget.screenPage),
);
},
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 5.0),
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// Icon(Icons.favorite, size: 25.0),
// Text('${likes ?? ''}'),
],
),
onTap: () {
// TODO(implement)
},
),
),
],
),
));
}
}