How to add album arts in flutter - flutter

I am using Flute music player plugin to make music player app in Flutter. But I am having a trouble for adding album art.
I wrote:
dynamic getImage(int idx) {
return _songs[idx].albumArt == null
? null
: new File.fromUri(Uri.parse(_songs[idx].albumArt));
}
And I used Image.file Widget:
Container(
childe: Image.file(getImage(_index))
)
And the result is:
I/flutter (15576): The following assertion was thrown building HyperMusicHome(dirty, state:
I/flutter (15576): _HyperMusicHomeState#b83f2):
I/flutter (15576): 'package:flutter/src/painting/image_provider.dart': Failed assertion: line 621 pos 14: 'file !=
I/flutter (15576): null': is not true.
I/flutter (15576):
I/flutter (15576): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (15576): more information in this error message to help you determine and fix the underlying cause.
I/flutter (15576): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (15576): https://github.com/flutter/flutter/issues/new?template=BUG.md

The error you're getting comes from this line in Flutter's FileImage class which checks whether what you're passing to Image.file() is null. It seems like the song you're currently viewing does not have an album art. All you need to do is not show the image when no album art is available.
I don't know what exactly your widget looks like, but you could do something like this:
#override
Widget build(BuildContext context) {
// Call `getImage` once to get the image file (which might be `null`)
final albumArtFile = getImage(_index);
return Container(
// Only show the image if `albumArtFile` is not `null`
child: albumArtFile != null ? Image.file(albumArtFile) : null,
);
}
You could also bundle a placeholder image with your app and show that when no album art is available:
albumArtFile != null ? Image.file(albumArtFile) : Image.asset('assets/placeholder.png')
You can learn more about adding assets to your app here.

Related

Flutter Testing: How to target (specific) widgets

I am testing an application created by the mobile apps division.
Hardly any of the widgets have any keys or labels to distinguish themselves from each other.
I'm having a hard timing even targeting a single widget, let alone 2 similar widgets on the same page; example: 2 text field widgets: username, password.
Right now, the only test I have is this:
testWidgets('Empty Login Box', (WidgetTester tester) async {
app.main();
await tester.pumpAndSettle();
final emailText = find.text("EMAIL");
expect(emailText, findsOneWidget);
});
And even this doesn't work. Here's the response:
00:40 +0: ...\EndevStudios\MedicalApp\gshDevWork\medical-app-frontend\integration_test\mock_image_upload_test.dart I00:43 +0: ...\EndevStudios\MedicalApp\gshDevWork\medical-app-frontend\integration_test\mock_image_upload_test.d 2,854ms
00:47 +0: Login Page Tests Empty Login Box
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
Actual: _TextFinder:<zero widgets with text "EMAIL" (ignoring offstage widgets)>
Which: means none were found but one was expected
When the exception was thrown, this was the stack:
#4 main.<anonymous closure>.<anonymous closure> (file:///D:/WEBDEV/EndevStudios/MedicalApp/gshDevWork/medical-app-frontend/integration_test/mock_image_upload_test.dart:29:7)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)
This was caught by the test expectation on the following line:
file:///D:/WEBDEV/EndevStudios/MedicalApp/gshDevWork/medical-app-frontend/integration_test/mock_image_upload_test.dart line 29
The test description was:
Empty Login Box
════════════════════════════════════════════════════════════════════════════════════════════════════
00:47 +0 -1: Login Page Tests Empty Login Box [E]
Test failed. See exception logs above.
The test description was: Empty Login Box
00:48 +0 -1: Some tests failed.
I've been trying to use these CommonFinders class, but I can't seem to utilize them effectively.
https://docs.flutter.dev/cookbook/testing/widget/finders
https://api.flutter.dev/flutter/flutter_driver/CommonFinders-class.html
https://api.flutter.dev/flutter/flutter_test/CommonFinders-class.html
To anyone who can, please help!
You need to first pump your widget, if you don't do that, the Finder is not going to find your widget and will error:
The following TestFailure was thrown running a test: Expected: exactly
one matching node in the widget tree Actual: _TextFinder:<zero
widgets with text "EMAIL" (ignoring offstage widgets)> Which: means
none were found but one was expected
Try the following code:
testWidgets('Empty Login Box', (WidgetTester tester) async {
/// Pump your widget first:
await tester.pumpWidget(const LoginBoxWidget(
title: 'My Title',
message: 'Another parameter...',
)); // Parameters depend on your widget
final emailText = find.text("EMAIL");
expect(emailText, findsOneWidget);
});

setState() or markNeedsBuild() called during build inside a StreamBuilder

I am using this StreamBuilder to get the current location:
StreamBuilder<UserLocation>(
stream: locationService.locationStream,
builder: (context, snapshot) {
if (snapshot.data != null) {
bool es_actual = ubicacionesProvider.ubicacionActualSeleccionada;
bool es_elegida = ubicacionesProvider.ubicacionElegidaSeleccionada;
if(es_actual){
latitudData = snapshot.data.latitude;
// ubicacionesProvider.setlatitudActual(latitudData);
longitudData = snapshot.data.longitude;
//ubicacionesProvider.setlongitudActual(longitudData);
Coordinates misCoordenadas =
new Coordinates(latitudData, longitudData);
// ubicacionesProvider.setubicacionActual(_miDireccionActual);
getAddress(misCoordenadas);
}
if(es_elegida){
_latitudElegida = ubicacionesProvider.latitudElegida;
_longitudElegida = ubicacionesProvider.longitudElegida;
_miDireccionActual = ubicacionesProvider.ubicacionElegida;
}
}
I want to update a provider called ubicacionesProvider with some changes:
ubicacionesProvider.setlatitudActual(latitudData)
ubicacionesProvider.setlongitudActual(longitudData)
ubicacionesProvider.setubicacionActual(_miDireccionActual)
But I am getting a warning using one or all of them, the app is not exiting but the warning is shown:
======== Exception caught by foundation library ====================================================
The following assertion was thrown while dispatching notifications for UbicacionesProvider:
setState() or markNeedsBuild() called during build.
This _InheritedProviderScope<UbicacionesProvider> widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: _InheritedProviderScope<UbicacionesProvider>
value: Instance of 'UbicacionesProvider'
listening to value
The widget which was currently being built when the offending call was made was: StreamBuilder<UserLocation>
dirty
dependencies: [MediaQuery]
state: _StreamBuilderBaseState<UserLocation, AsyncSnapshot<UserLocation>>#39568
When the exception was thrown, this was the stack:
#0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4292:11)
#1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4307:6)
#2 _InheritedProviderScopeElement.markNeedsNotifyDependents (package:provider/src/inherited_provider.dart:496:5)
#3 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:226:25)
#4 UbicacionesProvider.setlatitudActual (package:flutter_qplan/providers/ubicaciones_provider.dart:50:5)
...
The UbicacionesProvider sending notification was: Instance of 'UbicacionesProvider'
====================================================================================================
I would like to update the provider without getting that warning.
Usually this happens when you setState or notifyListeners before the build has finished building all the widgets. Maybe you can add your update logic like this :
WidgetsBinding.instance!.addPostFrameCallback((_) {
// Add Your Update Code here.
});

Failed assertion: line 556 pos 15: 'scrollOffsetCorrection != 0.0': is not true

After Upgrading the flutter to the latest version. I'm facing this issue, I've the same code for another application having earlier version of flutter and it is working fine.
With the new ListView add two or more children.
Scroll down the list to the point where the first child is entirely off the screen.
Scroll all the way back up to the initial position. The ListView shows nothing on screen (just white empty space).
Attaching minimal reproducible code:
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MYYApp(),
);
}
}
class MYYApp extends StatefulWidget {
#override
_MYYAppState createState() => _MYYAppState();
}
class _MYYAppState extends State<MYYApp> {
final list = [
'BMW',
'Fiat',
'Toyota',
'Fiat',
'Testa',
'Fiat',
'Ford',
'Fiat',
'BMW',
'Fiat',
'Toyota',
'Fiat',
'Testa',
'Fiat',
'Ford',
'Fiat'
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ListView.builder(
itemCount: list.length,
itemBuilder: (context,index){
return list[index]=='Fiat'? //list[index] == 'Fiat' (this condition check is responsible for the issue and earlier it was not an issue)
Container(
height: 300,
child: Center(child: Text(list[index])),
):Container();
})
),
);
}
}
Here's the error:
════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The method '-' was called on null.
Receiver: null
Tried calling: -(223.60756587000844)
The relevant error-causing widget was:
ListView file:///C:/Users/prave/AndroidStudioProjects/for_stackoverflow/lib/main.dart:49:25
════════════════════════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during performLayout():
'package:flutter/src/rendering/sliver.dart': Failed assertion: line 556 pos 15: 'scrollOffsetCorrection != 0.0': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
The relevant error-causing widget was:
ListView file:///C:/Users/prave/AndroidStudioProjects/for_stackoverflow/lib/main.dart:49:25
When the exception was thrown, this was the stack:
#2 new SliverGeometry (package:flutter/src/rendering/sliver.dart:556:15)
#3 RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:180:20)
#4 RenderObject.layout (package:flutter/src/rendering/object.dart:1769:7)
#5 RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:137:11)
#6 RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:377:11)
This is only a part of error,it produces nearly 10 same kind of errors.
The error vanishes as soon as you give your alternative non-Fiat container a height of non-zero.
I don't know exactly why that is or if it's on purpose, but the list seems to have problems with zero-height elements.
I suggest you actually use a filtering mechanism on your data and not work around that part by making it zero height in the view as an afterthought.
I have same issue after upgrade flutter framework.
For me the description of problem is:
The issue: when you use a Container or Widget without child and or without height property inside ListVIew
The solution: Just give height property to Widget that inside ListView.
This is my code, that's worked for me
.......
body: ListView(
shrinkWrap: true,
children: <Widget>[
Auth ? Container(height: 1): signUpWidget() , // Add height property to Container
.....
......
]
)
Min height should be greater than 0. You can put it 0.1. It may be a bug but it works.
ListView(
shrinkWrap: true,
children: <Widget>[
SizedBox(height: 0.1,);
]

Showing dialog with bottom navigationbar flutter

I want to show Dialog instead of function using bottom navigation bar in flutter.How can I implement that?
#override
Widget build(BuildContext context) {
Widget child = Container();
switch(_selectedIndex) {
case 0:
child = function_1();
print("done");
break;
case 1:
child = function_1();
break;
}
When I use ShowDialog method It says:
The following assertion was thrown building ServerGrid(dirty; state: _ServerGridState#59211289()):
I/flutter (14351): setState() or markNeedsBuild() called during build.
I/flutter (14351): This Overlay widget cannot be marked as needing to build because the framework is already in the
I/flutter (14351): process of building widgets. A widget can be marked as needing to be built during the build phase
I/flutter (14351): only if one of its ancestors is currently building. This exception is allowed because the framework
I/flutter (14351): builds parent widgets before children, which means a dirty descendant will always be built.
I/flutter (14351): Otherwise, the framework might not visit this widget during this build phase.

Set a provide after Future returns results

I'm trying to modify data using a provider after a Future returns with data.
class FirstPart extends StatelessWidget {
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getAll(),
initialData: Text('Loading Bro'),
builder: (context, snapshot) {
if (snapshot.hasError)
return Text('error here bro');
else if (snapshot.hasData) {
final toDoListManager = Provider.of<ListManager>(context);
toDoListManager.list = snapshot.data;
return Text('loaded');
}
return Text('load');
},
);
}
}
Future<void> getAll() async {... API Request}
I get an error when I set the value of the provider. (I removed a lot of the error because it was too long for Stack Overflow.)
How can I modify a provider after a Future has results?
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building FutureBuilder<void>(dirty, dependencies:
flutter: [InheritedProvider<ListManager>], state: _FutureBuilderState<void>#fe02e):
flutter: type 'Text' is not a subtype of type 'List<ListItem>'
flutter:
flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially
flutter: more information in this error message to help you determine and fix the underlying cause.
flutter: In either case, please report this assertion by filing a bug on GitHub:
flutter: https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: User-created ancestor of the error-causing widget was:
flutter: FirstPart
package:crud_todo/home.dart:16
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 FirstPart.build.<anonymous closure>
package:crud_todo/home.dart:32
flutter: #1 _FutureBuilderState.build (package:flutter/src/widgets/async.dart)
setState() or markNeedsBuild() called during build.
There are some strange things going on there:
Your toDoListManager is a ListManager, toDoListManager.list returns a List and you are trying to assing a Text to thise list item since snapshot.data returns a Text Widget as initialData toDoListManager.list = snapshot.data;
Another strange thing is that your getAll returns a future of void when in my opinion should return a future of List