I want to render all of the pdfs' first page as images and pass them to Home Screen. I make Splash Screen's duration to 30second. But I think it is not right because there can be hundreds of pdfs in someone's phone storage and Splash Screen's duration can be longer than 30seconds. So is there any solution to my problem? Here is my code. Enlighten me pls.
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:native_pdf_renderer/native_pdf_renderer.dart';
import 'package:splash_screen_view/SplashScreenView.dart';
import 'constant.dart';
import 'package:permission_handler/permission_handler.dart';
import 'home_screen.dart';
class Splashscreens extends StatefulWidget {
_SplashscreensState createState() => _SplashscreensState();
}
class _SplashscreensState extends State<Splashscreens> {
List<FileSystemEntity>? filepdf;
List<Uint8List>? imagepdf = [];
void initState() {
super.initState();
getFile();
}
getFile() async {
await Permission.storage.request();
final myDir = Directory('/storage/emulated/0/documents/');
filepdf = myDir.listSync(recursive: true, followLinks: true);
for (int index = 0; index < filepdf!.length; index++) {
final document = await PdfDocument.openFile(filepdf![index].path);
final page = await document.getPage(1);
final pageImage = await page.render(width: page.width, height: page.height);
setState(() {
imagepdf!.add(pageImage!.bytes);
});
}
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: SplashScreenView(
navigateRoute: HomeScreen(filepdf, imagepdf),
duration: 25000,
imageSize: 650,
imageSrc: "assets/image/jensenpdfviewerlogo.jpg",
colors: [
Colors.purple,
Colors.blue,
Colors.yellow,
Colors.red,
Colors.orange,
Color(0xFFECECEC)
],
pageRouteTransition: PageRouteTransition.SlideTransition,
text: "LOADING......",
textType: TextType.ColorizeAnimationText,
textStyle: fontStyle,
backgroundColor: Color(0xFF4E4AC2),
),
),
);
}
}
Here is my suggestion
class Splashscreens extends StatefulWidget {
_SplashscreensState createState() => _SplashscreensState();
}
class _SplashscreensState extends State<Splashscreens> {
List<FileSystemEntity>? filepdf;
List<Uint8List>? imagepdf = [];
Future<Map<String, dynamic>> getFile() async {
await Permission.storage.request();
final myDir = Directory('/storage/emulated/0/documents/');
filepdf = myDir.listSync(recursive: true, followLinks: true);
for (int index = 0; index < filepdf!.length; index++) {
final document = await PdfDocument.openFile(filepdf![index].path);
final page = await document.getPage(1);
final pageImage = await page.render(width: page.width, height: page.height);
setState(() {
imagepdf!.add(pageImage!.bytes);
});
}
var data = {
"file_pdf": filepdf,
"image_pdf": imagepdf
};
return data;
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getFile(),
builder: (BuildContext context, AsyncSnapshot<Map<String, dynamic>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.done:
Map<String, dynamic> data = snapshot.data!;
List<FileSystemEntity>? _filePdf = data["file_pdf"];
List<Uint8List>? _imagepdf = data["image_pdf"];
return YourResultScreen();
default:
return Container();
}
}
);
}
}
Related
I'm working with SfMaps syncfusion map and when I try to load geojson data from the local assets folder using the MapShapeSource.asset() property and everything works fine. But I'm having problems when I want to load geojson data as a result from api calling (GET / POST) using the http package flutter.
// Function to load data json from API
Future<void> loadGeojsonDataFromAPI() async {
setState(() => loading = true);
try {
final response = await http.post(
Uri.parse("some url"),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
body: body);
if (response.statusCode >= 400) {
throw Exception('statusCode=${response.statusCode}');
}
setState(() {
loading = false;
data = jsonDecode(response.body);
});
} catch (e) {
setState(() => loading = false);
debugPrint("Error load data: $e");
return;
}
}
// Loadjson data from API in Map Shape Source.network() but not sure how to do it
dataSource = MapShapeSource.network(
'url',
shapeDataField: 'name',
);
I believe this can be solved using MapShapeSource.network(), but am still confused about how to use it.
any kind of help is very much appreciated
You can load the area shape JSON data from the web/network using the MapShapeSource.network() constructor available in the maps widget. We have shared the user guide documentation and sample below for your reference.
UG, https://help.syncfusion.com/flutter/maps/getting-started#from-network
Code snippet:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Syncfusion Flutter Maps',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Syncfusion Flutter Maps'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late MapShapeSource _dataSource;
late List<IndiaMap> _mapDetails;
Future<bool> _fetchNetworkJsonDetails() async {
if (_mapDetails.isNotEmpty) {
return true;
}
final http.Response response = await http
.get(Uri.tryParse('https://api.npoint.io/b127f79b6e9c883d0aba')!);
if (response.statusCode == 200) {
Map<String, dynamic> responseJson = json.decode(response.body);
List<dynamic> countriesCoordinates = responseJson['features'];
for (int i = 0; i < countriesCoordinates.length; i++) {
Map<String, dynamic> data = countriesCoordinates[i]['properties'];
IndiaMap mapDetail = IndiaMap.fromJsonMap(data);
_mapDetails.add(mapDetail);
}
_dataSource = MapShapeSource.network(
'https://api.npoint.io/b127f79b6e9c883d0aba',
shapeDataField: 'name',
dataCount: _mapDetails.length,
primaryValueMapper: (index) => _mapDetails[index].state,
);
return true;
} else {
throw Exception('Failed to load JSON');
}
}
#override
void initState() {
_mapDetails = [];
super.initState();
}
#override
void dispose() {
_mapDetails.clear();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: FutureBuilder(
future: _fetchNetworkJsonDetails(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(15),
child: SfMaps(
layers: [
MapShapeLayer(
source: _dataSource,
color: const Color.fromRGBO(15, 59, 177, 0.5),
strokeColor: Colors.white,
strokeWidth: 0.5,
),
],
),
);
} else {
return const Center(child: CircularProgressIndicator());
}
}),
);
}
}
class IndiaMap {
late String state;
late String country;
IndiaMap(this.state, this.country);
IndiaMap.fromJsonMap(Map data) {
state = data['name'];
country = data['admin'];
}
}
I am trying to do a compound query. If this one works, then I want to display the results in a listView.builder.
The records are not displayed properly. I do not understand why. I must display the name field of each document find using the query. I have tried different options, but the result is also an error.
Thank you.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class LoadDataFromFirestore extends StatefulWidget {
const LoadDataFromFirestore({super.key});
#override
State<LoadDataFromFirestore> createState() => _LoadDataFromFirestoreState();
}
class _LoadDataFromFirestoreState extends State<LoadDataFromFirestore> {
QuerySnapshot? querySnapshot;
#override
void initState() {
super.initState();
myQuery().then((results) {
setState(() {
querySnapshot = results;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: _showDrivers(),
);
}
Widget _showDrivers() {
if (querySnapshot != null) {
return ListView.builder(
primary: false,
itemCount: querySnapshot?.docs.length,
padding: const EdgeInsets.all(12),
itemBuilder: (context, i) {
return Column(
children: <Widget>[
Text(querySnapshot!.docs[i].data().toString()),
],
);
},
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
}
Future myQuery () async{
final uid = FirebaseAuth.instance.currentUser!.uid;
final path = 'Users/$uid/allTasks';
final currentQuery = FirebaseFirestore.instance.collection(path);
Query statusQuery = currentQuery.where('status', isEqualTo: 'Next Action');
Query importantQuery = statusQuery.where('important', isEqualTo: 'False');
final snapshot = await importantQuery.get();
final data = snapshot.docs;
if(data.isNotEmpty){
for(var i =0; i < data.length; i++){
print(data[i].data());
return Text(data[i]['name']);
}
return data;
}
}
}
Since I can't test this, my guess is that the view is not refreshing properly since you used an function to get that widget.
Also you're returning an widget (Text) instead of the expected response that is of type QuerySnapshot.
Also you're returning data at the end which is a List and not the snapshot.
Go ahead and try this please:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class LoadDataFromFirestore extends StatefulWidget {
const LoadDataFromFirestore({super.key});
#override
State<LoadDataFromFirestore> createState() => _LoadDataFromFirestoreState();
}
class _LoadDataFromFirestoreState extends State<LoadDataFromFirestore> {
QuerySnapshot? querySnapshot;
#override
void initState() {
super.initState();
myQuery().then((results) {
setState(() {
querySnapshot = results;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: querySnapshot != null ? ListView.builder(
primary: false,
itemCount: querySnapshot?.docs.length,
padding: const EdgeInsets.all(12),
itemBuilder: (context, i) {
return ListTile(
title: Text(querySnapshot!.docs[i].data().toString()),
);
},
) : Center(
child: CircularProgressIndicator(),
)
);
}
Future myQuery () async{
final uid = FirebaseAuth.instance.currentUser!.uid;
final path = 'Users/$uid/allTasks';
final currentQuery = FirebaseFirestore.instance.collection(path);
Query statusQuery = currentQuery.where('status', isEqualTo: 'Next Action');
Query importantQuery = statusQuery.where('important', isEqualTo: 'False');
final snapshot = await importantQuery.get();
final data = snapshot.docs;
if(data.isNotEmpty){
//for(var i =0; i < data.length; i++){
// print(data[i].data());
// return Text(data[i]['name']);
//}
return snapshot;
}
}
}
how can I add refresh to listview.builder in flutter?
This is my all code from posts screen when I delete post or add new post not realtime just after hot restart it worked I want to add refresh to listview I called getPosts method in refreshIndecator but not worked please any one can help me? Thanks.
Code :
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:data_connection_checker/data_connection_checker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:social_media_app/models/post.dart';
import 'package:social_media_app/posts/create_post.dart';
import 'package:social_media_app/utils/firebase.dart';
import 'package:social_media_app/widgets/indicators.dart';
import 'package:social_media_app/widgets/posts_view.dart';
class Timeline extends StatefulWidget {
#override
_TimelineState createState() => _TimelineState();
}
class _TimelineState extends State<Timeline> {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
List<DocumentSnapshot> post = [];
bool isLoading = false;
DocumentSnapshot lastDocument;
ScrollController _scrollController;
getPosts() async {
if (isLoading) {
return CircularProgressIndicator();
}
if (mounted)
setState(() {
isLoading = true;
});
QuerySnapshot querySnapshot;
if (lastDocument == null) {
querySnapshot =
await postRef.orderBy('timestamp', descending: true).get();
} else {
querySnapshot = await postRef
.orderBy('timestamp', descending: true)
.startAfterDocument(lastDocument)
.get();
}
lastDocument = querySnapshot.docs[querySnapshot.docs.length - 1];
post.addAll(querySnapshot.docs);
if (mounted)
setState(() {
isLoading = false;
});
}
#override
void initState() {
super.initState();
getPosts();
_scrollController?.addListener(() {
double maxScroll = _scrollController.position.maxScrollExtent;
double currentScroll = _scrollController.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.25;
if (maxScroll - currentScroll <= delta) {
getPosts();
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(
'Admin App',
style: TextStyle(fontWeight: FontWeight.w900),
),
leading: IconButton(
onPressed: () => Navigator.push(
context, MaterialPageRoute(builder: (_) => CreatePost())),
icon: Icon(Feather.plus)),
centerTitle: true,
),
body: isLoading
? circularProgress(context)
: ListView.builder(
controller: _scrollController,
itemCount: post.length,
itemBuilder: (context, index) {
internetChecker(context);
PostModel posts = PostModel.fromJson(post[index].data());
return Padding(
padding: const EdgeInsets.all(10.0),
child: Posts(post: posts),
);
},
),
);
}
internetChecker(context) async {
bool result = await DataConnectionChecker().hasConnection;
if (result == false) {
showInSnackBar('No Internet Connection', context);
}
}
void showInSnackBar(String value, context) {
ScaffoldMessenger.of(context).removeCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(value)));
}
}
Why don't you try using a Refresh Indicator Widget for this purpose. Check sample usage in the Flutter official documentation
I'm getting this error:
NosuchmethodError: Class 'List' has no instance setter 'state='.
Recevier: Instance(length:0) of ' _GrowableList' Tried calling: state=Instance(lenght:15) of'_GrowableList'
and I don't know where is the problem I can't see any problem in the code.
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:quiz2/const/const.dart';
import 'package:sqflite/sqflite.dart';
class Category {
int ID;
String name, image;
Map<String, dynamic> toMap() {
var map = <String, dynamic> {
columnMainCategoryId: ID,
columnCategoryName: name,
columnCategoryImage: image
};
return map;
}
Category();
Category.fromMap(Map<String,dynamic> map) {
ID = map[columnMainCategoryId];
name = map[columnCategoryName];
image = map[columnCategoryImage];
}
}
class CategoryProvider {
Future<Category> getCategoryById(Database db, int id)async {
var maps = await db.query(tableCategoryName,
columns: [
columnMainCategoryId,
columnCategoryName,
columnCategoryImage
], where: "$columnMainCategoryId=?",
whereArgs: [id]);
if(maps.length > 0)
return Category.fromMap(maps.first);
return null;
}
Future<List<Category>> getCategories(Database db) async{
var maps = await db.query(tableCategoryName,
columns: [
columnMainCategoryId,
columnCategoryName,
columnCategoryImage
]);
if(maps.length > 0) return maps.map((category) => Category.fromMap(category)).toList();
return null;
}
}
class CategoryList extends StateNotifier<List<Category>>{
CategoryList(List<Category> state):super(state ?? []);
void addAll(List<Category> category)
{
state.addAll(category);
}
void add(Category category){
state = [
...state,
category,
];
}
}
file const.dart
final db_name = "quiz.db";
final columnMainCategoryId = "ID";
final columnCategoryName = "Name";
final columnCategoryImage = "Image";
final tableCategoryName = "Category";
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:quiz2/screens/home_page.dart';
void main() {
runApp(ProviderScope(child:MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
routes: {
"/homePage": (context) => MyCategoryPage(title: "My Quiz",)
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Topics'),
);
}
}
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
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pop();
Navigator.pushNamed(context, "/homePage");
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
// This trailing comma makes auto-formatting nicer for build methods.
);
}
}
screens/home_page.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:quiz2/const/state.dart';
import 'package:quiz2/database/category_provider.dart';
import 'package:quiz2/database/db_helper.dart';
class MyCategoryPage extends StatefulWidget {
MyCategoryPage({Key key, this.title}):super(key: key);
final String title;
#override
_MyCategoryPageState createState() => _MyCategoryPageState();
}
class _MyCategoryPageState extends State<MyCategoryPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Category>>(
future: getCategories(),
builder: (context, snapshot){
if(snapshot.hasError)
return Center(child: Text('${snapshot.error}'),);
else if(snapshot.hasData)
{
Category category = new Category();
category.ID = -1;
category.name = "Exam";
snapshot.data.add(category);
return GridView.count(
crossAxisCount: 2,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: snapshot.data.map((category){
return GestureDetector(child: Card(
elevation: 2,
color: category.ID == -1 ? Colors.green : Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: AutoSizeText(
"${category.name}",
style: TextStyle(
color: category.ID == -1 ? Colors.white : Colors.black,
fontWeight: FontWeight.bold
),
maxLines: 1,
textAlign: TextAlign.center,
)
,)
],
),
),);
}).toList(),
);
}
else return Center(child: CircularProgressIndicator(),);
},
)
);
}
Future<List<Category>> getCategories() async {
var db = await copyDB();
var result = await CategoryProvider().getCategories(db);
context.read(categoryListProvider).state = result;
return result;
}
}
db_helper.dart
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:quiz2/const/const.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
Future<Database> copyDB() async{
var dbPath = await getDatabasesPath();
var path = join(dbPath, db_name);
var exists = await databaseExists(path);
if(!exists){
try{
await Directory(dirname(path)).create(recursive:true);
} catch(_){
}
ByteData data = await rootBundle.load(join("assets/db",db_name));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes,data.lengthInBytes);
await File(path).writeAsBytes(bytes, flush:true);
}else{
print("DB already exists!");
}
return await openDatabase(path, readOnly: true);
}
state.dart
import 'package:flutter_riverpod/all.dart';
import 'package:quiz2/database/category_provider.dart';
final categoryListProvider = StateNotifierProvider((ref) => new CategoryList([]));
NosuchmethodError: Class 'List' has no instance setter 'state='.
Recevier: Instance(length:0) of ' _GrowableList'
Tried calling: state=Instance(lenght:15) of'_GrowableList'
In your code, you have
Future<List<Category>> getCategories() async {
var db = await copyDB();
var result = await CategoryProvider().getCategories(db);
context.read(categoryListProvider).state = result;
return result;
}
Here, your context.read(categoryListProvider) is actually of type List.
That's why, when you are calling it like that, it means that you are calling,
[/* some kind of list */].state = result
But, the List class doesn't have a property called state but you are trying to modify it. That's why the error is coming.
Comment out that line and check.
I have code that I use to write data to a file (such as global settings for an application). I write down the data and see. But the problem is that I do not understand how to take these mini data from another page. For example I wrote the word "Test" and I want and I want to assign that word to some variable in another page. I will be grateful for your help. Here is my code:
import 'dart:io';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Reading and Writing to Storage",
home: Home(
storage: Storage(),
),
);
}
}
class Home extends StatefulWidget {
final Storage storage;
Home({Key key, #required this.storage}) : super(key: key);
#override
HomeState createState() => HomeState();
}
class HomeState extends State<Home> {
TextEditingController controller = TextEditingController();
String state;
Future<Directory> _appDocDir;
#override
void initState() {
super.initState();
widget.storage.readData().then((String value) {
setState(() {
state = value;
});
});
}
Future<File> writeData() async {
setState(() {
state = controller.text;
controller.text = '';
});
return widget.storage.writeData(state);
}
void getAppDirectory() {
setState(() {
_appDocDir = getApplicationDocumentsDirectory();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Reading and Writing Files'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('${state ?? "File is Empty"}'),
TextField(
controller: controller,
),
RaisedButton(
onPressed: writeData,
child: Text('Write to File'),
),
RaisedButton(
child: Text("Get DIR path"),
onPressed: getAppDirectory,
),
FutureBuilder<Directory>(
future: _appDocDir,
builder:
(BuildContext context, AsyncSnapshot<Directory> snapshot) {
Text text = Text('');
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
text = Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
text = Text('Path: ${snapshot.data.path}');
} else {
text = Text('Unavailable');
}
}
return new Container(
child: text,
);
},
)
],
),
),
);
}
}
class Storage {
Future<String> get localPath async {
final dir = await getApplicationDocumentsDirectory();
return dir.path;
}
Future<File> get localFile async {
final path = await localPath;
return File('$path/db.txt');
}
Future<String> readData() async {
try {
final file = await localFile;
String body = await file.readAsString();
return body;
} catch (e) {
return e.toString();
}
}
Future<File> writeData(String data) async {
final file = await localFile;
return file.writeAsString("$data");
}
}
And scrin:
You can pass the value to other page using Navigator and parameter.
class NewScreen extends StatelessWidget {
final String data;
NewScreen({this.data});
...
}
When you move to 'NewScreen' by using Navigator at your 'Home' page,
pass the data what you transfer.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NewScreen(data: 'Test'),
),
);