Flutter: datasource error with video_thumbnail package - java

I'm trying to follow the example from the video_thumbnail plugin to generate a thumbnail for a video I've placed locally in my android emulator Download folder:
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
class VideoSelectPageListTile extends StatefulWidget {
final String videoName;
const VideoSelectPageListTile({
Key key,
#required this.videoName,
}) : super(key: key);
#override
_VideoSelectPageListTileState createState() =>
_VideoSelectPageListTileState();
}
class _VideoSelectPageListTileState extends State<VideoSelectPageListTile> {
Future<Image> generateThumbnail(String videoName) async {
final uint8list = await VideoThumbnail.thumbnailData(
video: "/storage/emulated/0/Download/my-video-file.mp4",
imageFormat: ImageFormat.JPEG,
maxWidth: 128, // specify the width of the thumbnail, let the height auto-scaled to keep the source aspect ratio
quality: 25,
);
return Image.memory(uint8list);
}
#override
Widget build(BuildContext context) {
return FutureBuilder<Image>(
future: generateThumbnail(widget.videoName),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListTile(
title: Text(widget.videoName),
trailing: snapshot.data,
);
} else {
return Text("No image can be generated");
}
},
);
}
}
For whatever reason it continues to just throw IllegalArgumentExceptions at line 77 in the MediaMetadataRetriever.java class on build:
Launching lib/main.dart on Android SDK built for x86 in debug mode...
Running Gradle task 'assembleDebug'...
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk...
Waiting for Android SDK built for x86 to report its views...
Debug service listening on ws://127.0.0.1:55082/iYajbqTSHdQ=/ws
Syncing files to device Android SDK built for x86...
D/EGL_emulation(27588): eglMakeCurrent: 0xebc126a0: ver 3 0 (tinfo 0xe2a0f850)
D/eglCodecCommon(27588): setVertexArrayObject: set vao to 0 (0) 1 0
D/ThumbnailPlugin(27588): buildThumbnailData( format:0, maxh:0, maxw:128, timeMs:0, quality:25 )
W/System.err(27588): java.lang.IllegalArgumentException
W/System.err(27588): at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:77)
W/System.err(27588): at xyz.justsoft.video_thumbnail.VideoThumbnailPlugin.createVideoThumbnail(VideoThumbnailPlugin.java:201)
W/System.err(27588): at xyz.justsoft.video_thumbnail.VideoThumbnailPlugin.buildThumbnailData(VideoThumbnailPlugin.java:116)
W/System.err(27588): at xyz.justsoft.video_thumbnail.VideoThumbnailPlugin.access$100(VideoThumbnailPlugin.java:37)
W/System.err(27588): at xyz.justsoft.video_thumbnail.VideoThumbnailPlugin$1.run(VideoThumbnailPlugin.java:77)
W/System.err(27588): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err(27588): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err(27588): at java.lang.Thread.run(Thread.java:919)
D/EGL_emulation(27588): eglMakeCurrent: 0xe2a1a2a0: ver 3 0 (tinfo 0xe2a0fad0)
Is there some error in my implementation here? I ran the example program at the package link without issue and without adding additional permissions in my AndroidManifest.xml file.
Would one of you know how to address this?

You can copy paste run full code below
You need permission READ_EXTERNAL_STORAGE
Step 1: Add <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> to AndroidManifest.xml
Step 2: Request permission with permission_handler
Future<Image> generateThumbnail(String videoName) async {
Map<Permission, PermissionStatus> statuses = await [
Permission.storage,
].request();
...
working demo
full code
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
class VideoSelectPageListTile extends StatefulWidget {
final String videoName;
const VideoSelectPageListTile({
Key key,
#required this.videoName,
}) : super(key: key);
#override
_VideoSelectPageListTileState createState() =>
_VideoSelectPageListTileState();
}
class _VideoSelectPageListTileState extends State<VideoSelectPageListTile> {
Future<Image> generateThumbnail(String videoName) async {
Map<Permission, PermissionStatus> statuses = await [
Permission.storage,
].request();
final uint8list = await VideoThumbnail.thumbnailData(
video: "/storage/emulated/0/Download/my-video-file.mp4",
imageFormat: ImageFormat.JPEG,
maxWidth:
128, // specify the width of the thumbnail, let the height auto-scaled to keep the source aspect ratio
quality: 25,
);
return Image.memory(uint8list);
}
#override
Widget build(BuildContext context) {
return FutureBuilder<Image>(
future: generateThumbnail(widget.videoName),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListTile(
title: Text("${widget.videoName}"),
trailing: snapshot.data,
);
} else {
return Text("No image can be generated");
}
},
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
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(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
VideoSelectPageListTile(
videoName: "test",
),
],
),
),
);
}
}

Related

How to fix The following _CastError was thrown building: type 'Future<dynamic>' is not a subtype of type 'List<dynamic>' in type cast

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'UI_Tool/size_fit.dart';
class Gallery extends StatefulWidget {
#override
_GalleryState createState() => _GalleryState();
}
class _GalleryState extends State<Gallery> {
pic() async {
var url = "http://120.76.247.131:8081/findAllImages";
var response = await http.get(Uri.parse(url));
return json.decode(response.body);
}
#override
void initState() {
super.initState();
pic();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Gallery'),
),
body: FutureBuilder(
future : pic(),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ListView.builder(
itemCount:2,
itemBuilder: (context, index) {
List list = pic() as List;
return Card(
child: ListTile(
title: Container(
width: 100,
height: 100,
child: Image.network(
"http://120.76.247.131:8081/findAllImages/%7Blist[index][%22image%22]%7D%22)"
),
),
));
})
: Center(
child: CircularProgressIndicator(),
);
},
),
);
}
}
I had tried to add behind the future and it doesn't solve the problem. Moreover, there is a problem with the itemcount, so I left it with a number instead of add snapshot.data!.length() because I am not sure why there is an error with snapshot.data!.length() for itemcount.
Here is full working code.
At first because pic() returns Future,
you need to use 'await' or 'then' to get a response.
https://dart.dev/codelabs/async-await
Because of that, below sentence cause error as you provided.
But because it is not necessary in this case, I get rid of this.
List list = pic() as List;
If you want use pic() method, just call like below.
(But in this case, you cannot call like this.)
List list = await pic()
You've already used 'FutureBuilder', you don't need to call pic() again.
You just use snapdata's data incase of snapdata has a data.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
print('onStart');
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Gallery(),
);
}
}
class Gallery extends StatefulWidget {
#override
_GalleryState createState() => _GalleryState();
}
class _GalleryState extends State<Gallery> {
pic() async {
var url = "http://120.76.247.131:8081/findAllImages";
var response = await http.get(Uri.parse(url));
return json.decode(response.body);
}
#override
void initState() {
super.initState();
pic();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Gallery'),
),
body: FutureBuilder(
future: pic(),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ListView.builder(
itemCount: (snapshot.data! as Map)['data'].length,
itemBuilder: (context, index) {
// List list = pic() as List;
print((snapshot.data! as Map)['data'][index]);
return Card(
child: ListTile(
title: Container(
width: 100,
height: 100,
child: Image.network(
(snapshot.data! as Map)['data'][index]['image']),
),
));
})
: Center(
child: CircularProgressIndicator(),
);
},
),
);
}
}

Flutter How to add java code to flutter module

I want to add some java code to flutter module。Which directory should I add java code.
I have tried to add java code in the directory as picture bottom,but the code will not be compiled to aar.
You should implement platform channel for executing some java code.
For Example, I am passing two int value from a flutter to Android Native. In the Android native side, Kotlin/Java will sum these numbers and return the result to flutter
Flutter side
class Demo extends StatefulWidget {
#override
_DemoState createState() => _DemoState();
}
class _DemoState extends State<Demo> {
static const platform = const MethodChannel('flutter.native/helper');
#override
void initState() {
super.initState();
}
getData(int num1, int num2) async {
try {
final int result =
await platform.invokeMethod('add', {'num1': num1, 'num2': num2});
print('$result');
} on PlatformException catch (e) {}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Country"),
SizedBox(
height: 20.0,
),
RaisedButton(
onPressed: () => getData(10, 20),
child: Text('Add'),
)
],
),
),
),
);
}
}
Android native side
class MainActivity : FlutterActivity() {
private val CHANNEL = "flutter.native/helper"
override fun configureFlutterEngine(#NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "add") {
val num1 = call.argument<Int>("num1")
val num2 = call.argument<Int>("num2")
val sum = num1!! + num2!!
result.success(sum)
} else {
result.notImplemented()
}
}
}
}
Note: You should do the same thing in iOS native side or execute this method if the device is Android otherwise it will crash in iOS device

How can i make the first screen of my flutter show up before executing native based java code that will fetch data using a java library

i was working on some project with flutter that has to fetch data from the internet i tried to get it done using dart but it was not possible so i decided to do it in java and it works the problem the native java code started executing before the loading screen shows up on the screen and it shows some white screen and after that it just goes to the homepage is there anyway that i can make my loading screen appear first and then load the data from the internet as the loading screen is showing while the user waits and push the screen to the home screen after the loading is over.
i have tried putting sleep Duration for one second so that it can render the loading screen first but it didn't work.
Here is my java code
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "samples.flutter.dev/battery";
#Override
public void configureFlutterEngine( FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
if (call.method.equals("getDate")) {
try {
result.success(getReal2());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
else {
result.notImplemented();
}
}
);
}
public static List getCoffee() throws IOException {
ArrayList coffee = new ArrayList();
Document doc;
doc= Jsoup.connect("https://www.bankofabyssinia.com").timeout(6000).get();
for(int i=0;i<=8;i++) {
for (int j=2;j<=3;j++){
coffee.add(doc.select(" #myTable > tbody > tr:nth-child("+i+") > td:nth-child("+j+")").text());
}
}
return coffee;
}
#TargetApi(Build.VERSION_CODES.N)
public List getReal2() throws ExecutionException, InterruptedException {
CompletableFuture<List > completableFuture = CompletableFuture.supplyAsync(() -> {
try {
return getCoffee();
} catch (IOException e) {
e.printStackTrace();
}
return null;
});
while (!completableFuture.isDone()) {
}
List result = completableFuture.get();
return result;
}
}
and here is my flutter code
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'Home.dart';
class Load extends StatefulWidget {
#override
_LoadState createState() => _LoadState();
}
class _LoadState extends State<Load> {
static const platform = const MethodChannel('samples.flutter.dev/battery');
void getWholeJava() async {
try {
final List result = await platform.invokeMethod('getDate');
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => Home(
whole: result,
)));
} on PlatformException catch (e) {
print(e);
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
getWholeJava();
}
#override
Widget build(BuildContext context) {
return Scaffold(body: Builder(builder: (BuildContext context) {
return Container(
child: Center(
child: Column(
children: <Widget>[
Text(
'The app is loading',
style: TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.w900,
color: Colors.green[900]),
),
],
)),
);
}));
}
}
First, android will default to its launch screen, which is managed by launch_background.xml inside the template flutter android project. This means that you will need to use a background color for the splash screen, that will work with the android native launch screen drawable.
Next, to implement a splash screen, that will then navigate to a page, where you can run and load your data, you can look at this:
import 'package:async/async.dart';
class SampleSplashScreenPage extends StatefulWidget {
#override
_SampleSplashScreenPageState createState() => new _SampleSplashScreenPageState();
}
class _SampleSplashScreenPageState extends State<SampleSplashScreenPage> {
#override
void initState() {
super.initState();
new RestartableTimer(new Duration(seconds: 3), () async {
await Navigator.push(context, MaterialPageRoute(builder: (_) {
return FlutterDataLoadingPage();
}));
});
}
#override
Widget build(BuildContext context) {
return new Text("Your splash screen");
}
RestartableTimer is a class that will begin a stopwatch, and will count up to the designated duration. Once this duration is reached, it will then invoke the handler you pass to it, which in this case is the navigation logic to the page responsible for reading the remote data. This counter by the way does not restart, and will automatically be disposed by the garbage collector.
Take a look at the documentation to learn more:
https://api.flutter.dev/flutter/package-async_async/RestartableTimer-class.html

How to add Google Consent Android SDK to Flutter

Im trying to add the Google Android Consent SDK to Flutter and connect to it using a MethodChannel. I've got the form popping up successfully and I am able to return some info back to my main.dart file on the Flutter side.
I'm having trouble getting the users choice they selected from the Google Consent Form returned back to me to the Flutter side so I can then save whether they selected to see PERSONALIZED or NON-PERSONALIZED ads back in my main.dart file. Im just using the boilerplate Flutter example app to achieve this. Any help is greatly appreciated.
main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.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(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
static const CHANNEL = const MethodChannel("flutter.native/helper");
static const IS_EEA_OR_UNKNOWN_METHOD = "isEeaOrUnknown";
bool isEeaOrUnknown = true;
Future<bool> _isEeaOrUnknown() async {
var result = await CHANNEL.invokeMethod(IS_EEA_OR_UNKNOWN_METHOD);
if (result is bool) {
print("isEEAOrUnknown: $result");
return result;
} else {
print("WTF: $result");
return true;
}
}
void _callIsEea() {
_isEeaOrUnknown().then((result) {
Future.delayed(Duration(seconds: 3)).then((d) {
setState(() {
isEeaOrUnknown = result;
});
});
});
}
#override
void initState(){
super.initState();
_callIsEea();
}
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
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(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"iisEeaOrUnknown: $isEeaOrUnknown",
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
MainActivity.kt
package com.example.flutter_consent
import android.os.Bundle
import com.google.ads.consent.DebugGeography
import com.google.ads.consent.ConsentStatus
import com.google.ads.consent.ConsentInfoUpdateListener
import com.google.ads.consent.ConsentInformation
import com.google.ads.consent.ConsentFormListener
import com.google.ads.consent.ConsentForm
import io.flutter.app.FlutterActivity
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
import java.net.MalformedURLException
import java.net.URL
class MainActivity: FlutterActivity() {
var form: ConsentForm? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
MethodChannel(flutterView, CHANNEL).setMethodCallHandler { call, result ->
print("NATIVE method call")
when (call.method) {
IS_EEA_METHOD_NAME -> {
print("NATIVE METHOD CALLED - $IS_EEA_METHOD_NAME")
isEeaOrUnknown(result)
}
else -> {
print("NATIVE METHOD CALL ERROR")
result.notImplemented()
}
}
}
}
private fun isEeaOrUnknown(result: MethodChannel.Result){
val consentInformation = ConsentInformation.getInstance(this)
//testing only
consentInformation.debugGeography = DebugGeography.DEBUG_GEOGRAPHY_EEA
//consentInformation.debugGeography = DebugGeography.DEBUG_GEOGRAPHY_NOT_EEA
consentInformation.requestConsentInfoUpdate(arrayOf(PUBLISHER_ID), object : ConsentInfoUpdateListener {
override fun onConsentInfoUpdated(consentStatus: ConsentStatus) {
when (consentStatus) {
ConsentStatus.PERSONALIZED -> {
print("User selected personalized")
}
ConsentStatus.NON_PERSONALIZED -> {
print("User non-personalized")
}
ConsentStatus.UNKNOWN -> {
print("UNKNOWN")
}
}
}
override fun onFailedToUpdateConsentInfo(errorDescription: String) {
print("ERROR $errorDescription")
result.success(consentInformation.isRequestLocationInEeaOrUnknown)
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
var privacyUrl: URL? = null
try {
privacyUrl = URL("http://www.privacyurl.com/")
} catch (e: MalformedURLException) {
e.printStackTrace()
// Handle error.
}
form = ConsentForm.Builder(this, privacyUrl).withListener(object : ConsentFormListener() {
override fun onConsentFormLoaded() {
// Consent form loaded successfully.
form!!.show()
}
override fun onConsentFormOpened() {
// Consent form was displayed.
}
override fun onConsentFormClosed(
consentStatus: ConsentStatus?, userPrefersAdFree: Boolean?) {
// Consent form was closed.
}
override fun onConsentFormError(errorDescription: String?) {
// Consent form error.
}
})
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.build()
form!!.load()
}
companion object{
const val CHANNEL = "flutter.native/helper"
const val PUBLISHER_ID = "pub-xxxxxxxxxxxxxxx"
const val IS_EEA_METHOD_NAME = "isEeaOrUnknown"
}
}

Flutter: I got stuck with a problem in Flutter. I think the problem is the card that does not adapt dynamically

I got stuck with a problem in Flutter. I am a beginner and I think it is simple enough to solve. I think the problem is the card that does not adapt dynamically.
I apologize for spelling mistakes but I'm writing with google translator!
The user inserts a subject and a description from an input, when I try to show them on video in the Home Overview.
I am an Italian boy who has been very close to programming in Flutter and I started with this course. You are the only people I can address. I will offer a pizza Margherita to anyone who can solve this "problem";) !!!
The Widget AssegnoCard is simply a widget with dynamic data taken by input.
The error that Android Studio returns me is like this:
I/flutter (18690): The following assertion was thrown during
performResize():
I/flutter (18690): Vertical viewport was given unbounded height.
I/flutter (18690): Viewports expand in the scrolling direction to fill
their container.In this case, a vertical
I/flutter (18690): viewport was given an unlimited amount of vertical
space in which to expand. This situation
I/flutter (18690): typically happens when a scrollable widget is
nested inside another scrollable widget.
I/flutter (18690): If this widget is always nested in a scrollable
widget there is no need to use a viewport because
I/flutter (18690): there will always be enough vertical space for the
children. In this case, consider using a Column
I/flutter (18690): instead. Otherwise, consider using the "shrinkWrap"
property (or a ShrinkWrappingViewport) to size
I/flutter (18690): the height of the viewport to the sum of the
heights of its children.
The following code concerns the main.dart file, overview and the homework (where the ListView.builder is located). The code in the other files is identical to that of the video course:
//MAIN.DART
import 'package:flutter/material.dart';
import 'panoramica.dart';
import './assegno/gestione_assegno.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
final List<Map<String, dynamic>> _assegno = [];
void _aggiungiAssegno(Map<String, dynamic> assegno) {
setState(() {
_assegno.add(assegno);
});
print(_assegno);
}
void _aggiornaAssegno(int index, Map<String, dynamic> assegno) {
setState(() {
_assegno[index] = assegno;
});
}
void _eliminaAssegno(int index) {
setState(() {
_assegno.removeAt(index);
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
buttonColor: Colors.blue,
accentColor: Colors.blue,
),
//home: Panoramica(),
routes: {
'/': (BuildContext context) => Panoramica(_assegno),
'/gestioneassegno': (BuildContext context) => GestioneAssegno(_aggiungiAssegno, _aggiornaAssegno, _eliminaAssegno, _assegno),
},
onGenerateRoute: (RouteSettings settings) {
final List<String> pathElements = settings.name.split('/');
if (pathElements[0] != '') {
return null;
}
if (pathElements[1] == 'assegno') {
final int index = int.parse(pathElements[2]);
return MaterialPageRoute<bool>(
builder: (BuildContext context) => Panoramica(
_assegno[index]['materia'],
),
);
}
return null;
},
onUnknownRoute: (RouteSettings settings) {
return MaterialPageRoute(
builder: (BuildContext context) => Panoramica(_assegno ));
},
);
}
}
//OVERVIEW
import 'package:flutter/material.dart';
import './assegno/assegno.dart';
import 'drawer.dart';
// import 'eventi.dart';
class Panoramica extends StatelessWidget {
final List<Map<String, dynamic>> assegno;
Panoramica(this.assegno);
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(child: DrawerWidget()),
appBar: AppBar(
title: Text('Panoramica'),
),
body: Assegno(assegno),
//Eventi()
);
}
}
// HOMEWORK
import 'package:flutter/material.dart';
import 'assegno_card.dart';
class Assegno extends StatelessWidget {
final List<Map<String, dynamic>> assegno;
Assegno(this.assegno);
Widget _buildAssegnoList(BuildContext context) {
Widget assegnoCard;
if (assegno.length > 0) {
assegnoCard = ListView.builder(
itemBuilder: (BuildContext context, int index) =>
AssegnoCard(assegno[index], index),
itemCount: assegno.length,
);
} else {
assegnoCard = Container(
child: Card(
child: Column(
children: <Widget>[
ListTile(
title: Text('Assegno'),
leading: Icon(Icons.book),
),
Text('Non è inserito nessun assegno, aggiungerne uno'),
ButtonTheme.bar(
child: ButtonBar(
children: <Widget>[
FlatButton(
child: Text('Aggiungi assegno'),
onPressed: () {
Navigator.pushReplacementNamed(
context, '/gestioneassegno');
},
),
Icon(Icons.note_add, color: Colors.blue,)
],
),
),
],
),
),
);
}
return assegnoCard;
}
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Card(
child: _buildAssegnoList(context)
)
],
);
}
}
The build function for Assegno should have a Flexible or an Expanded widget in it like this:
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Flexible(child: Card(child: _buildAssegnoList(context)))
],
);
}

Categories