AppBar with a ListView (Flutter) - flutter

I'm a big beginner with Flutter and I followed a tutorial to make a ListView with pictures. However, I'm a bit lost in the code and I don't know where to implement my AppBar. I've already tried several times but never succeeded. I hope you'll be able to help me, here's the code:
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../recyclerview/data.dart';
class ListViewExample extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new ListViewExampleState(
);
}
}
class ListViewExampleState extends State<ListViewExample>{
List<Container> _buildListItemsFromItems(){
int index = 0;
return item.map((item){
var container = Container(
decoration: index % 2 == 0?
new BoxDecoration(color: const Color(0xFFFFFFFF)):
new BoxDecoration(
color: const Color(0xFFFAFAF5)
),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(5.0),
child: new CachedNetworkImage(
imageUrl: item.imageURL,
width: 200.0,
height: 100.0,
fit: BoxFit.cover,
),
),
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
item.title,
style: new TextStyle(),
),
new Text(
item.description,
),
]
)
],
)
);
index = index + 1;
return container;
}).toList();
}
#override
Widget build(BuildContext context) {
return new ListView(
children: _buildListItemsFromItems(),
);
}
}
If you need more resources I'll send you this, Thank you.
Update: I have added the AppBar at outside of the ListView in the Scaffold

You have to use the AppBar in a Scaffold and not in the listview like this:
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../recyclerview/data.dart';
class ListViewExample extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new ListViewExampleState(
);
}
}
class ListViewExampleState extends State<ListViewExample>{
List<Container> _buildListItemsFromItems(){
int index = 0;
return item.map((item){
var container = Container(
decoration: index % 2 == 0?
new BoxDecoration(color: const Color(0xFFFFFFFF)):
new BoxDecoration(
color: const Color(0xFFFAFAF5)
),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(5.0),
child: new CachedNetworkImage(
imageUrl: item.imageURL,
width: 200.0,
height: 100.0,
fit: BoxFit.cover,
),
),
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
item.title,
style: new TextStyle(),
),
new Text(
item.description,
),
]
)
],
)
);
index = index + 1;
return container;
}).toList();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(),
body: ListView(
children: _buildListItemsFromItems(),
),
);
}
}

Related

how to add two posts per screen flutter

I'm trying to create a video screen like the picture. on the right side picture showing my implementation so far. how can I create video screen like half of the screen and one after the other as left UI below. (two videos per screen). appriciate your help on this. I haveadded my code for your refernce
post_template.dart
import 'package:flutter/material.dart';
import '../constants/button.dart';
class PostTemplate extends StatelessWidget {
final String username;
final String videoDescription;
final String numberOfLikes;
final String numberOfComments;
final String numberOfShares;
final userPost;
PostTemplate({
required this.username,
required this.videoDescription,
required this.numberOfLikes,
required this.numberOfComments,
required this.numberOfShares,
required this.userPost,
});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
// user post (at the very back)
userPost,
// user name and caption
Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
alignment: Alignment(-1, 1),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text('#' + username,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
)),
SizedBox(
height: 10,
),
RichText(
text: TextSpan(
children: [
TextSpan(
text: videoDescription,
style: TextStyle(color: Colors.white)),
TextSpan(
text: ' #live #lalaive',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white)),
],
),
)
],
),
),
),
// buttons
Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
alignment: Alignment(1, 1),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
MyButton(
icon: Icons.people,
number: numberOfComments,
),
MyButton(
icon: Icons.thumb_up,
number: numberOfLikes,
),
MyButton(
icon: Icons.share,
number: numberOfShares,
),
],
),
),
)
],
),
);
}
}
video_screen.dart
import 'package:flutter/material.dart';
import 'package:lala_live/screens/post_template.dart';
class VideoScreen extends StatefulWidget {
const VideoScreen({Key? key}) : super(key: key);
#override
_VideoScreenState createState() => _VideoScreenState();
}
class _VideoScreenState extends State<VideoScreen> {
final _controller = PageController(initialPage: 0);
#override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _controller,
scrollDirection: Axis.vertical,
children: [
MyPost1(),
MyPost2(),
MyPost3(),
],
),
);
}
}
class MyPost1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return PostTemplate(
username: 'amandasharma',
videoDescription: 'Free your mind',
numberOfLikes: '1.2M',
numberOfComments: '1232',
numberOfShares: '122',
userPost: Container(
//color: Colors.deepPurple[300],
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("asset/images/girl.jpeg"),
fit: BoxFit.fill,
)
)
)
);
}
}
class MyPost2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return PostTemplate(
username: 'zuckerberg',
videoDescription: 'reels for days',
numberOfLikes: '1.2M',
numberOfComments: '232',
numberOfShares: '122',
userPost: Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("asset/images/nature.jpg"),
fit: BoxFit.fill,
)
)
),
);
}
}
class MyPost3 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return PostTemplate(
username: 'randomUser',
videoDescription: 'Free your mind',
numberOfLikes: '1.2B',
numberOfComments: '232',
numberOfShares: '122',
userPost: Container(
color: Colors.blue[300],
),
);
}
}
for MyPost3() you can wrap the containers in a column and use the Expanded widget.
class MyPost3 extends StatelessWidget {
const MyPost3({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return PostTemplate(
username: 'randomUser',
videoDescription: 'Free your mind',
numberOfLikes: '1.2B',
numberOfComments: '232',
numberOfShares: '122',
userPost: Column(
children: [
Expanded(
child: Container(
color: Colors.blue[300],
),
),
Expanded(
child: Container(
color: Colors.red[300],
),
),
],
),
);
}
}
I believe this is where you want the video widgets to appear ,
// user post (at the very back)
userPost,
You can put the widgets in a column and use Expandable to give them size, i.e flex 2 for each to split screen halfway.
Column -
- Expanded( flex:2, child:video1
- Expanded( flex:2, child:video2
On MyPost3():
return PostTemplate(
username: 'randomUser',
videoDescription: 'Free your mind',
numberOfLikes: '1.2B',
numberOfComments: '232',
numberOfShares: '122',
userPost: SafeArea(
child: Column(children: [
Expanded(
child: Container(
color: Colors.blue,
)),
Expanded(
child: Container(
color: Colors.red,
))
]),
));
You can use an Expanded() to take as much space you can, surrounded by a SafeArea() to ensure your screens don't overlap with your status bar leaving the possibility of an overflow.

Calling setState() from another page - Flutter

I have a String _value, which I would like to call it from another page.
Here is my players.dart
class MyWidgetPopup extends StatefulWidget {
#override
MyWidgetPopupState createState() => MyWidgetPopupState();
}
enum Answers{FIRST,SECOND}
class MyWidgetPopupState extends State<MyWidgetPopup> {
String _value = '';
void _setValue(String value) => setState(() => _value = value);
Future selectGk(BuildContext context) async {
switch(
await showDialog(
...
...
{
case Answers.FIRST:
_setValue('FIRST TEAM');
break;
case Answers.SECOND:
_setValue('SECOND TEAM');
break;
}
}
So, in players.dart, I can show the selected team with simple code: Text(_value)
But I would like to show it in select.dart
import 'package:flutter/material.dart';
import 'package:myapp/players.dart';
MyWidgetPopupState dataSource = MyWidgetPopupState();
class Besdortbir extends StatefulWidget {
#override
_BesdortbirState createState() => _BesdortbirState();
}
class _BesdortbirState extends State<Besdortbir> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'My Title'),
centerTitle: true,
backgroundColor: Colors.redAccent[700],
elevation: 0.0,
),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(
image: new DecorationImage(
image: new AssetImage("assets/field.png"),
fit: BoxFit.fill
)
),
),
//FIRST PLAYER
Container(
padding: EdgeInsets.only(bottom: 90.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
GestureDetector(
onTap: (){dataSource.selectGk(context);}, //I have the FIRST TEAM and SECOND TEAM listed here.
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset('assets/PLUS.png',
scale: 8),
),
),
),
Text(//somehow I would like to show which team is selected by user),
],
),
),
],
),
);
}
}
I have tried to recall setState(), _value, and a few other options. But, I could not be successful.

How to navigate to another page within a stack in flutter?

I am currently trying to manage the navigation logic within the flutter stack I have created.
I would like to add separate page navigation to each of the list items listed:
List<String> images = [
"assets/berries-chocolates-delicious-918327.jpg",
"assets/adult-beauty-cosmetic-1029896.jpg",
"assets/aerial-shot-architecture-beach-1488515.jpg",
"assets/brush-brushes-cosmetics-212236.jpg",
];
List<String> title = [
"Cadbury",
"Biotherme",
"Trip Advisor",
"L'Oreal Paris",
];
> This is the associated stack logic code in another file:
Stack(
children: <Widget>[
CardScrollWidget(currentPage),
Positioned.fill(
child: PageView.builder(
itemCount: images.length,
controller: controller,
reverse: true,
itemBuilder: (context, index) {
return Container();
},
),
)
],
),
// SizedBox(
// height: 10.0,
// ),
This is the associated widget file code:
import 'package:flutter/material.dart';
import '../screens/introductory_screen.dart';
import 'data.dart';
import 'dart:math';
import '../constants/constants.dart';
class CardScrollWidget extends StatefulWidget {
var currentPage;
CardScrollWidget(this.currentPage);
#override
_CardScrollWidgetState createState() => _CardScrollWidgetState();
}
class _CardScrollWidgetState extends State<CardScrollWidget> {
var padding = 20.0;
var verticalInset = 20.0;
#override
Widget build(BuildContext context) {
return new AspectRatio(
aspectRatio: widgetAspectRatio,
child: LayoutBuilder(builder: (context, contraints) {
var width = contraints.maxWidth;
var height = contraints.maxHeight;
var safeWidth = width - 2 * padding;
var safeHeight = height - 2 * padding;
var heightOfPrimaryCard = safeHeight;
var widthOfPrimaryCard = heightOfPrimaryCard * cardAspectRatio;
var primaryCardLeft = safeWidth - widthOfPrimaryCard;
var horizontalInset = primaryCardLeft / 2;
List<Widget> cardList = List();
for (var i = 0; i < images.length; i++) {
var delta = i - widget.currentPage;
bool isOnRight = delta > 0;
var start = padding +
max(
primaryCardLeft -
horizontalInset * -delta * (isOnRight ? 15 : 1),
0.0);
var cardItem = Positioned.directional(
top: padding + verticalInset * max(-delta, 0.0),
bottom: padding + verticalInset * max(-delta, 0.0),
start: start,
textDirection: TextDirection.rtl,
child: ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Container(
decoration: BoxDecoration(
color: Colors.deepPurpleAccent,
boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(3.0, 6.0),
blurRadius: 10.0)
]),
child: AspectRatio(
aspectRatio: cardAspectRatio,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset(
images[i],
fit: BoxFit.cover,
),
Align(
alignment: Alignment.bottomLeft,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(
horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.deepPurpleAccent,
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: const EdgeInsets.all(6.0),
This is where a gesture detector will be added to create a navigation link
child: Text(
title[i],
style: kCampaignLabelStyle,
),
),
),
),
This is where a gesture detector will be added to create a navigation link
// SizedBox(
// height: 10.0,
// ),
// Padding(
// padding: const EdgeInsets.only(
// left: 12.0, bottom: 12.0),
// child: Container(
// padding: EdgeInsets.symmetric(
// horizontal: 22.0, vertical: 6.0),
// decoration: BoxDecoration(
// color: Colors.deepPurpleAccent,
// borderRadius: BorderRadius.circular(20.0)),
// child: Text(
// "Read More",
// style: TextStyle(color: Colors.white),
// ),
// ),
// )
],
),
)
],
),
),
),
),
);
cardList.add(cardItem);
}
return Stack(
children: cardList,
);
}),
);
}
}
If anyone can help with the navigation logic, I would appreciate it.
create seperate files
Cadbury.dart
class Cadbury extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return CadburyState();
}
}
class CadburyState extends State<DashboardApp> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("Cadbury Screen"),
backgroundColor: MyColor.colorRed,
),
backgroundColor: MyColor.colorRed,
body: new Center());
}
}
Biotherme.dart
class Biotherme extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return BiothermeState();
}
}
class BiothermeState extends State<Biotherme> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("Biotherme Screen"),
backgroundColor: MyColor.colorRed,
),
backgroundColor: MyColor.colorRed,
body: new Center());
}
}
and make the redirections like this
// common function to create button and redirects the page which is in callback name
Widget buttonBuilder(
String buttonText, BuildContext context, Widget callbackName) {
return new RaisedButton(
child: Text(buttonText),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => callbackName));
});
}
// home redirection screen which redirects to the cadbury and Biotherme screen
class RedirectionScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(title: Text("Home Screen")),
body: Center(
child: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
buttonBuilder('Cadbury Screen', context, Cadbury()),
buttonBuilder('Biotherme Screen', context, Biotherme()),
],
),
));
}
}
try this below code for Navigation, it works for me
If you want to navigate the page on the button's click event then write code
return new RaisedButton(
child: Text(buttonText),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => redirection_page_name));
});
Note: Here redirection_page_name is the page or widget name which you want to be load on the button's click event.
The original syntax is
Navigator.push(context, MaterialPageRoute(builder: (context) => redirection_page_name));
here context is the current screen widget context which is built, and redirection_page_name is the new page/widget which is being loaded.

Flutter: Calling SetState() from another class

I am trying to make a simple image that appears or disappears when a button is pushed. This button resides in a separate class to the image, so in Flutter this creates a massive headache of an issue.
I have read many forums on this and I have tried all the solutions posed but none of them are working for me.
What I am trying to do:
class SinglePlayerMode extends StatefulWidget {
#override
SinglePlayerModeParentState createState() => SinglePlayerModeParentState();
}
class SinglePlayerModeParentState extends State<SinglePlayerMode> {\
bool coinVisible = false;
toggleCoin() {
setState(() {
coinVisible = !coinVisible;
});
}
Widget topMenuRow() {
return Stack(
children: [
Column(
children: [
coinVisible == true ?
Padding(
padding: EdgeInsets.all(50),
child: Container(
height: 60,
width: 60,
color: Colors.blueGrey[0],
decoration: BoxDecoration(
color: Colors.blueAccent,
image: DecorationImage(
image: ExactAssetImage('lib/images/coin_head.jpg'),
fit: BoxFit.cover,
),
),
),
) : Container(
height: 60,
width: 60,
color: Colors.black,
),
],
),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
child: ListView(
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
children: [
topMenuRow(),
SizedBox(height: 40),
],
),
),
);
}
And this is the separate class which I would like to trigger the SetState() on coinVisible from:
class dropDownMenu extends StatefulWidget { #override
_dropDownMenuState createState() => _dropDownMenuState();
}
class _dropDownMenuState extends State<dropDownMenu> {
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget> [
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
child: Opacity(
opacity: 0.0,
child: FloatingActionButton(
heroTag: null,
onPressed: (){
//SOMEHOW CALL SetState() ON coinVisble HERE!
},
),
),
);
}
}
But nothing I have tried is working, and I have lost hours.
It simple, you need to send your SinglePlayMode::toggleCoin function as callback to dropDownMenu class.
class dropDownMenu extends StatefulWidget {
final _callback; // callback reference holder
//you will pass the callback here in constructor
dropDownMenu( {#required void toggleCoinCallback() } ) :
_callback = toggleCoinCallback;
#override
_dropDownMenuState createState() => _dropDownMenuState();
}
class _dropDownMenuState extends State<dropDownMenu> {
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget> [
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
child: Opacity(
opacity: 0.0,
child: FloatingActionButton(
heroTag: null,
onPressed: (){
widget?._callback(); // callback calling
},
),
),
);
}
}
Then when you create a dropDownMenu class instance in your SinglePlayerMode class you will do
dropDownMenu(
toggleCoinCallback: toogleCoin,
);

Hero animation not working properly?

I am new in Flutter.
Today I created splash screen and login screen. Then I want to animate my logo from splash screen -> login screen.
But when I run code, the animation not working
here is my code:
Splash Screen
class SplashScreen extends StatelessWidget{
#override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
home: new SplashScreenPage(),
routes: <String, WidgetBuilder>{
'/LoginPage': (BuildContext context) => new LoginPage()
},
);
}
}
class SplashScreenPage extends StatefulWidget{
SplashScreenPage({Key key, this.title}) : super(key: key);
final String title;
#override
State<StatefulWidget> createState() {
return new SplashScreenState();
}
}
class SplashScreenState extends State<SplashScreenPage>{
startTime() async {
var _duration = new Duration(seconds: 2);
return new Timer(_duration, navigationPage);
}
void navigationPage() {
Navigator.of(context).pushNamed('/LoginPage');
}
#override
void initState() {
startTime();
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new SizedBox(
child: new Hero(
tag: 'hero-tag-llama',
child: new Image.asset(
'images/logo_futurisx.png',
fit: BoxFit.cover,
height: 150.0,
)
),
)
],
)
),
);
}
Login screen
class LoginState extends State<LoginPage>{
final userNameController = new TextEditingController();
final passwordController = new TextEditingController();
#override
Widget build(BuildContext context) {
var _imageBox = new SizedBox(
child: new Hero(
tag: 'hero-tag-llama',
child: new Image.asset(
'images/logo_futurisx.png',
fit: BoxFit.cover,
height: 100.0,
)
),
);
var _loginForm = new Container(
padding: new EdgeInsets.all(32.0),
child: new Column(
children: <Widget>[
new TextField(
maxLines: 1,
controller: userNameController,
decoration: new InputDecoration(
border: new UnderlineInputBorder(),
fillColor: Colors.green,
hintText: "Username"
),
),
new Container(
padding: new EdgeInsets.only(bottom: 20.0),
),
new TextField(
maxLines: 1,
controller: passwordController,
decoration: new InputDecoration(
border: new UnderlineInputBorder(),
fillColor: Colors.green,
hintText: "Password"
),
),
new Container(
padding: new EdgeInsets.only(bottom: 30.0),
),
new RaisedButton(
padding: new EdgeInsets.fromLTRB(30.0, 10.0, 30.0, 10.0),
child: new Text("Login", style: new TextStyle(color: Colors.white)),
elevation: 4.0,
color: Colors.teal,
onPressed: (){
login(userNameController.text, passwordController.text);
}
),
])
);
return new Scaffold(
key: _scaffoldKey,
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
_imageBox,
_loginForm
],
)
)
);
}
The video I uploaded here:
https://vimeo.com/271938052
When I comment the _loginForm layout in Login Screen,
children: <Widget>[
_imageBox,
//_loginForm
],
animation work normally. Can anyone help me know why animation not running as expect?
UPDATE -----------
After a lots of searching and fixing, i found that Timer may be block thread(or something similar,..) removed timer let button click action to change page, animation work normally.
Did someone meet this problem?
What happens here is that the Timer finishes before even starting the Hero animation. A workaround here is to increase the duration set on the Timer.