No host specified in URI (Flutter) - android

So I have this code and I take an image from Internet with webscrapper, the problem is that when I try to take the image with the basic URl without the http:// behind it don't work and when I add it I don't have any error but I got a black screen on my emulator and I can't see this value of the image on my terminal even if I know the value is not null.
If someone can help I will be very greatful thank you very much !
class ContentScreen extends StatefulWidget {
const ContentScreen({Key? key}) : super(key: key);
#override
_ContentScreenState createState() => _ContentScreenState();
}
class _ContentScreenState extends State<ContentScreen> {
List<Map<String,dynamic>>? contentPages;
bool Data = false;
Future<void> getcontent() async{
final webscraper = WebScraper("https://manhuas.net/");
String TempRoute = "manhua/what-harm-would-my-girl-do-manhua/what-harm-would-my-girl-do-chapter-1/";
if (await webscraper.loadWebPage(TempRoute)){
contentPages = webscraper.getElement("div.page-break.no-gaps > img ", ["data-src"]);
setState(() {
Data = true;
});
print(contentPages);
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
getcontent();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getcontent(),
builder: (context, snapshot) {
return Scaffold(
body: Data? Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: contentPages!.length,
itemBuilder: (context,index ) {
return Image.network(contentPages![index]['attributes']['src'].toString().trim(),
fit: BoxFit.fitWidth,loadingBuilder: (context , child, loadingprogress){
if (loadingprogress != null) return child;
return Center(
child: CircularProgressIndicator(),
);
},);
},
)
)
: Center(
child: CircularProgressIndicator(
color: Constants.mygreen,
)
));
}
);
}
}
And this is a screen of my screen for more details:

Please check the below code it's working perfectly
import 'package:flutter/material.dart';
import 'package:web_scraper/web_scraper.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'OverlayEntry Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: ContentScreen(),
);
}
}
class ContentScreen extends StatefulWidget {
const ContentScreen({Key? key}) : super(key: key);
#override
_ContentScreenState createState() => _ContentScreenState();
}
class _ContentScreenState extends State<ContentScreen> {
List<Map<String, dynamic>>? contentPages;
bool Data = false;
Future<void> getcontent() async {
final webscraper = WebScraper("https://manhuas.net/");
String TempRoute =
"manhua/what-harm-would-my-girl-do-manhua/what-harm-would-my-girl-do-chapter-1/";
if (await webscraper.loadWebPage(TempRoute)) {
contentPages =
webscraper.getElement("div.page-break.no-gaps > img ", ["data-src"]);
setState(() {
Data = true;
});
print(contentPages);
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
getcontent();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getcontent(),
builder: (context, snapshot) {
return Scaffold(
body: Data
? Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: contentPages!.length,
itemBuilder: (context, index) {
return Image.network(
contentPages![index]['attributes']
['data-src']
.toString()
.trim(),
fit: BoxFit.fitWidth,
);
},
))
: Center(
child: CircularProgressIndicator(
color: Colors.green,
)));
});
}
}

Related

ProviderNotFoundException - Could not find the correct Provider

Hello fellow Flutter Devs
I am pretty new to Flutter and I am building a bottom navigation bar with three pages and on one page the will be a list with items from an API using the bloc architecture. However I am getting the error in the title located to the ListPage().
ProviderNotFoundException (Error: Could not find the correct Provider above this ListPage Widget
ListPage():
class ListPage extends StatelessWidget {
const ListPage({super.key});
#override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => ListCubit(
repository: context.read<ListRepository>(),
)..fetchList(),
child: const ItemListView(),
);
}
}
class ItemListView extends StatelessWidget {
const ItemListView({super.key});
#override
Widget build(BuildContext context) {
final state = context.watch<ListCubit>().state;
switch (state.status) {
case ListStatus.failure:
return const Center(child: Text('Oops something went wrong!'));
case ListStatus.success:
return ItemView(items: state.items);
case ListStatus.loading:
return const Center(child: CircularProgressIndicator());
}
}
}
class ItemView extends StatelessWidget {
const ItemView({super.key, required this.items});
final List<Item> items;
#override
Widget build(BuildContext context) {
return items.isEmpty
? const Center(child: Text('no content'))
: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ItemTile(
item: items[index],
);
},
itemCount: items.length,
);
}
}
class ItemTile extends StatelessWidget {
const ItemTile({
super.key,
required this.item,
});
final Item item;
#override
Widget build(BuildContext context) {
return Material(
child: ListTile(
leading: Text('#${item.id}'),
title: Text(item.position),
),
);
}
}
The ListPage() is in the HomePage():
class HomePage extends StatelessWidget {
const HomePage({super.key});
static Route<void> route() {
return MaterialPageRoute<void>(builder: (_) => const HomePage());
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: BlocBuilder<BottomNavigationBloc, BottomNavigationState>(
builder: (BuildContext context, BottomNavigationState state) {
if (state is PageLoading) {
return Center(child: CircularProgressIndicator());
}
if (state is ListPageLoaded) {
return ListPage();
}
if (state is SettingsPageLoaded) {
return SettingsPage(
biometrics: state.biomentrics,
version: state.version,
env: state.env,
);
}
return Container();
},
),
bottomNavigationBar:
BlocBuilder<BottomNavigationBloc, BottomNavigationState>(
builder: (BuildContext context, BottomNavigationState state) {
return BottomNavigationBar(
...
And last but not least, my app.dart:
class App extends StatelessWidget {
const App({
super.key,
required this.authenticationRepository,
required this.userRepository,
required this.listRepository,
required this.settingsRepository,
});
final AuthenticationRepository authenticationRepository;
final UserRepository userRepository;
final ListRepository listRepository;
final SettingsRepository settingsRepository;
#override
Widget build(BuildContext context) {
return RepositoryProvider.value(
value: authenticationRepository,
child: MultiBlocProvider(
providers: [
BlocProvider(
create: (_) => AuthenticationBloc(
authenticationRepository: authenticationRepository,
userRepository: userRepository,
),
),
BlocProvider(
create: (_) => BottomNavigationBloc(
listPageRepository: listRepository,
settingsPageRepository: settingsRepository))
],
child: const AppView(),
));
}
}
class AppView extends StatefulWidget {
const AppView({super.key});
#override
State<AppView> createState() => _AppViewState();
}
class _AppViewState extends State<AppView> {
final _navigatorKey = GlobalKey<NavigatorState>();
NavigatorState get _navigator => _navigatorKey.currentState!;
#override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _navigatorKey,
builder: (context, child) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
switch (state.status) {
case AuthenticationStatus.authenticated:
_navigator.pushAndRemoveUntil<void>(
HomePage.route(),
(route) => false,
);
break;
case AuthenticationStatus.unauthenticated:
_navigator.pushAndRemoveUntil<void>(
LoginPage.route(),
(route) => false,
);
break;
case AuthenticationStatus.unknown:
break;
}
},
child: child,
);
},
onGenerateRoute: (_) => SplashPage.route(),
);
}
}
As the error says it could not find the right provider I probably need to add it somewhere in my project but i don't know where because I added the ListRepository in my App(). Do I need to add in the _AppViewState() as well?
Thanks for your help and I will give additional information in the comments if you need so.

type 'Future<dynamic>' is not a subtype of type 'List<Application>?'

I am trying to create a search widget in flutter, for list I used the application list using device_apps (https://pub.dev/packages/device_apps). But Im getting an error "type 'Future' is not a subtype of type 'List?'" . To create the search widget I used help from this link.
Here is my code:
import 'dart:async';
import 'package:device_apps/device_apps.dart';
import 'package:flutter/material.dart';
class SearchWidget extends StatelessWidget {
SearchWidget({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
TextField(onChanged: _filter),
StreamBuilder<List<Application>>(
initialData: lelist(),
stream: _stream,
builder:
(BuildContext context, AsyncSnapshot<List<Application>> snapshot) {
print(snapshot.data);
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Text(snapshot.data[index].appName);
},
);
},
)
],
),
);
}
}
StreamController<List<Application>> _streamController = StreamController<List<Application>>();
Stream<List<Application>> get _stream => _streamController.stream;
_filter(String searchQuery) {
List<Application> _filteredList = lelist()
.where((Application app) => app.appName.toLowerCase().contains(searchQuery.toLowerCase()))
.toList();
_streamController.sink.add(_filteredList);
}
lelist() async {
List<Application> _dataFromQuerySnapShot = await DeviceApps.getInstalledApplications(includeAppIcons: true);
_dataFromQuerySnapShot.sort((a, b) {
return a.appName.toString().toLowerCase().compareTo(b.appName.toString().toLowerCase());
});
return _dataFromQuerySnapShot;
}
I think there it is unnecessary to load and sort the installed apps on every keystroke and therefore put all of this logic into initState. This also makes your _filter function synchronous.
import 'dart:async';
import 'package:device_apps/device_apps.dart';
import 'package:flutter/material.dart';
class SearchWidget extends StatefulWidget {
SearchWidget({Key key}) : super(key: key);
#override
_SearchWidgetState createState() => _SearchWidgetState();
}
class _SearchWidgetState extends State<SearchWidget> {
final _streamController = StreamController<List<Application>>();
List<Application> _dataFromQuerySnapShot;
Stream<List<Application>> get _stream => _streamController.stream;
#override
void initState() {
DeviceApps.getInstalledApplications(includeAppIcons: true)
.then((List<Application> apps) {
_dataFromQuerySnapShot = apps;
_dataFromQuerySnapShot.sort((a, b) {
return a.appName
.toString()
.toLowerCase()
.compareTo(b.appName.toString().toLowerCase());
});
_streamController.sink.add(_dataFromQuerySnapShot);
});
super.initState();
}
#override
void dispose() {
_streamController.close();
super.dispose();
}
_filter(String searchQuery) {
final filteredApplications = _dataFromQuerySnapShot
.where((Application app) =>
app.appName.toLowerCase().contains(searchQuery.toLowerCase()))
.toList();
_streamController.sink.add(filteredApplications);
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
TextField(onChanged: _filter),
StreamBuilder<List<Application>>(
stream: _stream,
builder: (BuildContext context,
AsyncSnapshot<List<Application>> snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
return snapshot.data.isEmpty
? Center(child: Text('Empty'))
: ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Text(snapshot.data[index].appName);
},
);
},
)
],
),
);
}
}
I think you need to add asList after calling your future.
lelist() async {
List<Application> _dataFromQuerySnapShot = await
DeviceApps.getInstalledApplications(includeAppIcons: true);
_dataFromQuerySnapShot.sort((a, b) {
return
a.appName.toString().toLowerCase().compareTo(b.appName.toString().toLowerCase());
}) as List;
return _dataFromQuerySnapShot;
}

Flutter call form save function from another file

I have this event form, it's to create or edit events data. The save button is inside the app bar action, and the form is inside the body. In this project, I have all of the widgets in different files. How do I run the save function inside EventFormForm.dart when I tap the save button inside EventFromAppBar.dart?
This is the structure :
These are my codes :
EventForm.dart
class EventForm extends StatelessWidget {
// Some Code
// Some Const
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: EventFormAppBar(
// Some Params
),
body: EventFormBody(
// Some Params
)
);
}
}
EventFormAppBar.dart
class EventFormAppBar extends PreferredSize{
// Some Code
// Some Const
// Some Code
#override
Widget build(BuildContext context) {
return AppBar(
// Some Code
actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: () {
}
)
]
);
}
}
EventFormBody.dart
class EventFormBody extends StatelessWidget {
// Some Code
// Some Const
#override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: EventFormForm(
// Some Params
),
),
);
}
}
EventFormForm.dart
class EventFormForm extends StatefulWidget {
// Some Code
// Some Const
#override
EventFormFormState createState() => EventFormFormState();
}
class EventFormFormState extends State<EventFormForm> {
//
//
// Some Code
//
//
#override
Widget build(BuildContext context) {
return Form(
//
// Some Code
//
);
}
saveForm() {
//
// Some Code
//
}
}
Tag #chunhunghan
You can copy paste run each files below
Step 1: Use final keyForm = GlobalKey<EventFormFormState>();
Step 2: Pass keyForm to EventFormForm(key: keyForm)
Step 3: In IconButton call keyForm.currentState.saveForm();
IconButton(
icon: Icon(Icons.save),
onPressed: () {
keyForm.currentState.saveForm();
})
working demo
full code
main.dart
import 'package:flutter/material.dart';
import 'event_form.dart';
import 'event_form_form.dart';
void main() => runApp(MyApp());
final keyForm = GlobalKey<EventFormFormState>();
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: EventForm(),
);
}
}
event_form.dart
import 'package:flutter/material.dart';
import 'event_form_appbar.dart';
import 'event_form_body.dart';
class EventForm extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(appBar: EventFormAppBar(), body: EventFormBody());
}
}
event_form_appbar.dart
import 'package:flutter/material.dart';
import 'main.dart';
class EventFormAppBar extends PreferredSize {
#override
Widget build(BuildContext context) {
return AppBar(actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: () {
keyForm.currentState.saveForm();
})
]);
}
#override
get preferredSize => Size.fromHeight(50);
}
event_form_body.dart
import 'package:flutter/material.dart';
import 'main.dart';
import 'event_form_form.dart';
class EventFormBody extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: EventFormForm(key: keyForm),
),
);
}
}
event_form_form.dart
import 'package:flutter/material.dart';
class EventFormForm extends StatefulWidget {
EventFormForm({Key key}) : super(key: key);
#override
EventFormFormState createState() {
return EventFormFormState();
}
}
class EventFormFormState extends State<EventFormForm> {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: RaisedButton(
onPressed: () {
saveForm();
},
child: Text('Submit'),
),
),
],
),
);
}
void saveForm() {
print("execute save Form");
if (_formKey.currentState.validate()) {
// If the form is valid, display a Snackbar.
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('Processing Data')));
}
}
}

Flutter - How correctly pause camera when user moved to other (preview) screen?

I need to pause camera when I move to another screen on the navigator tree in order to save battery and performance.
I tried to dispose() cameraController, but flutter doesn't re-initialize the state when it returns from another screen (which is obvious, though).
My main code to work with a camera:
#override
void initState() {
super.initState();
availableCameras().then((cameras) {
setState(() {
_firstCamera = cameras.first;
_controller = CameraController(_firstCamera, ResolutionPreset.high);
_initializeControllerFuture = _controller.initialize();
});
});
}
#override
void dispose() {
_controller?.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: Stack(
children: <Widget>[
FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Stack(
alignment: FractionalOffset.center,
children: <Widget>[
new Positioned.fill(
child: _getCameraPreview(context),
),
...
],
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
Align(
alignment: Alignment.bottomCenter,
child: BottomAppBar(
color: Color.fromARGB(0, 0, 0, 0),
child: _getBottomAppBarRow(context),
),
),
],
),
);
}
_getCameraPreview(BuildContext context) {
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Transform.scale(
scale: _controller.value.aspectRatio / deviceRatio,
child: Center(
child: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: CameraPreview(_controller),
),
),
);
}
Have a variable like _cameraOn = true. Show CameraPreview when it is true and not when it is false. While navigating to another screen set it to false
You could have the camera related functionality in a separate widget. So every time it is displayed it is initialized, and when it is not it's disposed.
A simple working example
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
List<CameraDescription> cameras;
Future<void> main() async {
cameras = await availableCameras();
runApp(MaterialApp(
home: CameraApp(),
));
}
class CameraApp extends StatefulWidget {
#override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
bool _cameraOn = true;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
child: _cameraOn ? Camera() : Container(),
),
FlatButton(
onPressed: () {
setState(() {
_cameraOn = false;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => Post())).then((res) {
setState(() {
_cameraOn = true;
});
}).catchError((err) {
print(err);
});
},
child: Text("NEXT PAGE"),
),
],
),
);
}
}
class Camera extends StatefulWidget {
#override
_CameraState createState() => _CameraState();
}
class _CameraState extends State<Camera> {
CameraController controller;
#override
void initState() {
super.initState();
controller = CameraController(cameras[0], ResolutionPreset.medium);
controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
}
#override
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return Container();
}
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
);
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
}
class Post extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Text("Post"),
);
}
}
Suppose the camera controller for an instance of the camera package is defined as such:
List<CameraDescription> cameras = [];
controller = CameraController(
cameras[0],
ResolutionPreset.high,
enableAudio: false,
);
This can be used to pause the camera:
controller.pausePreview();
This can be used to resume the camera:
controller.resumePreview();

FutureBuilder not working as intended in flutter

I am fetching json from here: https://api.myjson.com/bins/1g3xpe, in my flutter app.
Here is the code (I have removed unrelated part).The issue is, FutureBuilder's builder part is never getting called. This line debugPrint(snapshot.hasData.toString()); is never getting called.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:nirmithi/objects/project.dart';
import 'dart:convert';
class Projects extends StatefulWidget {
#override
ProjectsState createState() => new ProjectsState();
}
class ProjectsState extends State<Projects> {
#override
Widget build(BuildContext context) {
return Scaffold(
primary: true,
appBar: EmptyAppBar(),
body: Column(
children: <Widget>[
headerWidget(),
Container(
child: futureBuilder(),
)
],
),
);
}
#override
void setState(fn) {
super.setState(fn);
}
}
Future<List<Project>> getData() async {
String getProjects = "https://api.myjson.com/bins/1g3xpe";
final response = await http.get(getProjects);
if (response.statusCode == 200) {
List responseJson = json.decode(response.body);
return responseJson.map((m) => Project.fromJson(m)).toList();
} else
throw Exception(response.toString());
}
Widget futureBuilder() {
FutureBuilder<List<Project>>(
future: getData(),
builder: (context, snapshot) {
debugPrint(snapshot.hasData.toString());
},
);
return Center(
child: CircularProgressIndicator(),
);
}
Widget listWidget(List<Project> data) {
return ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
listItem(data.elementAt(index));
},
);
}
Widget listItem(Project project) {
return Card(
elevation: 6.0,
child: Column(
children: <Widget>[Text(project.projectId), Text(project.projectName)],
),
);
}
class EmptyAppBar extends StatelessWidget implements PreferredSizeWidget {
#override
Widget build(BuildContext context) {
return Container();
}
#override
Size get preferredSize => Size(0.0, 0.0);
}
UPDATE:
This is the code in builder part which I removed to debug.
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return new Text('loading...');
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return listWidget(snapshot.data);
}
You need to return your FutureBuilder so its part of the widget tree:
Widget futureBuilder() {
return FutureBuilder<List<Project>>(
future: getData(),
builder: (context, snapshot) {
// ...
},
);
}
Simply creating an instance of it wouldn't resolve the future.

Categories

Resources