Where do I wrong?
I created this method,
I get no issue in debugger, but when I run the app I get this error.
The following NoSuchMethodError was thrown building:
The method '[]' was called on null.
Receiver: null
Tried calling:
How can I solve this issue?
late String urlImage;
late String urlImageSource;
var _post;
final List<Article> _posts = [
Article(
urlImage: 'urlImage',
urlImageSource: 'urlImageSource',
title: 'title',
description: 'description',
),
];
String checkIfUrlContainPrefixHttps(String urlImageSource) {
if (!urlImageSource.startsWith("//") || !urlImageSource.startsWith("http")) {
return urlImageSource;
} else {
return 'https://' + urlImageSource;
}
}
Widget image
SizedBox(
height: 190,
width: double.infinity,
child: CachedNetworkImage(
imageUrl: checkIfUrlContainPrefixHttps(_post[0].urlImageSource),
fit: BoxFit.cover,
placeholder: (context, url) => Image.asset("assets/gif/shimmer.gif",
width: double.infinity,
height: 190,
fit: BoxFit.cover,
),
errorWidget: (context, url, error) =>
Image.asset("assets/images/unloadedImage.png",
width: 250,
height: 250,
),
),
)
Your _post is null and you are trying to get 0 item in it, try this:
checkIfUrlContainPrefixHttps(_post != null ? _post[0].urlImageSource :'')
Related
I am using CacheNetworkImage for displaying an image, I have a use case like I have to show loading on the whole Container until the image is not rendered. Is there any way I can get to know that my image is successfully rendered on screen?
This is what I have done so far:
return CachedNetworkImage(
fit: BoxFit.fill,
imageUrl: url,
errorWidget: (a, b, c) => const Center(child: Icon(Icons.error_outline)),
progressIndicatorBuilder: (context, _, DownloadProgress progress) {
getProgressStatus(progress);
return Shimmer(color: Colors.grey, child: const SizedBox.expand());
},
);
void getProgressStatus(DownloadProgress loadingStatus) {
if (loadingStatus.downloaded == loadingStatus.totalSize) {
scheduleMicrotask(() {
setState(() {
isLoaded = true;
});
});
return;
}
scheduleMicrotask(() {
setState(() {
isLoaded = false;
});
});
}
By using progressIndicatorBuilder property of CachedNetworkImage you can manage it,
progressIndicatorBuilder: (context, url, downloadProgress) =>
Container(
margin: EdgeInsets.only(
top: 100.h,
bottom: 100.h
),
child: CircularProgressIndicator(
value: downloadProgress.progress,
color: AppColors.lightBlack)),
)
You can use placeholder until the image is loaded. This is how you can use it.
CachedNetworkImage(
placeholder: placeholderWidgetFn() as Widget Function(
BuildContext, String)?,
imageUrl: imgURL,
width: 300,
height: (MediaQuery.of(context).size.height) / 2.5,
),
Widget? Function(BuildContext, String) placeholderWidgetFn() =>
(_, s) => placeholderWidget();
Widget placeholderWidget() =>
Image.asset('images/placeholder.jpg', fit: BoxFit.cover);
Usecase: I have a tile in which i have added CacheNetworkImage & I want to add the PlaceHolder on the whole tile until that specific image not loads.
See this image for what I want to achieve
I have achieve this using Stack widget.
Stack(
children: [
MyTile(
image: CacheNetworkImage(imageUrl)
),
SizedBox(
width: double.infinity,
height: ///Same as your lower container
child CacheNetworkImage(
imageUrl: imageUrl,
fit: BoxFit.fill,
color: Colors.transparent,
colorBlendMode: BlendMode.clear,
placeholder: (context, _) {
return MyPlaceHolder(...)
},
)
],
),
Note: Image url for both the child's will be exactly same
I am working on uploading the uint8List type image to Firestore and get it again.
I have converted to String to upload to Firestore.
Future _pageDrawScreen() async {
// screenshot pakage
Uint8List? _previewImage = await _testController.capture(); // get uint8List image data
if (_previewImage == null) {
logger.d("_previewImage null");
}
// convert to String
_pageModel!.previewImage = _previewImage.toString();
// Firestore update
}
Then, I take the image data again, convert it, and output it as a memory image.
Widget _pageContainer(int index, PageModel pageModel) {
// get image and convert
Uint8List? previewImage;
if (pageModel.previewImage != null) {
List<int> list = pageModel.previewImage!.codeUnits;
previewImage = Uint8List.fromList(list);
// logger.d(previewImage);
}
return ListTile(
title: pageModel.previewImage != null
? ExtendedImage.memory(
previewImage!,// error!
width: 125,
height: 125,
fit: BoxFit.cover,
// check image state
loadStateChanged: (state) {
switch (state.extendedImageLoadState) {
case LoadState.loading:
return const SizedBox(
width: 50,
height: 50,
child: CircularProgressIndicator(
color: Colors.red,
),
);
case LoadState.completed:
return null;
// Failed error!!
case LoadState.failed:
return const Material(
color: Colors.white,
child: Icon(
Icons.cancel,
color: Colors.red,
size: 50,
),
);
}
},
)
: Container(
width: 125,
height: 125,
color: Colors.white,
child: const Center(
child: CircularProgressIndicator(),
),
),
);
}
However, this image is checked as an error state. Is the conversion of Uint8List wrong?
Expected Results (When using the uint8list image as it is,
):
Actual Results:
import
import 'dart:convert';
for uploading
Uint8List? _previewImage = await _testController.capture();
if(_previewImage != null){
String previewImage = base64.encode(_previewImage);
}
after fetching the image data
Uint8List previewImage = base64.decode(previewImage);
Hello so I added a way to display my url images in a list but because Im fetching this information from public API some of them are missing URLs and errors occur, I tried using placeholder and image errorbuilder but that didnt help
Here is my code:
child: FadeInImage.assetNetwork(
height: 100,
width: 100,
fit: BoxFit.fill,
image: newsList[index].urlToImage,
placeholder: 'images/placeholder.png',
imageErrorBuilder: (context, error, StackTrace) {
return const Image(
height: 100,
width: 100,
image: AssetImage("images/placeholder.png"));
},
),
and Error:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building:
'package:flutter/src/widgets/fade_in_image.dart': Failed assertion: line 234 pos 15: 'image !=
null': is not true.
Updated Code:
child: newsList[index].urlToImage == null
? Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/placeholder.png"),
),
),
)
: FadeInImage.assetNetwork(
height: 100,
width: 100,
fit: BoxFit.fill,
image: newsList[index].urlToImage,
placeholder: 'images/placeholder.png',
imageErrorBuilder:
(context, error, StackTrace) {
return const Image(
height: 100,
width: 100,
image:
AssetImage("images/placeholder.png"));
},
),
and error message:
imageErrorBuilder will only be called if there is an error occurs during image loading, example the image path does not exist.
To fix your issue, you have to check whether url is null or empty. If it is null, display another widget, else display FadeInImage.
newsList[index].urlToImage == null ? DisplayNoImage: FadeInImage.assetNetwork(...),
I'm going round in circles with this and would appreciate a fresh viewpoint.
I have the following button, which when tapped must display an image. The image data is fetched from the backend (this part works fine).
IconButton(
icon: Icon(
Icons.attach_email_rounded,
size: 32.0,
),
color: Colors.grey,
onPressed: () async {
await showDialog(
context: context,
builder: (_) => showAttachment( // <-- error here
appstate['arg1'],
appstate['arg2'],
appstate['arg3]),
);
},
)
Function:
Future<Dialog> showAttachment(arg1, arg2, arg3) async {
Uint8List attachmentData;
await getAttachment(arg1, arg2, arg3).then(
(value) => {
attachmentData = value,
},
);
return Dialog(
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: Image.memory(attachmentData).image,
fit: BoxFit.cover,
),
),
),
);
}
However, I'm getting the error The return type 'Future<Dialog>' isn't a 'Widget', as required by the closure's context.
Googling around has revealed I need to use FutureBuilder, but I'm not sure how to incorporate that in the above closure code.
I'd appreciate pointers.
Thanks
The builder functions for showDialog is synchronous, so in order to use a future we'll have to nest a FutureBuilder into the Dialog and keep the containing function synchronous.
I've adapted your code sample to demonstrate:
Dialog showAttachment(arg1, arg2, arg3) {
return Dialog(
child: FutureBuilder<Uint8List>(
future: getAttachment(arg1, arg2, arg3),
builder: (context, snapshot) {
return snapshot.hasData
? Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: Image.memory(snapshot.data!).image,
fit: BoxFit.cover,
),
),
)
: const CircularProgressIndicator();
},
),
);
}
It's important to remember that, unless you provide the optional initial data argument for the FutureBuilder, the first time the builder is called, the snapshot won't have data: so we should check that.
Also not shown above is handling errors; which is done in the same way as checking if the snapshot has data.
FutureBuilder Documentation
I'm trying to show the user image URL In the CircleAvatar(); It's showing a null error even though I've provided it. Or am I doing it wrong?
First I call the Auth Methods and Set image String img,
AuthMethods _auth = AuthMethods();
String img;
I then instantiate in initstate
_auth.getCurrentUser().then((user) async {
setState(() {
user.uid;
img = user.photoUrl
});
});
}
Then call it in the Drawer()
DrawerHeader(
child: CircleAvatar(
backgroundColor: Colors.deepOrange,
radius: 100,
child: Image(
fit: BoxFit.cover,
image: NetworkImage(
img != null ? img : Container(), // <== here
) ??
CircularProgressIndicator(),
),
),
decoration: BoxDecoration(
color: Colors.orange,
),
),
NetworkImage takes a String as perimeter, not a widget.
In your case:
NetworkImage(
img != null ? img : Container(), // <== here
)
if img i.e. String is null than you are returning Container(), but you should return a String (maybe you can give an empty string)
NetworkImage takes image URL in its String parameter, in your case you are passing either image URL or Widget into this parameter and obviously Widget is not String. Your null check should be above NetworkImage like this:
...
image:
img != null ? NetworkImage(img)
:
CircularProgressIndicator(),
//Or container or different desired widget in case image path is null
...