Issue
I have a Flutter application and I want to add a page that appears when opening the application asking the user to answer a question such as how many countries in the world - the answer is already stored in the application, so that if the answer is correct, the answer is stored and the application opens and this page does not appear again, But if the answer is wrong, the user remains On this page, he cannot open the application until he writes the correct answer Any suggestions or examples that would be helpful?
Update: I have created the following verification page that checks if the entered text is equal to the stored text,I used flutter_secure_storage to store the text if it is true Now iwant to know how i can add the shared_preferences to my code?
class check extends StatefulWidget {
@override
_checkState createState() => _checkState();
}
class _checkState extends State<check> {
final formKey = GlobalKey<FormState>();
final verifierController = TextEditingController();
String storedvalue = '200';
@override
void initState() {
super.initState();
init();
}
Future init() async {
final realcode = await UserSecureStorage.getCodestored() ?? '';
setState(() {
this.verifierController.text = realcode;
});
}
Codecheck() async {
await UserSecureStorage.setUsername(verifierController.text);
if (storedvalue == verifierController.text) {
Navigator.of(context).pushReplacementNamed('/homeScreen');
}
else {
Navigator.of(context).pushReplacementNamed('/checkScreen');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(10),
child: Center(
child: Stack(
children: [
Align(
child: Text(
'how many countries are there in the world?',
.........
),
Align(
child: TextFormField(
.......
controller: verifierController,
)),
Align(
child: RaisedButton(
.........
onPressed: () async {
Codecheck();
},
..........
Solution
In a very simple way, you can use the SharedPreferences plugin to store the answer to your question permanently, for example
You can store a "question" key that will have the value "how many countries are there in the world?" (optional). You also store an "answer" key with the value "324" (the exact number of countries in the world)
Then you create an "answer_found" key which will be a boolean and will update if yes or no the user answers the question correctly.
Then when the application starts, you will first query the "answer_found" key to see if its value is True.
If this value is True, you do not display the questionnaire page, if it is false or null, you display the questionnaire page.
When the user will enter the answer, simply compare there his answer to the one contained in the "answer" key in the preferences. If it is correct, simply update the key "answer_found" to become true. In the opposite case do nothing (or what you want)
UPDATE : As you asked, here is an extract of the code. I made it as simple as possible (although it is a bit barbaric) so that you can understand the mechanism as well as possible and that you can adapt it as you want.
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SharedPreferences.getInstance().then((preferences) async {
//Optional key (and can put want you want)
//Store the question in preferences
await preferences.setString('question', 'how many countries are there in the world?');
//Store the answer
await preferences.setInt('answer', 324);
});
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool? questionAnswered;
@override
void initState() {
super.initState();
_getQuestionState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: home,
);
}
Widget get home {
if (questionAnswered == null) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
} else if (questionAnswered!) {
return const HomePage();
} else {
return const QuestionPage();
}
}
Future<void> _getQuestionState() async {
final preferences = await SharedPreferences.getInstance();
//obtaining the present value of 'answer_found' to know if the question has been answered (with a correct answer)
final isQuestionAnswered = preferences.getBool('answer_found') ??
false; //if the value is null, we set it to false (to avoid a NullException)
setState(() => questionAnswered = isQuestionAnswered);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Home Page'),
),
body: const Center(
child: Text('WELCOME'),
),
);
}
class QuestionPage extends StatefulWidget {
const QuestionPage({Key? key}) : super(key: key);
@override
State<QuestionPage> createState() => _QuestionPageState();
}
class _QuestionPageState extends State<QuestionPage> {
late final TextEditingController _answerTextController;
@override
void initState() {
super.initState();
_answerTextController = TextEditingController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('how many countries are there in the world?'),
TextField(
controller: _answerTextController,
decoration: const InputDecoration(hintText: 'Enter answer'),
),
ElevatedButton(
onPressed: () async {
//Convert the user's response to be in an integer type (because we want to make a comparison with an integer)
//The user's response will be null, if the user has not entered an integer
final userAnswer = int.tryParse(_answerTextController.text);
if (userAnswer != null) {
final preferences = await SharedPreferences.getInstance();
final storedAnswer = preferences.getInt('answer')!;
if (userAnswer == storedAnswer) {
preferences.setBool('answer_found', true);
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => const HomePage()));
} else {
//Notify user that his answer was wrong or do some stuff (what you want)
}
} else {
//Do some stuff
}
},
child: const Text('Validate')),
],
),
),
);
}
}
I have never used the flutter_secure_storage plugin, but following the code snippet I made for you, I think you could readapt it to work with flutter_secure storage, the reasoning and logic is the same.
P.S: You don't have to use shared_preferences and flutter_secure_storage at the same time. You can simply use flutter_secure_storage which, unlike shared_preferences, offers you a secure storage space (as its name indicates) and you only have to implement the same logic.
Answered By - Steeven Delucis
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.