Skip to content

Commit 04936b8

Browse files
committed
add initial code
1 parent 647d656 commit 04936b8

File tree

10 files changed

+836
-100
lines changed

10 files changed

+836
-100
lines changed

lib/main.dart

Lines changed: 4 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,22 @@
11
import 'package:flutter/material.dart';
2+
import 'package:python_exercise_builder/pages/home_page.dart';
23

34
void main() {
4-
runApp(MyApp());
5+
runApp(App());
56
}
67

7-
class MyApp extends StatelessWidget {
8+
class App extends StatelessWidget {
89
// This widget is the root of your application.
910
@override
1011
Widget build(BuildContext context) {
1112
return MaterialApp(
1213
title: 'Flutter Demo',
1314
theme: ThemeData(
14-
// This is the theme of your application.
15-
//
16-
// Try running your application with "flutter run". You'll see the
17-
// application has a blue toolbar. Then, without quitting the app, try
18-
// changing the primarySwatch below to Colors.green and then invoke
19-
// "hot reload" (press "r" in the console where you ran "flutter run",
20-
// or simply save your changes to "hot reload" in a Flutter IDE).
21-
// Notice that the counter didn't reset back to zero; the application
22-
// is not restarted.
2315
primarySwatch: Colors.blue,
24-
// This makes the visual density adapt to the platform that you run
25-
// the app on. For desktop platforms, the controls will be smaller and
26-
// closer together (more dense) than on mobile platforms.
2716
visualDensity: VisualDensity.adaptivePlatformDensity,
2817
),
29-
home: MyHomePage(title: 'Flutter Demo Home Page'),
18+
home: HomePage(title: 'Python Exercise Builder'),
3019
);
3120
}
3221
}
3322

34-
class MyHomePage extends StatefulWidget {
35-
MyHomePage({Key key, this.title}) : super(key: key);
36-
37-
// This widget is the home page of your application. It is stateful, meaning
38-
// that it has a State object (defined below) that contains fields that affect
39-
// how it looks.
40-
41-
// This class is the configuration for the state. It holds the values (in this
42-
// case the title) provided by the parent (in this case the App widget) and
43-
// used by the build method of the State. Fields in a Widget subclass are
44-
// always marked "final".
45-
46-
final String title;
47-
48-
@override
49-
_MyHomePageState createState() => _MyHomePageState();
50-
}
51-
52-
class _MyHomePageState extends State<MyHomePage> {
53-
int _counter = 0;
54-
55-
void _incrementCounter() {
56-
setState(() {
57-
// This call to setState tells the Flutter framework that something has
58-
// changed in this State, which causes it to rerun the build method below
59-
// so that the display can reflect the updated values. If we changed
60-
// _counter without calling setState(), then the build method would not be
61-
// called again, and so nothing would appear to happen.
62-
_counter++;
63-
});
64-
}
65-
66-
@override
67-
Widget build(BuildContext context) {
68-
// This method is rerun every time setState is called, for instance as done
69-
// by the _incrementCounter method above.
70-
//
71-
// The Flutter framework has been optimized to make rerunning build methods
72-
// fast, so that you can just rebuild anything that needs updating rather
73-
// than having to individually change instances of widgets.
74-
return Scaffold(
75-
appBar: AppBar(
76-
// Here we take the value from the MyHomePage object that was created by
77-
// the App.build method, and use it to set our appbar title.
78-
title: Text(widget.title),
79-
),
80-
body: Center(
81-
// Center is a layout widget. It takes a single child and positions it
82-
// in the middle of the parent.
83-
child: Column(
84-
// Column is also a layout widget. It takes a list of children and
85-
// arranges them vertically. By default, it sizes itself to fit its
86-
// children horizontally, and tries to be as tall as its parent.
87-
//
88-
// Invoke "debug painting" (press "p" in the console, choose the
89-
// "Toggle Debug Paint" action from the Flutter Inspector in Android
90-
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
91-
// to see the wireframe for each widget.
92-
//
93-
// Column has various properties to control how it sizes itself and
94-
// how it positions its children. Here we use mainAxisAlignment to
95-
// center the children vertically; the main axis here is the vertical
96-
// axis because Columns are vertical (the cross axis would be
97-
// horizontal).
98-
mainAxisAlignment: MainAxisAlignment.center,
99-
children: <Widget>[
100-
Text(
101-
'You have pushed the button this many times:',
102-
),
103-
Text(
104-
'$_counter',
105-
style: Theme.of(context).textTheme.headline4,
106-
),
107-
],
108-
),
109-
),
110-
floatingActionButton: FloatingActionButton(
111-
onPressed: _incrementCounter,
112-
tooltip: 'Increment',
113-
child: Icon(Icons.add),
114-
), // This trailing comma makes auto-formatting nicer for build methods.
115-
);
116-
}
117-
}

lib/models/question.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:json_annotation/json_annotation.dart';
2+
3+
part 'question.g.dart';
4+
5+
@JsonSerializable()
6+
class Question {
7+
final int level;
8+
final String question;
9+
final String hints;
10+
final String solution;
11+
final String test;
12+
13+
Question({this.level, this.question, this.hints, this.solution, this.test});
14+
15+
factory Question.fromJson(Map<String, dynamic> json) => _$QuestionFromJson(json);
16+
17+
Map<String, dynamic> toJson() => _$QuestionToJson(this);
18+
}

lib/models/question.g.dart

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/pages/home_page.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:python_exercise_builder/pages/question_page.dart';
3+
import 'package:python_exercise_builder/pages/setting_page.dart';
4+
5+
class HomePage extends StatefulWidget {
6+
HomePage({Key key, this.title}) : super(key: key);
7+
final String title;
8+
9+
@override
10+
_HomePageState createState() => _HomePageState();
11+
}
12+
13+
class _HomePageState extends State<HomePage> {
14+
static List<Widget> _pages = <Widget>[QuestionPage(), SettingPage()];
15+
16+
int _currentIndex = 0;
17+
18+
void _onItemTapped(int index) {
19+
setState(() {
20+
_currentIndex = index;
21+
});
22+
}
23+
24+
@override
25+
Widget build(BuildContext context) {
26+
return Scaffold(
27+
body: SafeArea(
28+
child: IndexedStack(
29+
index: _currentIndex,
30+
children: _pages,
31+
),
32+
),
33+
bottomNavigationBar: BottomNavigationBar(
34+
type: BottomNavigationBarType.fixed,
35+
items: const <BottomNavigationBarItem>[
36+
BottomNavigationBarItem(
37+
icon: Icon(
38+
Icons.question_answer,
39+
),
40+
title: Text('Question'),
41+
),
42+
BottomNavigationBarItem(
43+
icon: Icon(
44+
Icons.settings,
45+
),
46+
title: Text('Settings'),
47+
),
48+
],
49+
currentIndex: _currentIndex,
50+
onTap: _onItemTapped,
51+
),
52+
);
53+
}
54+
}

lib/pages/question_form_page.dart

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_form_builder/flutter_form_builder.dart';
3+
import 'package:python_exercise_builder/models/question.dart';
4+
5+
class QuestionFormPage extends StatefulWidget {
6+
QuestionFormPage({Key key, this.question}) : super(key: key);
7+
final Question question;
8+
9+
@override
10+
_QuestionFormPageState createState() => _QuestionFormPageState();
11+
}
12+
13+
class _QuestionFormPageState extends State<QuestionFormPage> {
14+
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
15+
@override
16+
Widget build(BuildContext context) {
17+
var question = widget.question;
18+
return Scaffold(
19+
appBar: AppBar(),
20+
body: SingleChildScrollView(
21+
child: Column(
22+
children: [
23+
FormBuilder(
24+
key: _fbKey,
25+
initialValue: {
26+
'level': question?.level,
27+
'question': question?.question,
28+
'hints': question?.hints,
29+
'solution': question?.solution,
30+
'test': question?.test,
31+
},
32+
autovalidate: true,
33+
child: Column(
34+
children: <Widget>[
35+
FormBuilderChoiceChip(
36+
attribute: 'level',
37+
decoration: InputDecoration(
38+
labelText: 'Select an level',
39+
),
40+
options: [
41+
FormBuilderFieldOption(value: '', child: Text('')),
42+
FormBuilderFieldOption(value: 1, child: Text('Level 1')),
43+
FormBuilderFieldOption(value: 2, child: Text('Level 2')),
44+
FormBuilderFieldOption(value: 3, child: Text('Level 3')),
45+
FormBuilderFieldOption(value: 4, child: Text('Level 4')),
46+
],
47+
),
48+
FormBuilderTextField(
49+
attribute: "question",
50+
maxLines: 5,
51+
decoration: InputDecoration(
52+
labelText: "question",
53+
),
54+
),
55+
FormBuilderTextField(
56+
attribute: "hints",
57+
maxLines: 5,
58+
decoration: InputDecoration(
59+
labelText: "hints",
60+
),
61+
),
62+
FormBuilderTextField(
63+
attribute: "solution",
64+
maxLines: 5,
65+
decoration: InputDecoration(
66+
labelText: "solution",
67+
),
68+
),
69+
FormBuilderTextField(
70+
attribute: "test",
71+
maxLines: 5,
72+
decoration: InputDecoration(
73+
labelText: "test",
74+
),
75+
),
76+
],
77+
),
78+
)
79+
],
80+
),
81+
),
82+
floatingActionButton: FloatingActionButton(
83+
child: Icon(Icons.save),
84+
onPressed: () async {
85+
if (_fbKey.currentState.saveAndValidate()) {
86+
var question = Question.fromJson(_fbKey.currentState.value);
87+
Navigator.of(context).pop(question);
88+
}
89+
},
90+
),
91+
);
92+
}
93+
}

0 commit comments

Comments
 (0)