RangeError (start): Invalid value: Only valid value is 0: -16 - FLUTTER - flutter

I am trying to encrypt a password locally, it is created or changed when the user wishes.
But when I try to change it from the user interface I get this error:
Unhandled Exception: RangeError (start): Invalid value: Only valid value is 0: -16.
although the app still works.
This is the class code:
class SettingsPage extends StatefulWidget {
#override
_State createState() => _State();
static String routeName = '/settings';
static bool switched = false;
static String inputPassword = '0000';
}
class _State extends State<SettingsPage> {
static final key = encrypt.Key.fromLength(32);
static final iv = encrypt.IV.fromLength(1);
static final encrypter = encrypt.Encrypter(encrypt.AES(key));
static encryptAES(text) {
final encrypted = encrypter.encrypt(text, iv: iv);
print(encrypted.bytes);
print(encrypted.base16);
print(encrypted.base64);
return encrypted;
}
static decryptAES(text) {
return encrypter.decrypt(text, iv: iv);
}
TextEditingController tec = TextEditingController();
var encryptedText, plainText;
Future<void> localAuth(BuildContext context) async {
final localAuth = LocalAuthentication();
final didAuthenticate = await localAuth.authenticateWithBiometrics(
localizedReason: 'Please authenticate');
if (didAuthenticate) {
Navigator.pop(context);
}
}
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
late SharedPreferences prefs;
getSwitchValues() async {
SettingsPage.switched = await getSwitchState();
setState(() {});
}
getPassValues() async{
prefs = await _prefs;
setState(() {
prefs.containsKey('savedPass')? prefs.getString('savedPass'): "";
setState(() {
});
});
}
#override
void initState() {
super.initState();
getSwitchValues();
getPassValues();
}
Future<bool> getSwitchState() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
SettingsPage.switched = prefs.getBool("switched")!;
print(SettingsPage.switched);
return SettingsPage.switched;
}
Future<bool> saveSwitchState(bool value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool("switched", value);
print('Switch Value saved $value');
return prefs.setBool("switched", value);
}
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(paddingSizeLarge),
child:
Column(
children: [
Text('SETTINGS',
style: GoogleFonts.encodeSansSemiCondensed(fontSize: 35.0, fontWeight: FontWeight.w700,color: Palette.secondaryTextColor),
textAlign: TextAlign.center,
),
VerticalSpacing(of: marginSizeDefault),
Container(
child:
ListView(
shrinkWrap: true,
padding: EdgeInsets.all(paddingSizeDefault),
children: [
Row(
children:[
Text('Activate Biometrics : ',
style: GoogleFonts.encodeSansSemiCondensed(fontSize: 20.0, fontWeight: FontWeight.w700,color: Palette.textColor),),
HorizontalSpacing(of: marginSizeXXLarge),
Switch(
value: SettingsPage.switched,
onChanged: (value) {
setState(() {
SettingsPage.switched = value;
saveSwitchState(SettingsPage.switched);
});
screenLock(context: context, correctString: '1234',
canCancel: true,
customizedButtonTap: () async {
await localAuth(context);
},
didOpened: () async {
await localAuth(context);
},);
},
activeTrackColor: Colors.blue,
activeColor: Colors.blue,
),
]),
VerticalSpacing(of: marginSizeLarge),
/* Row(
children:[
Text('Biometrics Settings : ',
style: GoogleFonts.encodeSansSemiCondensed(fontSize: 20.0, fontWeight: FontWeight.w700,color: Palette.textColor),),
HorizontalSpacing(of: marginSizeXXLarge),
IconButton(onPressed: (){ print('bio set');} , icon: const Icon(FeatherIcons.arrowRight, color: Colors.black,))
]),
VerticalSpacing(of: marginSizeLarge),*/
Row(
children:[
Text('Create/Change Password : ',
style: GoogleFonts.encodeSansSemiCondensed(fontSize: 20.0, fontWeight: FontWeight.w700,color: Palette.textColor),),
IconButton( icon: const Icon(FeatherIcons.arrowRight, color: Colors.black,),
onPressed: () async {
final result = await
showOkCancelAlertDialog(
context: context,
title: 'Change or Create a new Password',
message:
'This will remove your existing Password or create a new one',
);
if (result == OkCancelResult.ok) {
final input = (await showTextInputDialog(
textFields: [DialogTextField(keyboardType: TextInputType.numberWithOptions(decimal: true),
),
],
context: context,
title: 'Change or Create a new Password',
message: 'enter your new password',
))!.join();
if (input != null && input.length > 0 && input.length == 4 ) {
context.read<SettingsBloc>().changePassword(input);
SettingsPage.inputPassword = input;
SettingsPage.inputPassword = tec.text;
setState(() {
encryptedText = encryptAES(SettingsPage.inputPassword);
print("PROVA ENCRYPTED TEXT "+encryptedText);
});
prefs.setString('savedPass', encryptedText);
encryptedText = decryptAES(encryptedText);
print("PROVA TESTO DECRIPTATO " + encryptedText);
}
}
},
),
]),
VerticalSpacing(of: 50),
RoundedButton(text:'Log Out',),
],
),
decoration: new BoxDecoration(
color: Palette.primaryLightColor,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(color: Palette.backgroundColor,
),
],
),
),
]
),
);
}
}
both texts are not written to the prompt with the print function. there must be some problem within the conditions and in addition the error I get when changing the password, please if anyone knows how to help me come forward thanks.

Related

How to make search FLUTTER JSON

I'm a new Flutter user, here I'm having a problem, I'm confused about how to make a search that reads from JSON, here I've created a search menu but I don't understand how to connect to the database. Can you help me to modify my source code so I can do a search. Hopefully good friends can help me make a search function. Thank you friend
datanasabah.dart
GlobalKey<ScaffoldState> _scaffoldState = GlobalKey<ScaffoldState>();
class DataNasabah extends StatefulWidget {
DataNasabah({Key key}) : super(key: key);
final String title = "Data Nasabah";
#override
_DataNasabahState createState() => _DataNasabahState();
}
class _DataNasabahState extends State<DataNasabah> {
ApiService apiService;
ListNasabah _listNasabah;
bool _isLoading = true;
List<Nasabah> data;
final _textHeadStyle =
TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold);
void fetchData() async {
final res = await apiService.getNasabah();
data = res;
setState(() {
_isLoading = false;
});
}
#override
void initState() {
super.initState();
apiService = ApiService();
_listNasabah = new ListNasabah(apiService: apiService);
fetchData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldState,
appBar: AppBar(
title: Text(
'Data Nasabah',
style: TextStyle(color: Colors.white),
),
actions: <Widget>[
MaterialButton(
elevation: 5,
child: Text("CARI", style: _textHeadStyle),
onPressed: () async {
var value = await showTopModalSheet<String>(
context: context, child: DumyModal());
},
),
],
),
body: _listNasabah.createViewList(),
);
}
}
class DumyModal extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
height: MediaQuery.of(context).size.height * .2,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextField(
decoration: InputDecoration(
labelText: "NIK Nasabah", //babel text
hintText: "Masukkan NIK Nasabah", //hint text
prefixIcon: Icon(Icons.people), //prefix iocn
hintStyle: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, ), //hint text style
labelStyle: TextStyle(fontSize: 17, color: Colors.black), //label style
)
),
MaterialButton(
color: Colors.orange,
child: const Text("Cari", style: TextStyle(color: Colors.white),),
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
},
)
],
),
);
}
}
nasabah_service.dart
class ApiService {
final String baseUrl = '192.168.100.207:8080';
Client client = Client();
Future<List<Nasabah>> getNasabah() async {
final response = await client.get('http://$baseUrl/api/mstdebitur');
print(response.body);
if (response.statusCode == 200) {
final nasabah = (json.decode(response.body) as List)
.map((e) => Nasabah.fromMap(e))
.toList();
return nasabah;
} else {
throw Exception('Failed to load post');
}
}
Future<bool> createNasabah(Nasabah data) async {
String url = new Uri.http("$baseUrl", "/api/mstdebitur/").toString();
final response = await client.post(url,
headers: {"Content-Type": "application/json"},
body: nasabahToJson(data));
if (response.statusCode == 201) {
return true;
} else {
return false;
}
}
Future<bool> updateNasabah(Nasabah data) async {
String url =
new Uri.http("$baseUrl", "/api/mstdebitur/${data.id}").toString();
final response = await client.put(url,
headers: {"Content-Type": "application/json"},
body: nasabahToJson(data));
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
Future<bool> deleteNasabah(int id) async {
String url = new Uri.http("$baseUrl", "/api/mstdebitur/$id").toString();
final response = await client.delete(url);
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
}

Why flutter pdf setPage is not working if set the value return from AlertDialog in android only?

My code is view the pdf using by flutter_pdfview from online url. Opening the pdf is no issue. So I wrote the pagination at floatingActionButton. There is "Previous", "Page / Total Page" and "Next". If click page button, Alert Dialog box pop up and user can enter the page and can go to specified page. It is working on iOS. But at Android, after enter the page number on Dialog and click "Move" button and then dialog return the entered value and set the page number at
await snapshot.data!.setPage(pageNumber - 1);
But it is not call the PDFView's onPageChanged. If I don't call the dialog and just simply call snapshot.data!.setPage(pageNumber - 1), it is working.
I think something wrong with dialog.
May I know why it is only happening on android and only happening if set the page number return from dialog?
First Pdf page
Dialog to enter page number
Full source code
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:thitsarparami/helper/enum.dart';
import 'package:thitsarparami/widgets/circular_progress_indicator_widget.dart';
class PdfView extends StatefulWidget {
final String url;
final LoadPDF loadPDF;
final String title;
const PdfView(
{Key? key, required this.title, required this.url, required this.loadPDF})
: super(key: key);
#override
State<PdfView> createState() => _PdfViewerState();
}
class _PdfViewerState extends State<PdfView> with WidgetsBindingObserver {
String? path;
bool _isLoading = true;
TextEditingController? textController;
final Completer<PDFViewController> _controller =
Completer<PDFViewController>();
int? pages = 0;
int? currentPage = 0;
bool isReady = false;
String errorMessage = '';
bool isButtonActive = false;
loadDocument() async {
String fileName = widget.url.split("/").last;
switch (widget.loadPDF) {
case LoadPDF.assets:
fromAsset(widget.url, fileName).then((f) {
setState(() {
path = f.path;
_isLoading = false;
});
});
break;
case LoadPDF.url:
createFileOfPdfUrl().then((f) {
setState(() {
path = f.path;
_isLoading = false;
});
});
break;
case LoadPDF.file:
File file = File(widget.url);
setState(() {
path = file.path;
_isLoading = false;
});
break;
}
}
Future<File> createFileOfPdfUrl() async {
Completer<File> completer = Completer();
//print("Start download file from internet!");
try {
final url = widget.url;
final filename = url.substring(url.lastIndexOf("/") + 1);
var request = await HttpClient().getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
var dir = await getApplicationDocumentsDirectory();
//print("Download files");
//print("${dir.path}/$filename");
File file = File("${dir.path}/$filename");
await file.writeAsBytes(bytes, flush: true);
completer.complete(file);
} catch (e) {
throw Exception('Error parsing asset file!');
}
return completer.future;
}
Future<File> fromAsset(String asset, String filename) async {
// To open from assets, you can copy them to the app storage folder, and the access them "locally"
Completer<File> completer = Completer();
try {
var dir = await getApplicationDocumentsDirectory();
File file = File("${dir.path}/$filename");
var data = await rootBundle.load(asset);
var bytes = data.buffer.asUint8List();
await file.writeAsBytes(bytes, flush: true);
completer.complete(file);
} catch (e) {
throw Exception('Error parsing asset file!');
}
return completer.future;
}
#override
void initState() {
super.initState();
loadDocument();
textController = TextEditingController();
}
#override
void dispose() {
textController?.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
appBar: AppBar(
centerTitle: true,
backgroundColor: Theme.of(context).backgroundColor,
elevation: 0,
title: AutoSizeText(
widget.title,
style: Theme.of(context).appBarTheme.titleTextStyle,
),
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(
Icons.arrow_back,
color: Theme.of(context).primaryIconTheme.color!,
),
),
),
body: Center(
child: _isLoading
? const CircularProgressIndicatorWidget()
: PDFView(
filePath: path,
enableSwipe: true,
swipeHorizontal: false,
autoSpacing: false,
pageFling: true,
pageSnap: true,
defaultPage: currentPage!,
fitPolicy: FitPolicy.BOTH,
preventLinkNavigation:
false, // if set to true the link is handled in flutter
onRender: (_pages) {
setState(() {
pages = _pages;
isReady = true;
});
},
onError: (error) {
setState(() {
errorMessage = error.toString();
});
//print(error.toString());
},
onPageError: (page, error) {
setState(() {
errorMessage = '$page: ${error.toString()}';
});
//print('$page: ${error.toString()}');
},
onViewCreated: (PDFViewController pdfViewController) {
_controller.complete(pdfViewController);
},
onLinkHandler: (String? uri) {
//print('goto uri: $uri');
},
onPageChanged: (int? page, int? total) {
//print('page change: $page/$total');
setState(
() {
currentPage = page;
},
);
},
),
),
floatingActionButton: FutureBuilder<PDFViewController>(
future: _controller.future,
builder: (context, AsyncSnapshot<PDFViewController> snapshot) {
if (snapshot.hasData) {
return FloatingActionButton.extended(
label: Row(
children: [
IconButton(
icon: Icon(Icons.navigate_before,
color: (currentPage! > 0) ? Colors.white : Colors.grey),
onPressed: (currentPage! < pages!)
? () async {
await snapshot.data!.setPage(currentPage! - 1);
}
: null,
),
ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
side: const BorderSide(
color: Colors.white,
),
minimumSize: Size.zero,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
onPressed: () async {
final result = await openDialog();
if (result == null || result.isEmpty) return;
int pageNumber = int.parse(result);
await snapshot.data!.setPage(pageNumber - 1);
},
child: Text("${currentPage! + 1}"),
),
Text(" / $pages"),
IconButton(
icon: Icon(Icons.navigate_next,
color: (currentPage! + 1 < pages!)
? Colors.white
: Colors.grey),
onPressed: (currentPage! < pages!)
? () async {
await snapshot.data!.setPage(currentPage! + 1);
}
: null,
),
],
),
onPressed: null,
);
}
return Container();
},
),
);
}
Future<String?> openDialog() => showDialog<String>(
context: context,
builder: (context) => StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: const Text('Go to page'),
content: TextField(
autofocus: true,
decoration: const InputDecoration(hintText: 'Page number'),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
controller: textController,
onChanged: (value) {
if (value.isNotEmpty) {
int pageNumber = int.parse(value);
setState(() {
isButtonActive = pageNumber < pages!;
});
}
},
onSubmitted: (_) => gotToPage(),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
textController?.clear();
},
child: const Text('Cancel'),
),
TextButton(
style: TextButton.styleFrom(
onSurface: Theme.of(context).primaryColor),
onPressed: isButtonActive
? () {
gotToPage();
textController?.clear();
}
: null,
child: const Text('Move'),
),
],
);
},
),
);
void gotToPage() {
Navigator.of(context).pop(textController?.text);
}
}
I am not sure why this error occurred in android. It is happening because opening the keyboard. So Now I am using number picker and it is working now.

having trouble with Flutter null safety, database object refuses to initialize

I have been trying to implement a simple To Do app without providers (for the course's sake) to advance in the course at the pace the instructor intended. But I cannot seem to find a solution for this small problem..
in the below code, the variable database does not want to be initialized whatsoever. The getData() method that's supposed to retrieve data (query) doesn't initialize the variable database even if I call it in createDatabase() in initState() It keeps giving the following errors:
''' I/flutter ( 5171): error LateInitializationError: Field 'database' has not been initialized. during open, closing...
E/flutter ( 5171): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: LateInitializationError: Field 'database' has not been initialized.
'''
import 'package:intl/intl.dart';
import 'package:sqflite/sqflite.dart';
import 'package:to_do_app/modules/todo_app/archived/archived_screen.dart';
import 'package:to_do_app/modules/todo_app/done/done_screen.dart';
import 'package:to_do_app/modules/todo_app/tasks/tasks_screen.dart';
class HomeLayout extends StatefulWidget {
const HomeLayout({ Key? key }) : super(key: key);
#override
State<HomeLayout> createState() => _HomeLayoutState();
}
class _HomeLayoutState extends State<HomeLayout> {
int currentIndex = 0;
List<String> titles = [
'Tasks',
'Done Tasks',
'Archived Tasks',
];
List<Map> tasks = [];
late Database database;
var scaffoldKey = GlobalKey<ScaffoldState>();
bool isOpen = false;
IconData fabIcon = Icons.edit;
var titleController = TextEditingController();
var dateController = TextEditingController();
var timeController = TextEditingController();
var formKey = GlobalKey<FormState>();
#override
void initState() {
super.initState();
createDatabase();
}
#override
Widget build(BuildContext context) {
List <Widget> screens = [
NewTasksScreen(),
DoneTasksScreen(),
ArchivedTasksScreen()
];
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: Text(titles[currentIndex]),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if(isOpen == false){
isOpen = true;
setState(() {
fabIcon = Icons.add;
});
scaffoldKey.currentState!.showBottomSheet(
(context) => SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20),
child: Form(
key: formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
validator: (value){
if(value!.isEmpty){
return 'title must not be empty';
}
},
controller: titleController,
decoration: InputDecoration(
labelText: 'Title',
prefixIcon: Icon(
Icons.title
),
),
),
SizedBox(height: 10),
TextFormField(
onTap: (){
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime.now(),
lastDate: DateTime(2025)
).then((value) {
dateController.text = DateFormat.yMMMMd().format(value!);
});
},
validator: (value){
if(value!.isEmpty){
return 'date must not be empty';
}
},
controller: dateController,
decoration: InputDecoration(
labelText: 'Date',
prefixIcon: Icon(
Icons.date_range
),
),
),
SizedBox(height: 10),
TextFormField(
onTap: (){
showTimePicker(
context: context,
initialTime: TimeOfDay.now()
).then((value) {
timeController.text = value!.format(context);
});
},
validator: (value){
if(value!.isEmpty){
return 'time must not be empty';
}
},
controller: timeController,
decoration: InputDecoration(
labelText: 'Time',
prefixIcon: Icon(
Icons.timer
),
),
),
],
),
),
),
),
).closed.then(
(value) {
isOpen = false;
}
);
} else {
if (formKey.currentState!.validate()) {
insertIntoDatabase(
title: titleController.text,
date: dateController.text,
time: timeController.text
).then((value) {
Navigator.pop(context);
isOpen = false;
setState(() {
fabIcon = Icons.edit;
});
});
}
}
},
child: Icon(
fabIcon
),
),
bottomNavigationBar: BottomNavigationBar(
elevation: 20,
type: BottomNavigationBarType.fixed,
currentIndex: currentIndex,
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.task_alt
),
label: 'new tasks'
),
BottomNavigationBarItem(
icon: Icon(
Icons.done
),
label: 'done tasks'
),
BottomNavigationBarItem(
icon: Icon(
Icons.archive_outlined
),
label: 'archived tasks'
)
],
onTap: (index){
setState(() {
currentIndex = index;
});
},
),
body: screens[currentIndex],
);
}
Future getName() async {
return 'Ahmad Ali';
}
void createDatabase() async {
database = await openDatabase(
'todo.db',
version: 1,
onCreate: (database, version) {
print('databse created');
database.execute(
'CREATE TABLE tasks(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, date TEXT, time TEXT, status TEXT)'
).then(
(value) {
print('table created');
}
).catchError(
(error){
print('error creating table ${error.toString()}');
}
);
},
onOpen: (databse) async {
print('database opened');
await getData(database).then((value) {
tasks = value;
print(tasks);
});
}
);
}
Future insertIntoDatabase({
required String title,
required String date,
required String time
}
) async {
return await database.transaction(
(txn) {
return txn.rawInsert(
'INSERT INTO tasks (title, date, time, status) VALUES ("$title", "$date", "$timeController", "new")'
).then(
(value) {
print('$value inserted succsessfully');
}
).catchError(
(error){
print('error inserting into table ${error.toString()}');
}
);
}
);
}
Future<List<Map>> getData(Database database) async {
return await database.rawQuery('SELECT * FROM tasks');
}
} ```
Try to initialize
late Database database;
in the StatefulWidget instead of it's State and in the createDatabase() call it like
widget.database = await OpenDatabase...
Also try to see if adding await in initState helps.
instead of
late Database database;
Write
static Database? database;

The getter 'name' was called on null

I'm trying to make an app that has basically the same mechanics as a simple todo-app. My problem is, when I try to open the screen where I can create a new project/todo(new_project_screen), there should be loaded some TextFields, but they don't. Instead, this error occurs. I tried several solutions from stackoverflow, but nothing worked and I have no idea why it's not working.(sorry for my bad english, I'm not a native xD)
Here is my code:
main.dart:
import 'package:flutter/material.dart';
import 'package:leisy/surface/main_screen.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(App());
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Leisy',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainScreen(),
);
}
}
main_screen.dart:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:sqflite/sqflite.dart';
import 'package:leisy/db/database_helper.dart';
import 'package:leisy/model/project.dart';
import 'package:leisy/surface/settings_screen.dart';
import 'package:leisy/surface/new_project_screen.dart';
class MainScreen extends StatefulWidget {
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
DatabaseHelper databaseHelper = DatabaseHelper();
List<Project> projectList = [];
int count = 0;
#override
Widget build(BuildContext context) {
if (projectList == null) {
projectList = <Project>[];
updateListView();
}
debugPrint("Building entire main screen scaffold");
return Scaffold(
appBar: AppBar(
title: Text("Leisy"),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Center(
child: Text(
"Menü",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 25,
),
),
),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () => {Navigator.of(context).pop()},
),
ListTile(
leading: Icon(Icons.add),
title: Text('Neues Projekt'),
onTap: () => {
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => new NewProjectScreen()))
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Einstellungen'),
onTap: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SettingsScreen()))
},
)
],
),
),
body: getProjectListView(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: navigateToNewProject,
),
);
}
ListView getProjectListView() {
TextStyle titleStyle = Theme.of(context).textTheme.subtitle1;
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.blue,
),
title: Text(
this.projectList[position].name,
style: titleStyle,
),
subtitle: Text(this.projectList[position].date),
onTap: () {
debugPrint('ListTile Tapped');
//navigateToDetail() einfügen
},
),
);
});
}
void _showSnackBar(BuildContext context, String message) {
final snackBar = SnackBar(
content: Text(message),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
void navigateToNewProject() async {
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) => NewProjectScreen()));
if (result == true) {
updateListView();
}
}
void updateListView() {
final Future<Database> dbFuture = databaseHelper.initDB();
dbFuture.then((database) {
Future<List<Project>> projectListFuture = databaseHelper.getProjectList();
projectListFuture.then((projectList) {
setState(() {
this.projectList = projectList;
this.count = projectList.length;
});
});
});
}
}
new_project_screen.dart:
import 'package:flutter/material.dart';
import 'package:leisy/db/database_helper.dart';
import 'package:leisy/model/project.dart';
import 'package:leisy/surface/main_screen.dart';
import 'package:leisy/surface/settings_screen.dart';
class NewProjectScreen extends StatefulWidget {
#override
_NewProjectScreenState createState() => _NewProjectScreenState();
}
class _NewProjectScreenState extends State<NewProjectScreen> {
Project project;
DatabaseHelper helper = DatabaseHelper();
TextEditingController nameController = TextEditingController();
TextEditingController dateController = TextEditingController();
TextEditingController locationController = TextEditingController();
#override
Widget build(BuildContext context) {
nameController.text = project.name;
dateController.text = project.date;
locationController.text = project.location;
return Scaffold(
appBar: AppBar(
title: Text("Neues Projekt"),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Center(
child: Text(
"Menü",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 25,
),
),
),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => MainScreen()))
},
),
ListTile(
leading: Icon(Icons.add),
title: Text('Neues Projekt'),
onTap: () => {Navigator.of(context).pop()},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Einstellungen'),
onTap: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SettingsScreen()))
},
)
],
),
),
body: Padding(
padding: EdgeInsets.all(8.0),
child: ListView(
children: <Widget>[
TextField(
controller: nameController,
decoration: InputDecoration(labelText: 'Name'),
style: TextStyle(fontSize: 20),
onChanged: (value) {
setState(() {
updateName();
});
},
),
TextField(
decoration: InputDecoration(labelText: 'Datum'),
style: TextStyle(fontSize: 20),
onChanged: (value) {
setState(() {
updateDate();
});
},
),
TextField(
decoration: InputDecoration(labelText: 'Ort'),
style: TextStyle(fontSize: 20),
onChanged: (value) {
setState(() {
updateLocation();
});
},
),
Row(
children: <Widget>[
Expanded(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Theme.of(context).primaryColorDark),
),
child: Text('Speichern'),
onPressed: () {
setState(() {
_save();
});
},
)),
Expanded(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Theme.of(context).primaryColorDark),
),
child: Text('Abbrechen'),
onPressed: () {
setState(() {
_cancel();
});
},
)),
],
)
],
)
)
);
}
void _save() async {
Navigator.pop(context, true);
await helper.insertProject(project);
}
void _showSnackBar(String message) {
SnackBar snackBar = SnackBar(content: Text(message));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
void _cancel() async {
Navigator.pop(context, true);
_showSnackBar('Vorgang abgebrochen');
}
void updateName() {
project.name = nameController.text;
}
void updateDate() {
project.date = dateController.text;
}
void updateLocation() {
project.location = locationController.text;
}
}
project.dart:
class Project {
int _id;
String _name;
String _date;
String _location;
String _personaldb;
Project(this._name, this._date, this._location, this._personaldb);
Project.withId(
this._id, this._name, this._date, this._location, this._personaldb);
int get id => _id;
String get name => _name;
String get date => _date;
String get location => _location;
String get personalDB => _personaldb;
set name(String newName) {
if (newName.length <= 63) {
this._name = newName;
}
}
set date(String newDate) {
this._date = newDate;
}
set location(String newLocation) {
this._location = newLocation;
}
set personalDB(String newPersonalDB) {
this._personaldb = newPersonalDB;
}
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
if (id != null) {
map['id'] = _id;
}
map['name'] = _name;
map['date'] = _date;
map['location'] = _location;
map['personalDB'] = _personaldb;
return map;
}
Project.fromMapObject(Map<String, dynamic> map) {
this._id = map['id'];
this._name = map['name'];
this._date = map['date'];
this._location = map['location'];
this._personaldb = map['personalDB'];
}
}
database_helper.dart:
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:leisy/model/project.dart';
class DatabaseHelper {
static DatabaseHelper _databaseHelper;
static Database _database;
String projectTable = 'project_table';
String colId = 'id';
String colName = 'name';
String colDate = 'date';
String colLocation = 'location';
String colPersonalDB = 'personalDB';
DatabaseHelper._createInstance();
factory DatabaseHelper() {
if (_databaseHelper == null) {
_databaseHelper = DatabaseHelper._createInstance();
}
return _databaseHelper;
}
Future<Database> get database async {
if (_database == null) {
_database = await initDB();
}
return _database;
}
Future<Database> initDB() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'projects.db';
var projectsDB = await openDatabase(path, version: 1, onCreate: _createDB);
return projectsDB;
}
void _createDB(Database db, int newVersion) async {
await db.execute('CREATE TABLE $projectTable('
'$colId INTEGER PRIMARY KEY AUTOINCREMENT,'
'$colName TEXT,'
'$colDate TEXT,'
'$colLocation TEXT,'
'$colPersonalDB TEXT)');
}
Future<List<Map<String, dynamic>>> getProjectMapList() async {
Database db = await this.database;
var result = await db.query(projectTable);
return result;
}
Future<int> insertProject(Project project) async {
Database db = await this.database;
var result = await db.insert(projectTable, project.toMap());
return result;
}
Future<int> updateProject(Project project) async {
var db = await this.database;
var result = await db.update(projectTable, project.toMap(), where: '$colId = ?', whereArgs: [project.id]);
return result;
}
Future<int> deleteProject(int id) async {
var db = await this.database;
int result = await db.delete(projectTable, where: '$colId = $id');
return result;
}
Future<int> getCount() async {
Database db = await this.database;
List<Map<String, dynamic>> x = await db.rawQuery('SELECT COUNT (*) from $projectTable');
int result = Sqflite.firstIntValue(x);
return result;
}
Future<List<Project>> getProjectList() async {
var projectMapList = await getProjectMapList();
int count = projectMapList.length;
List<Project> projectList = <Project>[];
for (int i = 0; i < count; i++) {
projectList.add(Project.fromMapObject(projectMapList[i]));
}
return projectList;
}
}
Error:
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building NewProjectScreen(dirty, state: _NewProjectScreenState#670bc):
The getter 'name' was called on null.
Receiver: null
Tried calling: name
The relevant error-causing widget was:
NewProjectScreen file:///C:/Users/gabri/AndroidStudioProjects/leisy/lib/surface/main_screen.dart:116:89
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 _NewProjectScreenState.build (package:leisy/surface/new_project_screen.dart:24:35)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4612:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4667:11)
...
====================================================================================================
If anybody can help me, I would really appreciate it. And if anything in my code is inconvenient or badly implemented, please be kind with me I'm a beginner at this.
The file new_project_screen.dart has the problem
To be exact, the problem can be found in lines 24:35
And seems like that project variable is null project.name;
That is because you are creating Project project but isn't instancied yet. Is just a null variable
See the image below, will help you to understand a bit:
https://dartpad.dev/1ebc897cd3f547cc0b79e52290a63653
So to fix it, you need to create the instance previously

Getter method returning null value

I have developed a login page using local db in flutter SQL. I want to display the username in SQL database after the table is created but the getter method is returning null.
I am displaying the username like this in class home
body: Center(
child: user != null ? Text("Saved \n \n Username: '${user.username}' ")
: Text("Not saved"),
),
Here is login page code
BuildContext _ctx;
bool _isLoading = false;
final _formKey = new GlobalKey<FormState>();
final scaffoldKey = new GlobalKey<ScaffoldState>();
String _username,_password;
LoginPagePresenter _presenter;
#override
void initState(){
_presenter = new LoginPagePresenter(this);
}
void _submit(){
final form = _formKey.currentState;
if(form.validate()){
_isLoading = true;
form.save();
_presenter.doLogin(_username, _password);
}
}
void _showsnackbar(String text){
scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(text),
));
}
#override
Widget build(BuildContext context) {
return _isLoading ? Loading() :Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text('Login Page',textAlign: TextAlign.center,),
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
TextFormField(
decoration: InputDecoration(labelText:'Username' ),
validator: (val) => val.isEmpty ? 'Enter Username' : null,
onChanged: (val) {
setState(() => _username = val);
},
),
SizedBox(height: 20.0),
TextFormField(
obscureText: true,
decoration: InputDecoration(labelText:'Password' ),
validator: (val) => val.length < 6 ? 'Enter a password 6+ chars long' : null,
onChanged: (val) {
setState(() => _password = val);
},
),
SizedBox(height: 20.0),
RaisedButton(
color: Colors.pink[400],
child: Text(
'Sign In',
style: TextStyle(color: Colors.white),
),
onPressed: () async {
_submit();
}
),
],
),
),
),
);
}
#override
void onLoginError(String error) {
_showsnackbar(error);
setState(() {
_isLoading = false;
});
}
#override
void onLoginSuccess(User user) async {
_showsnackbar(user.toString());
setState(() {
_isLoading = false;
});
var db = new DatabaseHelper();
await db.saveUser(user);
Navigator.of(_ctx).push(MaterialPageRoute<Null>(
builder: (BuildContext context){
return new Home(
user:user,
);
}
));
}
Here is user class
class User{
String _username;
String _password;
User(this._username,this._password);
User.map(dynamic obj){
this._username = obj['username'];
this._password = obj['password'];
}
String get username => _username;
String get password => _password;
Map<String,dynamic> toMap(){
var map = new Map<String,dynamic>();
map["username"] = _username;
map["password"] = _password;
return map;
}
}
And this is database helper class
class DatabaseHelper{
static final DatabaseHelper _instance = new DatabaseHelper.internal();
DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database _db;
Future<Database> get db async{
if(_db!= null)
{
return _db;
}
_db = await initdb();
return _db;
}
initdb() async{
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path,"main.db");
var ourDb = await openDatabase(path,version:1,onCreate:_onCreate);
return ourDb;
}
void _onCreate(Database db,int version)async {
await db.execute("CREATE TABLE User(id INTEGER PRIMARY KEY,username TEXT,password TEXT)");
print("Table created");
}
//insertion of data
Future<int> saveUser(User user)async {
var dbClient = await db;
int res = await dbClient.insert("User", user.toMap());
return res;
}
// deleting data
Future<int> deleteUser(User user)async {
var dbClient = await db;
int res = await dbClient.delete("User");
return res;
}
}
this is login presenter
abstract class LoginPageContract{
void onLoginSuccess(User user);
void onLoginError(String error);
}
class LoginPagePresenter{
LoginPageContract _view;
RestData api = new RestData();
LoginPagePresenter(this._view);
doLogin(String username,String password){
api
.login(username, password)
.then((user)=> _view.onLoginSuccess(user))
.catchError((onError)=>_view.onLoginError(onError()));
}
}
This is github link to the code for reference: https://github.com/meadows12/sql
Please help !!
All you have to do is to access the user obejct as "widget.user" instead of "user". So, the following would do the trick :
body: Center(
child: widget.user != null ? Text("Saved \n \n Username: '${widget.user.username}' ")
: Text("Not saved"),
)
There's one more problem in the code. You are not assigning the buildcontext to variable _ctx. So, the screen change didn't happen on your code on the github. I added one line in login.dart as below to make it work :
Widget build(BuildContext context) {
_ctx = context;
return _isLoading ? Loading() :Scaffold(______________
Result :