Reputation: 197
I'm testing out this Flutter project which generates a movie list from a for loop:for (int i = 0; i < 3; i++) {...}.
The result of the loop is 3 cards which I'd like to add an onTap function to and navigate to the corresponding page as a result.
Github:https://github.com/devefy/Flutter-Streaming-Service-App-UI/blob/master/lib/main.dart
After the padding on line 222, I added a ListTile() with the onTap:(){} widget. This enabled the tap widget for the bottom half of the card.
// Line 219 to 222
Padding(
padding: EdgeInsets.only(top: 3.0),
child: Text(i == 0 ? "Season 2" : ""),
),// Padding
ListTile(onTap: (){
debugPrint('${[i]} was tapped!');
//Navigator.push(context, route)
My results when tapping the 3 cards.
flutter: [0] was tapped!
flutter: [1] was tapped!
flutter: [2] was tapped!
Where I get lost is how to actually navigate to the detail page of the movie depending on which card I tap on.
Any help is appreciated...Thank You All!!!
Upvotes: 0
Views: 2333
Reputation: 197
Finally found a solution I was happy with. Thanks to flutter_ui_challenge.
import 'package:flutter/material.dart';
import 'package:flutter_youtube/flutter_youtube.dart';
class YouTubeVideoList extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("YouTube Video List"),
backgroundColor: Colors.lightBlue,
elevation: 2,
actions: <Widget>[
Container(
padding: EdgeInsets.all(10),
)
],
),
body: Lists(),
);
}
}
class Item {
final String title;
final String category;
final String place;
final Function onTap;
final String image;
Item(
{this.title,
this.category,
this.place,
this.onTap,
this.image});
}
class Lists extends StatelessWidget {
final List<Item> _data = [
Item(
onTap: playYoutubeVideo1,
title: 'Gardens By the Bay',
category: "Gardens",
place: "Singapore",
image: "https://images.pexels.com/photos/672142/pexels-photo-672142.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"),
Item(
onTap: playYoutubeVideo2,
title: 'Singapore Zoo',
category: "Parks",
place: "Singapore",
image: "https://images.pexels.com/photos/1736222/pexels-photo-1736222.jpeg?cs=srgb&dl=adult-adventure-backpacker-1736222.jpg&fm=jpg"),
Item(
onTap: playYoutubeVideo3,
title: 'National Orchid Garden',
category: "Parks",
place: "Singapore",
image: "https://images.pexels.com/photos/62403/pexels-photo-62403.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"),
];
@override
Widget build(BuildContext context) {
return ListView.builder(
padding: EdgeInsets.all(6),
itemCount: _data.length,
itemBuilder: (BuildContext context, int index) {
Item item = _data[index];
return GestureDetector(
onTap: item.onTap,
child: Card(
elevation: 3,
child: Row(
children: <Widget>[
Container(
height: 125,
width: 110,
padding:
EdgeInsets.only(left: 0, top: 10, bottom: 70, right: 20),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(item.image),
fit: BoxFit.cover)),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
item.title,
style: TextStyle(
color: Colors.deepOrange,
fontWeight: FontWeight.w700,
fontSize: 15),
),
Text(
item.category,
style: TextStyle(fontSize: 12, color: Colors.black87),
),
Text(
item.place,
style: TextStyle(fontSize: 10, color: Colors.black87),
),
SizedBox(
height: 10,
),
],
),
)
],
),
),
);
},
);
}
var youtube = new FlutterYoutube();
static playYoutubeVideo1() {
FlutterYoutube.playYoutubeVideoByUrl(
apiKey: "YOUR_API_KEY",
videoUrl: "YOUTUBE_VIDEO_URL",
);
}
static playYoutubeVideo2() {
FlutterYoutube.playYoutubeVideoByUrl(
apiKey: "YOUR_API_KEY",
videoUrl: "YOUTUBE_VIDEO_URL",
);
}
static playYoutubeVideo3() {
FlutterYoutube.playYoutubeVideoByUrl(
apiKey: "YOUR_API_KEY",
videoUrl: "YOUTUBE_VIDEO_URL",
);
}
}
Upvotes: 0
Reputation: 837
The best practice for something like this would be to create 2 pages, a movie list, and a details page.
The movie list will loop through all of the movies, then the on tap would point to the details page. The key here is that you can pass data to the details page when navigating. Whether that be an id or slug for the movie allowing you to fetch specific data or just an index to a list for a simpler example.
Navigator.push( context, MaterialPageRoute( builder: (context) => DetailScreen(todo: todos[index]),),);
Here is an example regarding a todo list and a details screen. I would try running this so you can understand further what I mean.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class Todo {
final String title;
final String description;
Todo(this.title, this.description);
}
void main() {
runApp(MaterialApp(
title: 'Passing Data',
home: TodosScreen(
todos: List.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
),
),
));
}
class TodosScreen extends StatelessWidget {
final List<Todo> todos;
TodosScreen({Key key, @required this.todos}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
// Declare a field that holds the Todo.
final Todo todo;
// In the constructor, require a Todo.
DetailScreen({Key key, @required this.todo}) : super(key: key);
@override
Widget build(BuildContext context) {
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(todo.description),
),
);
}
}
Here is the app running.
Let me know if you have any questions!
Upvotes: 1