215 Commits

Author SHA1 Message Date
Robin Koedood
b2c320dd14 [UPDATED] Route Test 2021-01-06 17:12:52 +01:00
Sem van der Hoeven
ce264d78bc rename 2021-01-06 17:09:11 +01:00
Robin Koedood
f8acc35c5b Merge remote-tracking branch 'origin/follow-route' into follow-route 2021-01-06 17:07:47 +01:00
Robin Koedood
e5e0916555 [ADD] Static Data Test 2021-01-06 17:07:26 +01:00
Sem van der Hoeven
c738deab23 commentssssssssssssssssssssss 2021-01-06 17:06:27 +01:00
Sem van der Hoeven
223e77cdc8 Merge branch 'follow-route' of https://github.com/SemvdH/Next-Location into follow-route 2021-01-06 16:57:08 +01:00
Sem van der Hoeven
7c9dc07c3d added keeping zoom level 2021-01-06 16:56:57 +01:00
Robin Koedood
187f45b770 Merge remote-tracking branch 'origin/follow-route' into follow-route 2021-01-06 16:56:21 +01:00
Robin Koedood
04487b77a7 [ADD] RouteHandler Test 2021-01-06 16:56:16 +01:00
RemoMeijer
d67d78b385 Added total distance in route detail 2021-01-06 16:27:28 +01:00
Sem van der Hoeven
fb2f7e8a66 added updating time when you start a route but are already following another one 2021-01-06 16:20:03 +01:00
Sem van der Hoeven
c412f36e6c moved sections into own methods 2021-01-06 16:09:00 +01:00
RemoMeijer
2d9dfe9c0e updated coords 2021-01-06 15:53:02 +01:00
RemoMeijer
b31ba7023e Updated coordinates 2021-01-06 15:50:43 +01:00
Sem van der Hoeven
7ba87b71b0 added time 2021-01-06 15:44:14 +01:00
Sem van der Hoeven
edfc125427 added icon 2021-01-06 15:37:10 +01:00
Sem van der Hoeven
6d3a092298 Merge branch 'follow-route' of https://github.com/SemvdH/Next-Location into follow-route 2021-01-06 15:32:35 +01:00
Sem van der Hoeven
15608bed2b added icon to drawable 2021-01-06 15:32:25 +01:00
RemoMeijer
deb4bd5a19 Distance Calculation works, added distance test 2021-01-06 15:26:07 +01:00
Sem van der Hoeven
05c8951f2c Merge branch 'follow-route' of https://github.com/SemvdH/Next-Location into follow-route 2021-01-06 15:25:36 +01:00
Sem van der Hoeven
a27ebfc0c3 added stopping route if last location has been reached 2021-01-06 14:40:30 +01:00
Bart
dabe3cfb99 moved Refreshable to package Fragment 2021-01-06 14:35:54 +01:00
Sem van der Hoeven
f806015963 Merge branch 'follow-route' of https://github.com/SemvdH/Next-Location into follow-route 2021-01-06 14:33:38 +01:00
Sem van der Hoeven
fcec6e1ecd stuffff 2021-01-06 14:33:25 +01:00
Bart
7284b66c13 Merge branch 'languages' into follow-route 2021-01-06 14:26:39 +01:00
Sem van der Hoeven
6266705c3e fix clusterfuck? 2021-01-06 14:18:37 +01:00
Sem van der Hoeven
e90582b539 stuff merge iewl 2021-01-06 14:12:59 +01:00
Sem van der Hoeven
68f2855a66 added locations back 2021-01-06 14:07:19 +01:00
Bart
d018b83490 added strings 2021-01-06 14:04:37 +01:00
Sem van der Hoeven
1aee93cd0c mergeeee 2021-01-06 13:59:59 +01:00
Sem van der Hoeven
216f48cc0f fixed distance 2021-01-06 13:57:00 +01:00
Robin Koedood
8a758f1d8d [ADD] Start Route button from other branch 2021-01-06 13:55:20 +01:00
Sem van der Hoeven
bd623a3f1d stuff 2021-01-06 13:54:30 +01:00
Sem van der Hoeven
1760f510c6 comment location 2021-01-06 13:46:08 +01:00
Sem van der Hoeven
ba9569b5a8 Merge branch 'follow-route' of https://github.com/SemvdH/Next-Location into follow-route 2021-01-06 13:45:53 +01:00
Robin Koedood
ca8d291262 [CHANGED] String values 2021-01-06 13:44:17 +01:00
Sem van der Hoeven
98eeba4de1 comments 2021-01-06 13:42:26 +01:00
Robin Koedood
f0ef9512a0 Merge remote-tracking branch 'origin/RecyclerView' into Tests 2021-01-06 13:32:22 +01:00
sebas
f0f87af42b Merge branch 'follow-route' into RecyclerView
# Conflicts:
#	app/src/main/java/com/a1/nextlocation/fragments/RouteDetailFragment.java
2021-01-06 13:23:58 +01:00
sebas
192f1a4c64 Route detail fragment now fills in the right name and text 2021-01-06 13:22:37 +01:00
RemoMeijer
391792a5e2 Merge branch 'RecyclerView' into follow-route
# Conflicts:
#	app/src/main/assets/locations.json
#	app/src/main/assets/routes.json
#	app/src/main/java/com/a1/nextlocation/fragments/LocationDetailFragment.java
#	app/src/main/java/com/a1/nextlocation/fragments/RouteDetailFragment.java
#	app/src/main/res/values/strings.xml
2021-01-06 13:20:52 +01:00
Bart
1cf973da9b bottom navigation sets locale on startup and language change. Fixed a bug where the selected fragment changes when rotated. 2021-01-06 12:21:31 +01:00
Robin Koedood
21c479076d Merge remote-tracking branch 'origin/follow-route' into Tests 2021-01-06 12:10:05 +01:00
Robin Koedood
0ed16ee069 [CHANGED] String values 2021-01-06 12:08:25 +01:00
Sem van der Hoeven
1f53890a4b added comments 2021-01-06 12:08:18 +01:00
RemoMeijer
09ced99654 Added route 2021-01-06 11:59:45 +01:00
sebas
86bc0f0c19 Merge branch 'RecyclerView' of https://github.com/SemvdH/Next-Location into RecyclerView
# Conflicts:
#	app/src/main/assets/locations.json
2021-01-06 11:56:14 +01:00
sebas
deb599db25 Font now changes according to last change when starting application, added scrollView to location detail, location detail now takes location name and description and added 2 discriptions to location.json 2021-01-06 11:54:39 +01:00
RemoMeijer
9be5ba27ab Added descriptions on all locations 2021-01-06 11:47:14 +01:00
Sem van der Hoeven
926a984c71 stop icon 2021-01-06 11:33:35 +01:00
Sem van der Hoeven
f5da1c8a83 added displaying all locations upon stopping the route 2021-01-06 11:33:15 +01:00
Robin Koedood
525d4b776d Merge remote-tracking branch 'origin/develop' into Tests 2021-01-06 11:14:19 +01:00
sebas
0e63bff0f1 Merge branch 'RecyclerView' of https://github.com/SemvdH/Next-Location into RecyclerView
# Conflicts:
#	app/src/main/java/com/a1/nextlocation/fragments/LocationDetailFragment.java
2021-01-06 11:13:16 +01:00
sebas
5e76ced998 Location detail now displays images 2021-01-06 11:12:33 +01:00
Robin Koedood
da2a9e43bc Merge remote-tracking branch 'origin/Tests' into Tests 2021-01-06 10:50:18 +01:00
Robin Koedood
3d1cfd244b [ADD] Main Activity Test 2021-01-06 10:50:14 +01:00
Bart
40e3ca3d51 Merge branch 'languages' into develop 2021-01-06 10:49:35 +01:00
Bart
6dd2f5de40 default strings.xml is now English, added more string resources 2021-01-06 10:48:23 +01:00
Sem van der Hoeven
f6af7ae80b added route singleton 2021-01-06 10:48:03 +01:00
RemoMeijer
d4cfa17fda Tried to add pictures in location detail 2021-01-06 10:45:00 +01:00
Sem van der Hoeven
abc58d3606 following route stuff 2021-01-06 10:41:56 +01:00
Bipin
399652c2ce Merge branch 'Tests' of https://github.com/SemvdH/Next-Location into Tests 2021-01-06 10:41:10 +01:00
Bipin
d9a6e1eff0 GeometryStart 2021-01-06 10:41:07 +01:00
Sem van der Hoeven
1877a693d0 added boolean to singleton 2021-01-06 10:40:20 +01:00
Sem van der Hoeven
80764591ad comment 2021-01-06 10:36:37 +01:00
sebas
738a733b72 Location adapter also now implements images into to location items 2021-01-06 10:20:55 +01:00
Bart
00d306631b Finished language functionality 2021-01-05 17:19:09 +01:00
Robin Koedood
20c09c3458 [TRIED] MainActivity Test 2021-01-05 16:52:48 +01:00
Sem van der Hoeven
587380fd89 added updating location when you're close to it 2021-01-05 16:39:12 +01:00
Bart
f7a2a79d00 Language can be changed, doesn't refresh automatically yet 2021-01-05 16:20:43 +01:00
RemoMeijer
faa79b5553 Added all pictures 2021-01-05 16:18:46 +01:00
Robin Koedood
e71c195573 [ADD] DirectionResultTest 2021-01-05 16:11:19 +01:00
RemoMeijer
1834aec01b Updated buttons 2021-01-05 16:10:06 +01:00
Robin Koedood
d4d452e723 Merge remote-tracking branch 'origin/Tests' into Tests 2021-01-05 16:04:32 +01:00
Robin Koedood
f381a29274 [ADD] DirectionsStep test 2021-01-05 16:04:25 +01:00
Sem van der Hoeven
062739ac7b added navigation to location from map 2021-01-05 16:02:48 +01:00
sebas
360198e784 65+ stand remember position and changes the theme. 2021-01-05 15:50:29 +01:00
Sem van der Hoeven
16bd30f785 added locations to map 2021-01-05 13:43:10 +01:00
Bart
fe5a5b6dfd Added functionality to the dropdown in settings. Language preference is stored in the sharedPreferences 2021-01-05 13:38:21 +01:00
Bipin
7e0b888974 Merge branch 'Tests' of https://github.com/SemvdH/Next-Location into Tests 2021-01-05 13:36:43 +01:00
Bipin
804bdddbef Remove detail 2021-01-05 13:36:14 +01:00
Robin Koedood
e1636c6bec Merge remote-tracking branch 'origin/Tests' into Tests 2021-01-05 13:32:50 +01:00
Robin Koedood
77a6226c1d [ADD] Comments 2021-01-05 13:32:44 +01:00
RemoMeijer
2e5f57aa23 Added coupon arrow 2021-01-05 13:32:28 +01:00
Bipin
c6b33f2663 fixie 2021-01-05 13:29:33 +01:00
Bipin
ba83d69c9f Merge branch 'Tests' of https://github.com/SemvdH/Next-Location into Tests
# Conflicts:
#	app/src/main/res/layout/fragment_settings.xml
2021-01-05 13:27:46 +01:00
Bipin
08902472a3 Added Settings and Statistics, started detail 2021-01-05 13:27:25 +01:00
RemoMeijer
fbf8cbe1c5 Small fix 2021-01-05 13:23:48 +01:00
Robin Koedood
e36e853875 [ADD] Route Fragment test 2021-01-05 13:19:27 +01:00
RemoMeijer
aae67f53ec Statistics button works 2021-01-05 13:18:25 +01:00
Robin Koedood
356ee55375 Merge remote-tracking branch 'origin/RecyclerView' into Tests 2021-01-05 13:16:30 +01:00
RemoMeijer
bc8b83e4f6 Updated strings and values to @string/ 2021-01-05 13:15:25 +01:00
Sem van der Hoeven
65d2f31e3f stuff 2021-01-05 13:03:42 +01:00
Sem van der Hoeven
40331f3135 removed test route 2021-01-05 12:59:35 +01:00
Sem van der Hoeven
f5f077db0f location stuff 2021-01-05 12:13:42 +01:00
Robin Koedood
3b363b3f33 [ADD] Location Detail Fragment Test 2021-01-05 12:07:15 +01:00
Robin Koedood
89902a5962 Merge remote-tracking branch 'origin/RecyclerView' into Tests 2021-01-05 12:03:36 +01:00
RemoMeijer
d53f63a6d7 Updated values 2021-01-05 12:02:20 +01:00
Robin Koedood
a0d35caeb5 [ADD] Coupon test 2021-01-05 11:44:25 +01:00
Sem van der Hoeven
e8af38981f added visualizing route 2021-01-05 11:25:13 +01:00
Robin Koedood
d3cab8c70d [ADD] Location Tests + ID at every XML file 2021-01-05 10:58:33 +01:00
RemoMeijer
d63b150275 Improved fragments 2021-01-05 10:47:35 +01:00
Bart
f236067706 Added English string.xml 2021-01-05 10:45:32 +01:00
RemoMeijer
a75b81033f Fixed locationList 2021-01-05 10:09:24 +01:00
Sem van der Hoeven
bcd9eb6378 merge 2021-01-04 15:49:42 +01:00
Sem van der Hoeven
a12493972a Merge branch 'directions-api' into develop 2021-01-04 15:47:31 +01:00
RemoMeijer
678b179e04 added backbutton 2021-01-04 15:46:18 +01:00
Sem van der Hoeven
9b93ddaec5 stuff 2021-01-04 15:44:47 +01:00
RemoMeijer
1b770020ed Added List button on Home 2021-01-04 15:37:09 +01:00
Robin Koedood
29b3623ab5 Merge remote-tracking branch 'origin/Tests' into Tests 2021-01-04 15:27:58 +01:00
Robin Koedood
da45a0a40e [TRIED] Test FileIO class
No luck so far
2021-01-04 15:27:52 +01:00
Sem van der Hoeven
5e218f3b99 added getting directions for whole route 2021-01-04 15:20:24 +01:00
sebas
e761dd80e5 Adjusted frame layout in main fragment so that topbar now longer displays over the top part of fragments, but instead above it. 2021-01-04 14:46:15 +01:00
sebas
79e24621e2 Statistics now shows amount of coupons 2021-01-04 14:38:39 +01:00
RemoMeijer
1549fc7a59 Coupon layout updated 2021-01-04 14:35:50 +01:00
Bart
edcfd2ff0a Added popups for coupons 2021-01-04 14:31:16 +01:00
Sem van der Hoeven
96f32ccdbc added deserialization of the api response 2021-01-04 13:50:50 +01:00
Bart
547d676a68 Coupon onClick unfinished code 2021-01-04 13:44:09 +01:00
RemoMeijer
d96a54863c coupons working 2021-01-04 13:04:02 +01:00
Bipin
7b9ca656aa Improved RouteTest, made LocationTest 2021-01-04 11:49:14 +01:00
Sem van der Hoeven
d433565fef added parsing of directions response 2021-01-04 11:42:34 +01:00
RemoMeijer
2118336815 Switching fragment from statistics to coupon works 2021-01-04 11:40:06 +01:00
Robin Koedood
36eb28ce07 Merge remote-tracking branch 'origin/Tests' into Tests 2021-01-04 11:39:08 +01:00
Robin Koedood
eea66fd153 [ADD] Data and Coupon Tests 2021-01-04 11:38:54 +01:00
RemoMeijer
ff32eefab0 Added coupon item 2021-01-04 11:27:49 +01:00
sebas
e2bccb6e76 Changed couponfragment layout 2021-01-04 11:23:16 +01:00
RemoMeijer
c355f64d38 Added couponadapter 2021-01-04 11:08:49 +01:00
sebas
91c0435e55 Merge branch 'RecyclerView' of https://github.com/SemvdH/Next-Location into RecyclerView 2021-01-04 11:06:38 +01:00
sebas
9ca3b12d71 Added code to CouponFragment 2021-01-04 11:06:04 +01:00
Bipin
08d9543e3b RouteTest made 2021-01-04 11:01:23 +01:00
Bart
70a9878b06 Merge branch 'statisticsFragment' into RecyclerView 2021-01-04 11:00:00 +01:00
Bart
294814dea8 StatisticFragment navigation to CouponFragment 2021-01-04 10:59:43 +01:00
RemoMeijer
6b197c4742 Location implements parcable 2020-12-17 14:57:04 +01:00
RemoMeijer
a3d8bdfd77 Merge branch 'develop' into RecyclerView
# Conflicts:
#	app/src/main/java/com/a1/nextlocation/data/Location.java
2020-12-17 14:56:15 +01:00
RemoMeijer
6f10444126 Route displays name 2020-12-17 14:48:15 +01:00
Robin Koedood
1ca13e3a6b [ADD]Locations from JSON now in app. Markers good color. No action bar. 2020-12-17 14:45:58 +01:00
RemoMeijer
1f7cd49a90 Route works and is clickable 2020-12-17 14:35:05 +01:00
Bipin
9c4eb98fb4 Added real locations to JSON 2020-12-17 14:24:06 +01:00
Sem van der Hoeven
610b23b056 added custom overlay 2020-12-17 14:22:20 +01:00
RemoMeijer
aba26f3211 Merge branch 'develop' into RecyclerView 2020-12-17 13:55:01 +01:00
Sem van der Hoeven
95a2e4e849 made list managers load on mainactivity oncreate 2020-12-17 13:53:00 +01:00
Sem van der Hoeven
74fb4440ed made listmanagers enums 2020-12-17 13:51:45 +01:00
Bart
6c923d27b2 Connected locationFragment with recyclerview and added functionality 2020-12-17 13:46:41 +01:00
Sem van der Hoeven
17d977bb17 fixed loading 2020-12-17 13:41:20 +01:00
Sem van der Hoeven
b52c5556d2 finished loading 2020-12-17 11:50:31 +01:00
Sem van der Hoeven
70342c6506 merge with recyclerview 2020-12-17 11:21:38 +01:00
Sem van der Hoeven
311a794a69 removed loader from route list manager 2020-12-17 11:18:23 +01:00
RemoMeijer
dbc10014f9 Merge branch 'develop' into RecyclerView 2020-12-17 11:16:36 +01:00
RemoMeijer
1f835a94b0 Updated managers so they can load 2020-12-17 11:16:03 +01:00
Sem van der Hoeven
12c8d6a62d [ADD] loaders and fileio read 2020-12-17 11:14:43 +01:00
Sem van der Hoeven
9e8e9f4cdd changed loader stuff 2020-12-17 11:00:14 +01:00
Sem van der Hoeven
1d48ada0ab changed loader stuff 2020-12-17 10:59:07 +01:00
Sem van der Hoeven
6a07ce77f0 remove room stuff 2020-12-17 10:32:28 +01:00
Sem van der Hoeven
5edf50c808 Merge branch 'Fragment' into develop 2020-12-17 10:07:36 +01:00
Sem van der Hoeven
db7d944a41 [ADD] log 2020-12-17 10:04:43 +01:00
Sem van der Hoeven
3f132f48a7 [ADD] start of api calls 2020-12-16 12:11:48 +01:00
Sem van der Hoeven
17f624cc30 [ADD] longitude latitude doubles in location 2020-12-16 11:54:35 +01:00
Robin Koedood
4f68398f33 [ADD] route detail landscape mode 2020-12-16 11:38:24 +01:00
Robin Koedood
4229acf87c [ADD] Route Detail Contraints 2020-12-16 11:20:52 +01:00
Sem van der Hoeven
521c9fd188 Merge branch 'RecyclerView' into develop 2020-12-16 11:20:41 +01:00
Sem van der Hoeven
1fd245f4f0 [ADD] all methods from daos to repos 2020-12-16 11:04:06 +01:00
Sem van der Hoeven
8d210a9707 [ADD] image url to location 2020-12-16 10:58:44 +01:00
RemoMeijer
ee1ae23e0f Merge branch 'develop' into RecyclerView 2020-12-16 10:56:36 +01:00
Sem van der Hoeven
49f78efdd3 [ADD] update and insert coupon 2020-12-16 10:56:03 +01:00
Sem van der Hoeven
512ad3980f [FIX] mapview stuff 2020-12-16 10:48:11 +01:00
RemoMeijer
e2f76c94f7 Merge branch 'develop' into RecyclerView
# Conflicts: resolved
#	app/src/main/res/layout/fragment_location.xml
#	app/src/main/res/layout/fragment_location_detail.xml
2020-12-16 10:43:46 +01:00
Sem van der Hoeven
2479563474 Merge branch 'data' into develop 2020-12-14 15:10:09 +01:00
Sem van der Hoeven
ea59b97f0f merge fragment 2020-12-14 15:09:59 +01:00
Sem van der Hoeven
0b9bba63a3 added all daos 2020-12-14 15:07:53 +01:00
sebas
75b7ff47cd [Added] small changes to route detail, location detail 2020-12-14 14:51:43 +01:00
sebas
a2d1ecfc71 [Added] layout created for routedetailfragment 2020-12-14 14:38:47 +01:00
Sem van der Hoeven
890a5264d6 added initmapview 2020-12-14 14:37:50 +01:00
Sem van der Hoeven
2792a62069 merge conflicts 2020-12-14 14:36:52 +01:00
Sem van der Hoeven
b3be078361 added mapview and osm map 2020-12-14 14:35:53 +01:00
RemoMeijer
148e84483a Added mapView 2020-12-14 14:35:24 +01:00
RemoMeijer
bf1c5d0ac4 Added fragment_location layout and location_item layout 2020-12-14 14:20:54 +01:00
Bipin
0092b2e839 fixie wixie 2020-12-14 14:08:40 +01:00
Bipin
9854f5f6ab finalize main activity (for now) 2020-12-14 14:07:08 +01:00
sebas
7c200bf780 [Added] Created route_item layout and filled it, also filled fragment_route 2020-12-14 14:01:41 +01:00
RemoMeijer
b174778dbf Merge branch 'Fragment' of https://github.com/SemvdH/Next-Location into Fragment 2020-12-14 14:00:55 +01:00
RemoMeijer
d33237791b Added location detail, location_item 2020-12-14 14:00:15 +01:00
Robin Koedood
c6a9b175cc [ADD] coupon landscape mode 2020-12-14 13:59:13 +01:00
Robin Koedood
d4d3e8d19f [ADD] forgot one string 2020-12-14 13:58:01 +01:00
Robin Koedood
8aa316fc97 [ADD] String values 2020-12-14 13:55:13 +01:00
Robin Koedood
ed6d80b399 [ADD] Imagebutton 2020-12-14 13:50:46 +01:00
Bipin
dc69d9a2ad Merge branch 'Fragment' of https://github.com/SemvdH/Next-Location into Fragment 2020-12-14 13:41:36 +01:00
Bipin
83796481e8 back button image added 2020-12-14 13:41:23 +01:00
Robin Koedood
14d9cf686f Merge remote-tracking branch 'origin/Fragment' into Fragment 2020-12-14 13:40:53 +01:00
Robin Koedood
49ec448e56 [FIXED] offset 2020-12-14 13:40:48 +01:00
Bart
996b061b65 Merge branch 'bottomNavigation' into develop 2020-12-14 13:36:18 +01:00
Bipin
64f76f46c0 Added top bar 2020-12-14 13:35:16 +01:00
Sem van der Hoeven
8fdb88f71a data dao 2020-12-14 13:16:03 +01:00
Bipin
8c25197967 Merge branch 'Fragment' of https://github.com/SemvdH/Next-Location into Fragment 2020-12-14 13:13:55 +01:00
Bipin
180f7fc051 fixed icon in navbar 2020-12-14 13:13:36 +01:00
Robin Koedood
9622d3d068 [ADD] Coupons fragments, changed box height 2020-12-14 12:33:28 +01:00
Robin Koedood
a2365d1c19 [ADD] Statistieken en settings fragments 2020-12-14 12:20:51 +01:00
Sem van der Hoeven
6b97c21a8b added ignores to fields that dont need to be in the database 2020-12-14 12:16:39 +01:00
Sem van der Hoeven
23d23bead4 added location dao and repository 2020-12-14 12:13:15 +01:00
Robin Koedood
297067fcb2 Merge remote-tracking branch 'origin/Fragment' into Fragment 2020-12-14 12:06:38 +01:00
Robin Koedood
19ae360ee0 [ADD] Settings fragment 2020-12-14 12:06:25 +01:00
RemoMeijer
16b9b15856 Added some functionality 2020-12-14 12:05:32 +01:00
Sem van der Hoeven
204d45cece added packages for dao and repository 2020-12-14 12:03:47 +01:00
Sem van der Hoeven
08215e18c5 added database and coupon and route daos 2020-12-14 12:00:01 +01:00
sebas
63c49c40d7 [change] Small change to adapter classes 2020-12-14 11:39:29 +01:00
sebas
13b73fb0de [Added] created method for CouponListManager 2020-12-14 11:21:43 +01:00
sebas
e5fa7db27d [Added] Added some functionallity to the adapters (not finished yet due to missing functionallity from other classes) 2020-12-14 11:19:39 +01:00
Sem van der Hoeven
c4fd44ad76 added room dependency 2020-12-14 11:19:11 +01:00
Sem van der Hoeven
3e9e41c118 Merge branch 'data' of https://github.com/SemvdH/Next-Location into data 2020-12-14 11:17:28 +01:00
Sem van der Hoeven
64c8b0591a [ADD] constructors 2020-12-14 11:16:40 +01:00
sebas
aee2797a0f [Added] methods to CouponAdapter 2020-12-14 11:10:51 +01:00
RemoMeijer
12b446b679 Implemented all Methods and interfaces 2020-12-14 11:09:00 +01:00
Bart
8f8303d66a Merge remote-tracking branch 'origin/data' into data 2020-12-14 11:04:53 +01:00
Bart
a2ffef1099 [ADD] data & location class fields and getters / setters 2020-12-14 11:04:31 +01:00
Sem van der Hoeven
dec62e8b9a [ADD] coupon class fields and getters / setters 2020-12-14 10:56:49 +01:00
Sem van der Hoeven
fac41e2ade [ADD] route class fields and getters / setters 2020-12-14 10:55:39 +01:00
131 changed files with 4983 additions and 139 deletions

View File

@@ -26,14 +26,21 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
repositories {
maven { url "https://jitpack.io" }
}
}
dependencies {
//gson
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
testImplementation 'junit:junit:4.13.1'
// okhttp
@@ -43,6 +50,17 @@ dependencies {
//osm
implementation 'org.osmdroid:osmdroid-android:6.1.8'
//osm bonus pack
implementation 'com.github.MKergall:osmbonuspack:6.6.0'
//BeforeEach
testImplementation(platform('org.junit:junit-bom:5.7.0'))
testImplementation 'org.junit.jupiter:junit-jupiter'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
testImplementation 'org.mockito:mockito-core:2.7.22'
androidTestImplementation 'com.21buttons:fragment-test-rule:2.0.1'
androidTestImplementation 'androidx.test:rules:1.3.0-beta01'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0-alpha02'
}

View File

@@ -0,0 +1,50 @@
package com.a1.nextlocation;
import androidx.test.espresso.Root;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.espresso.matcher.RootMatchers;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.rule.ActivityTestRule;
import com.a1.nextlocation.fragments.CouponFragment;
import com.a1.nextlocation.fragments.LocationFragment;
import org.junit.Rule;
import org.junit.Test;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isChecked;
import static androidx.test.espresso.matcher.ViewMatchers.isClickable;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
public class CouponFragmentTest {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void clickBackButton() throws Exception{
//Here we click the back button and then we check if the statisticsFragment is shown
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new CouponFragment()).commit();
onView(withId(R.id.coupon_back_button)).perform(click());
onView(withId(R.id.statisticsFragment)).check(matches(isDisplayed()));
}
@Test
public void clickDetailButton() throws Exception{
//Here we click a coupon and then a popup dialog shows, we press the "activeren" button in it and if the next dialog with the code and with
//the button "Klaar" is shown then the test works
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new CouponFragment()).commit();
onView(withId(R.id.coupon_recyclerview)).perform(RecyclerViewActions.actionOnItemAtPosition(1, click()));
onView(withText("activeren")).inRoot(RootMatchers.isDialog()).perform(click());
onView(withText("Klaar")).inRoot(RootMatchers.isDialog()).check(matches(isDisplayed()));
}
}

View File

@@ -0,0 +1,27 @@
package com.a1.nextlocation;
import androidx.test.rule.ActivityTestRule;
import com.a1.nextlocation.fragments.CouponFragment;
import org.junit.Rule;
import org.junit.Test;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
public class LocationDetailFragment {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void clickBackButton() throws Exception{
//Here we click the back button and then we check if the locationFragment is shown
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new com.a1.nextlocation.fragments.LocationDetailFragment()).commit();
onView(withId(R.id.detail_location_back_button)).perform(click());
onView(withId(R.id.locationFragment)).check(matches(isDisplayed()));
}
}

View File

@@ -0,0 +1,42 @@
package com.a1.nextlocation;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.rule.ActivityTestRule;
import com.a1.nextlocation.fragments.LocationFragment;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.inject.Inject;
import static androidx.test.espresso.Espresso.*;
import static androidx.test.espresso.action.ViewActions.*;
import static androidx.test.espresso.assertion.ViewAssertions.*;
import static androidx.test.espresso.matcher.ViewMatchers.*;
public class LocationFragmentTest {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void clickBackButton() throws Exception{
//Here we click the back button and then we check if the homeFragment is shown
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new LocationFragment()).commit();
onView(withId(R.id.location_back_button)).perform(click());
onView(withId(R.id.homeFragment)).check(matches(isDisplayed()));
}
@Test
public void clickDetailButton() throws Exception{
//Here we click an item in the recyclerview and then check if the routeDetailFragment is called
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new LocationFragment()).commit();
onView(withId(R.id.location_recyclerview)).perform(RecyclerViewActions.actionOnItemAtPosition(1, click()));
onView(withId(R.id.locationDetailFragment)).check(matches(isDisplayed()));
}
}

View File

@@ -0,0 +1,64 @@
package com.a1.nextlocation;
import android.app.LauncherActivity;
import android.widget.Button;
import androidx.test.espresso.contrib.NavigationViewActions;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.espresso.matcher.RootMatchers;
import androidx.test.rule.ActivityTestRule;
import com.a1.nextlocation.fragments.CouponFragment;
import com.google.android.material.bottomnavigation.BottomNavigationItemView;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
public class MainActivityTest {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void clickLocationsNavBar() throws Exception{
//Here we click the back button and then we check if the statisticsFragment is shown
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().commit();
onView(withId(R.id.locations)).perform(click());
onView(withId(R.id.homeFragment)).check(matches(isDisplayed()));
}
@Test
public void clickRouteNavBar() throws Exception{
//Here we click the back button and then we check if the statisticsFragment is shown
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().commit();
onView(withId(R.id.routes)).perform((click()));
onView(withId(R.id.routeFragment)).check(matches(isDisplayed()));
}
@Test
public void clickStatisticsNavBar() throws Exception{
//Here we click the back button and then we check if the statisticsFragment is shown
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().commit();
onView(withId(R.id.statistics)).perform(click());
onView(withId(R.id.statisticsFragment)).check(matches(isDisplayed()));
}
@Test
public void clickSettingNavBar() throws Exception{
//Here we click the back button and then we check if the statisticsFragment is shown
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().commit();
onView(withId(R.id.settings)).perform(click());
onView(withId(R.id.settingFragment)).check(matches(isDisplayed()));
}
}

View File

@@ -0,0 +1,39 @@
package com.a1.nextlocation;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.rule.ActivityTestRule;
import com.a1.nextlocation.fragments.LocationFragment;
import com.a1.nextlocation.fragments.RouteFragment;
import org.junit.Rule;
import org.junit.Test;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
public class RouteFragmentTest {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void clickBackButton() throws Exception{
//Here we click the back button and then we check if the homeFragment is shown
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new RouteFragment()).commit();
onView(withId(R.id.route_back_button)).perform(click());
onView(withId(R.id.homeFragment)).check(matches(isDisplayed()));
}
@Test
public void clickDetailButton() throws Exception{
//Here we click an item in the recyclerview and then check if the routeDetailFragment is called
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new RouteFragment()).commit();
onView(withId(R.id.route_recyclerview)).perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
onView(withId(R.id.routeDetailFragment)).check(matches(isDisplayed()));
}
}

View File

@@ -0,0 +1,70 @@
package com.a1.nextlocation;
import androidx.test.espresso.action.ViewActions;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.espresso.matcher.RootMatchers;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.rule.ActivityTestRule;
import com.a1.nextlocation.fragments.LocationFragment;
import com.a1.nextlocation.fragments.SettingsFragment;
import com.a1.nextlocation.fragments.StatisticFragment;
import org.hamcrest.core.AllOf;
import org.hamcrest.core.Is;
import org.hamcrest.core.IsInstanceOf;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.inject.Inject;
import static androidx.test.espresso.Espresso.*;
import static androidx.test.espresso.action.ViewActions.*;
import static androidx.test.espresso.assertion.ViewAssertions.*;
import static androidx.test.espresso.matcher.RootMatchers.isPlatformPopup;
import static androidx.test.espresso.matcher.ViewMatchers.*;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.is;
public class SettingsFragmentTest {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
//Tests if the back button sends you back home
@Test
public void clickBackButton() throws Exception{
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new SettingsFragment()).commit();
onView(withId(R.id.settings_back_button)).perform(click());
onView(withId(R.id.homeFragment)).check(matches(isDisplayed()));
}
//Checks if the dropdown is clickable, and checks if it has children
@Test
public void dropdownTest(){
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new SettingsFragment()).commit();
onView(withId(R.id.dropdown_menu_Settings)).check(matches(isClickable()));
onView(withId(R.id.dropdown_menu_Settings)).check(matches(hasMinimumChildCount(1)));
}
//Tests if all buttons are clickable, and if they get checked after being clicked.
@Test
public void buttonTest(){
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new SettingsFragment()).commit();
onView(withId(R.id.settingsImperialButton)).check(matches(isClickable()));
onView(withId(R.id.settingsOldButton)).check(matches(isClickable()));
onView(withId(R.id.settingsEyesButton)).check(matches(isClickable()));
onView(withId(R.id.settingsImperialButton)).perform(click());
onView(withId(R.id.settingsImperialButton)).check(matches(isChecked()));
onView(withId(R.id.settingsOldButton)).perform(click());
onView(withId(R.id.settingsOldButton)).check(matches(isChecked()));
onView(withId(R.id.settingsEyesButton)).perform(click());
onView(withId(R.id.settingsEyesButton)).check(matches(isChecked()));
}
}

View File

@@ -0,0 +1,38 @@
package com.a1.nextlocation;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.rule.ActivityTestRule;
import com.a1.nextlocation.fragments.LocationFragment;
import com.a1.nextlocation.fragments.StatisticFragment;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.inject.Inject;
import static androidx.test.espresso.Espresso.*;
import static androidx.test.espresso.action.ViewActions.*;
import static androidx.test.espresso.assertion.ViewAssertions.*;
import static androidx.test.espresso.matcher.ViewMatchers.*;
public class StatisticFragmentTest {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
//Tests to see if all boxes get created
@Test
public void checkText() throws Exception{
mActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainActivity, new StatisticFragment()).commit();
onView(withId(R.id.textView)).check(matches(isDisplayed()));
onView(withId(R.id.name_box)).check(matches(isDisplayed()));
onView(withId(R.id.Box2)).check(matches(isDisplayed()));
onView(withId(R.id.Box3)).check(matches(isDisplayed()));
onView(withId(R.id.Box4)).check(matches(isDisplayed()));
}
}

View File

@@ -2,16 +2,21 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.a1.nextlocation">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:icon="@drawable/next_location_icon"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:roundIcon="@drawable/next_location_icon"
android:supportsRtl="true"
android:theme="@style/Theme.NextLocation">
android:theme="@style/Theme.NextLocation"
android:hardwareAccelerated="false">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@@ -0,0 +1,10 @@
[
{
"code": "KROKET10",
"reward": "Gratis 2e kroket bij Kees Kroket™"
},
{
"code": "654",
"reward": ",juygly"
}
]

View File

@@ -0,0 +1,135 @@
[
{
"name":"McDonald's Breda Karnemelkstraat",
"coordinates":"51.586062613842245, 4.77579695141302",
"description":"Wist je dat McDonalds de grootste restaurantketen ter wereld is? Hierdoor hebben we een indrukwekkende geschiedenis. Maar wij kijken liever naar onze toekomst. Nieuwe restaurants, betere producten en duurzaam ondernemen. Wil je meer weten over McDonalds? Lees verder op: https://www.mcdonalds.com/nl/nl-nl/over-ons.html!",
"imageUrl":"mc_donalds"
},
{
"name":"Subway Karnemelkstraat 10 A, 1",
"coordinates":"51.58604142340411, 4.7751359436675545",
"description":"Subway is een Amerikaanse multinationale fastfoodketen die voornamelijk sandwiches verkoopt. Het bedrijf onderscheidt zich van veel andere broodjeszaken doordat de klant zelf de sandwich kan laten samenstellen. Subway werkt met franchisenemers. Het bedrijf heeft bijna 45.000 vestigingen in alle werelddelen.",
"imageUrl":"subway"
},
{
"name":"Wok To Go Halstraat 40",
"coordinates":"51.586464146477574, 4.777606887874218",
"description":"Bij Wok To Go houden we van snelle, gezonde en smaakvolle maaltijden. Sinds 2003 ontwikkelen onze chef-koks de lekkerste wokgerechten met verse ingrediënten. We doen dit vól overgave onder het motto “Making people happy through food”. Door het roerbakken met een kleine hoeveelheid olie op grote hitte, blijven de smaak en gezonde voedingsstoffen bewaard. We kiezen voor gezonde en unieke ingrediënten en bereiden uitgebalanceerde gerechten in een Wokki box voor een gezonde levensstijl.",
"imageUrl":"wok_to_go"
},
{
"name":"De Boterhal Grote Markt 19",
"coordinates":"51.58798747205394, 4.776265846483903",
"description":"De Boterhal in Breda is een internationaal tapasrestaurant, speciaalbiercafé en wijnbar. Men kan gezellig bij ons lunchen, borrelen en dineren. Wij hebben een uitgebreide menukaart met een hele hoop bieren, wijnen, zowel per glas als per fles te verkrijgen, lunch en tapasgerechtjes. Naast het eten wat wij serveren hebben we ook een hoop bieren en wijnen. Naast de bieren op de kaart hebben wij wisselende bieren; vijf ketelbieren en vijf seizoensbieren.",
"imageUrl":"de_boter_hal"
},
{
"name":"Gauchos Grote Markt 33",
"coordinates":"51.588449106286255, 4.77604936398091",
"description":"De middeleeuwse Grote Markt is een historische plek in het Bourgondische hart van Breda, ooit in handen van de Spaanse bezetter. Gauchos Grill-Restaurant combineert daar Brabantse gemoedelijkheid met professionele gastvrijheid. In onze Latijnse keuken bereiden wij op uw aanwijzing een malse Argentijnse steak of een smakelijk visgerecht van de grill.",
"imageUrl":"gauchos"
},
{
"name":"The Tosti Club Breda A4, Vlaszak 2",
"coordinates":"51.588922458012384, 4.7804923888638",
"description":"Je kunt bij al onze vestigingen de hele dag terecht, want bij The Tosti Club eet je het klokje rond. Dus kom gezellig ontbijten, lunchen of voor een snelle hap aan het einde van de dag (wat dacht je van onze The Tosti Slice, onze variant op pizza!). Even geen zin in brood? Dan kunnen we je ook verblijden met onder andere acaï smoothiebowls, pancakes, granolas / yoghurt of gewoon een lekkere warme drank met gebak. Mogen we je de Red Velvet fudge cake aanraden?",
"imageUrl":"the_tosti_club"
},
{
"name":"Coffee & Lunch 4 you Oude Vest 31",
"coordinates":"51.587223367256605, 4.779547820326475",
"description":"Welkom bij Coffee & Lunch 4 you! Onze sfeervolle lunchroom is gelegen in het centrum van Breda, in de directe nabijheid van de parkeergarage en de fietsenstalling.",
"imageUrl":"coffee_and_lunch"
},
{
"name":"t Zusje Breda Vismarktstraat 28",
"coordinates":"51.589820093624986, 4.773333478675191",
"description":"Dat is een avond bij t Zusje. Gezellig samenzijn in een huiselijke sfeer en genieten van onze kleine gerechtjes, die je de hele avond kunt bestellen. Bij t Zusje ben je thuis: jij bepaalt zelf de invulling van de avond.\nWe horen graag wat je wensen zijn, vinden het leuk je te verrassen met bijzondere gerechtjes en zetten graag die extra stap. We bieden je een avond uit, zoals wij die zelf ook graag zien. Avondvullend Bourgondisch genieten? In het prachtige pand van ons Zusje in Breda beleef je een gezellige avond met avondvullend tapas eten voor 31,80.\nBel snel en reserveer!",
"imageUrl":"t_zusje_breda"
},
{
"name":"VR-World Nassaustraat 2",
"coordinates":"51.5915020518371, 4.786101713659277",
"description":"Virtual Reality is hét uitje van dit moment. Zombies verslaan, vuurballen schieten of met laserzwaarden vechten, met Virtual Reality is niks te gek. Bij VR World zijn we elke dag opzoek naar de nieuwste experiences voor jullie.\n\nWat dacht je bijvoorbeeld van een Escape Room, maar dan in Virtual Reality? Bij VR World bieden wij de nieuwste Escapes aan op het gebied van Virtual Reality. Ontsnap bijvoorbeeld uit een Piramide of ontmantel een raket. Durf jij deze uitdaging aan?\n\nVR World is gelegen op een unieke locatie, namelijk de koepelgevangenis van Breda. Deze gevangenis was tot 2016 nog in werking en daarna hebben bedrijven er hun intrek genomen, zo ook VR World.",
"imageUrl":"vr_world"
},
{
"name":"Kees Kroket Houtmarkt 9",
"coordinates":"51.58628401688983, 4.776977039420005",
"description":"KEEEEES KROKET! Al meer dan tien jaar is Kees Kroket in het centrum van Breda gevestigd, vlakbij het winkelend publiek. Eerst in de welbekende Houtmarktpassage en sinds april 2019 zijn we gevestigd op onze nieuwe locatie aan de Houtmarkt 9. U proeft de kwaliteit bij onze verse frites. Deze, uit de Agria aardappel gesneden frites, wordt in zonnebloemolie voorgebakken en in een mix van plantaardige oliën afgebakken. Dit zorgt niet alleen voor de heerlijke smaak maar ook dat onze frites relatief weinig verzadigde vetten en transvetzuren bevat, waardoor we van het beeldmerk Verantwoord Frituren gebruik mogen maken.",
"imageUrl":"kees_kroket"
},
{
"name":"Prison Escape Kloosterlaan 168",
"coordinates":"51.59062116889821, 4.784611234825872",
"description":"Prison Escape duurt in het totaal 3 uur en je hebt als doel om te ontsnappen uit de zwaarbewaakte gevangenis. Een cast van 25 acteurs brengt de ervaring tot leven en het is aan jou om een weg naar buiten te vinden. In de gevangenis zijn verschillende objecten verstopt die het wellicht makkelijker zouden kunnen maken om de weg naar buiten te realiseren.\n\nWees op je hoede, kijk goed om je heen, vertrouw (bijna) niemand en stap op mensen af..\nDe klok tikt en jij hebt 1 doel: de weg naar de vrijheid vinden.",
"imageUrl":"prison_escape_room"
},
{
"name":"De Koepel - FutureDome Events Nassausingel 26",
"coordinates":"51.59010624820322, 4.788301630342321",
"description":"n groepen word je onder begeleiding van een van onze gidsen rondgeleid langs de meest unieke en mooiste monumentale plekken in en rondom de Koepel!\n\u200B\n\nDe gids zal hierbij op de verschillende locaties toelichting geven over het roemruchte verleden. De rondleiding over het gevangenisterrein brengt u onder andere langs de koepel, de authentieke kapel, vrouwengevangenis, verschillende luchtplaatsen en het oude gerechtsgebouw.",
"imageUrl":"de_koepel_future_events"
},
{
"name":"Escaping Breda: Escape Room Games Boschstraat 114",
"coordinates":"51.59096347875923, 4.783722665161644",
"description":"Escaping Breda is een nieuwe moderne locatie en heeft op dit moment 2 avontuurlijke escape rooms. Daarnaast komen er volgend jaar nog 2 extra escape rooms bij. \n\nOntsnap uit de spannende escape room Lets Rob The Bank, een kamer geschikt voor volwassenen én kinderen. Ontsnap je liever uit een escape room met een hoger spannings- en spelniveau? Kies dan voor Patient X.\n\nOp onze locatie in Breda hebben we ook een gezellig boardgame café. Combineer je ontsnapping met een drankje, hapje en alle gratis boardgames.\n\nEscaping Breda is de perfecte plek voor een uitje met je familie, vrienden of collegas.",
"imageUrl":"escaping_room"
},
{
"name":"MEZZ Breda Keizerstraat 101",
"coordinates":"51.58361639477683, 4.778550518987883",
"description":"MEZZ is een open club, betrokken, nieuwsgierig en onderzoekend. MEZZ heeft humor, is gevat, soms provocatief en verrassend. Beleving en plezier staan centraal waarbij wij bottom up denken. Wij zijn er voor jou, jouw MEZZ. Heb je ideeën of wil je meer weten, neem contact op. Wij reageren altijd.",
"imageUrl":"mezz_breda"
},
{
"name":"Het Klooster Breda Schorsmolenstraat 13",
"coordinates":"51.587727575660196, 4.7649956643240525",
"description":"In dit oude Kapucijnenklooster wordt een woon- en werkgemeenschap gevestigd onder de naam\n”Het Klooster Breda”. \nMet de inkomsten uit bedrijvigheid wordt 12 mensen die dakloos zijn onderdak geboden, van waaruit zij zich weer een plek in de samenleving kunnen verwerven.",
"imageUrl":"het_klooster_breda"
},
{
"name":"Beach & Lounge club Spider “rooftop bar” Nieuwe Prinsenkade",
"coordinates":"51.59138317151629, 4.771525073666575",
"description":"Beach & Lounge Club Spider staat bekent om zijn immens populaire locatie in Bergen op Zoom. Sinds 2020 heeft deze hoog segment lounge club een tweede locatie geopend in Breda genaamd Beach & Lounge Club Spider Rooftop Bar.",
"imageUrl":"beach_and_lounge_club"
},
{
"name":"Koningin Wilhelmina Paviljoen, Kraanstraat 4b, Breda",
"coordinates":"51.590380346954696, 4.775770191566508",
"description":"Koningin Wilhelmina Paviljoen is een bouwwerk in Breda Centrum in Breda. Het behoort tot de Koninklijke Militaire Academie (KMA) en bezit de status van rijksmonument. Het staat aan het Kasteelplein 15, vlak voor het Kasteel van Breda. Het ligt met de voorgevel aan de westkant van de oprijlaan van het kasteel, met de lange rechterzijgevel aan de kasteelgracht en de lange linkerzijgevel aan de Cingelstraat.",
"imageUrl":"koningin_wilhelimna_paviljoen"
},
{
"name":"Hercules en de Nemeïsche leeuw",
"coordinates":"51.591204052421965, 4.777900596046037",
"description":"Het beeld toont Hercules met de huid van de Nemeïsche leeuw. Herakles of Hercules is een figuur uit de Griekse mythologie. Hij was een Griekse heros en werd beroemd om de 12 moeilijke werken die hij uitvoerde in opdracht van koning Eurystheus. Het beeld maakt onderdeel uit van 17 anderen zandstenen beelden die Willem III tussen 1670 en 1686 kocht. De beelden stonden verdeeld over grasperken in het Valkenberg park.\nHercules is het enige originele beeld dat overgebleven is.",
"imageUrl":"hercules_park_valkenburg"
},
{
"name":"Nassau-Baroniemonument - 1905 - Pierre Cuypers Delpratsingel 1",
"coordinates":"51.592530636759136,4.780278353833301",
"description":"Het Baroniemonument of Nassau-Baroniemonument is een beeld van de Nederlandse architect Pierre Cuypers. Het staat in het Park Valkenberg in Breda. Het monument werd geplaatst ter herinnering aan de 500-jarige band (1904) tussen Breda en het huis Oranje-Nassau. In 1404 werd Engelbrecht I van Nassau-Siegen gehuldigd als heer van Breda.",
"imageUrl":"nassau_baroniemonument"
},
{
"name":"Station Breda Gravinnen van Nassauboulevard 43",
"coordinates":"51.5924883160154, 4.779744240625213",
"description":"Station Breda is het centrale spoorwegstation van de Nederlandse stad Breda. Het bevindt zich ten noorden van het centrum van de stad. Omliggende wijken zijn Stationskwartier en Drie Hoefijzers aan de zuidkant, en aan de noordzijde Belcrum, Doornbos-Linie en Havenkwartier.\n\nHet eerste station in Breda werd geopend op 1 mei 1855, toen de Spoorlijn Roosendaal - Breda werd geopend. Dit station werd in 1863 door een nieuw gebouw vervangen, toen de lijn naar Tilburg werd geopend. Omdat Breda toen nog een vesting was en het station onder de beperkingen van de Vestingwet viel, was het zodanig uitgevoerd dat het in tijden van oorlog snel gesloopt zou kunnen worden.",
"imageUrl":"station_breda"
},
{
"name":"Belcrum Beach Veilingkade 12a",
"coordinates":"51.59960126665085, 4.765433657156298",
"description":"Belcrum Beach is HET stadsstrand van Breda, gelegen op het Haveneiland in de wijk Belcrum. Wij zijn begonnen in 2013 op deze unieke lokatie in Breda. Het strand werkt met drie beheerders en een groot aantal vrijwilligers voor bar, onderhoud, programmering, sponsoring en tuin. Een plek om te relaxen met een drankje en een hapje, genietend van de zon, gezellig kletsen met je vrienden, luisterend naar muziek van een band of DJ, soms in een festival setting. Kinderen die kunnen spelen in het zand of mee kunnen doen aan speciale kinderactiviteiten. Belcrum Beach is ook een unieke lokatie voor een feestje of om je verjaardag te vieren, trouwen op het strand of een trouwfeest behoren ook tot de mogelijkheden.",
"imageUrl":"belcrum_beach"
},
{
"name":"De Belcrum Watertoren (1935) Speelhuislaan 158",
"coordinates":"51.60051284129074, 4.7689723624007",
"description":"De watertoren in de Belcrum in Breda is een industrieel monument uit het interbellum. De toren is de thuisbasis voor SOAB adviseurs voor woning en leefomgeving en onderstreept de missie van ons bureau. De toren hoort bij de Belcrum. Als landmark en als onderdak voor activiteiten. Zo vierden de Belcrummers hun 400 jaar bestaan in de toren en worden lunches met rondleiding op hoog niveau georganiseerd. Kijken en proeven.",
"imageUrl":"belcrum_watertoren"
}
]

View File

@@ -0,0 +1,76 @@
[
{
"name": "rondje stad",
"locations": [
{
"name":"Escaping Breda: Escape Room Games Boschstraat 114",
"coordinates":"51.59096518753322, 4.783727736123234",
"description":"4811GK Breda",
"imageUrl":"NULL"
},
{
"name":"Prison Escape Kloosterlaan 168",
"coordinates":"51.59058740778487, 4.784723144974098",
"description":"4811EE Breda",
"imageUrl":"NULL"
},
{
"name":"De Koepel - FutureDome Events Nassausingel 26",
"coordinates":"51.59025697138579, 4.787354025225596",
"description":"4811HP Breda",
"imageUrl":"NULL"
},
{
"name":"MEZZ Breda Keizerstraat 101",
"coordinates":"51.5837840024532, 4.779037836841554",
"description":"4811HL Breda",
"imageUrl":"NULL"
},
{
"name":"Het Klooster Breda Schorsmolenstraat 13",
"coordinates":"51.58765659148822, 4.764801414019652",
"description":"4811VN Breda",
"imageUrl":"NULL"
}
],
"totalDistance": 1073.0,
"totalTime": 342342
},
{
"name": "Obesi Route",
"locations": [
{
"name": "McDonald's Breda Karnemelkstraat",
"coordinates": "51.586062613842245, 4.777606887874218",
"description": "Wist je dat McDonalds de grootste restaurantketen ter wereld is? Hierdoor hebben we een indrukwekkende geschiedenis. Maar wij kijken liever naar onze toekomst. Nieuwe restaurants, betere producten en duurzaam ondernemen. Wil je meer weten over McDonalds? Lees verder op: https://www.mcdonalds.com/nl/nl-nl/over-ons.html!"
},
{
"name": "Kees Kroket Houtmarkt 9",
"coordinates": "51.58628401688983, 4.77579695141302",
"description": "lekkere patatjes"
},
{
"name": "Wok To Go Halstraat 40",
"coordinates": "51.586464146477574, 4.777606887874218",
"description": "Bij Wok To Go houden we van snelle, gezonde en smaakvolle maaltijden. Sinds 2003 ontwikkelen onze chef-koks de lekkerste wokgerechten met verse ingrediënten. We doen dit vól overgave onder het motto “Making people happy through food”. Door het roerbakken met een kleine hoeveelheid olie op grote hitte, blijven de smaak en gezonde voedingsstoffen bewaard. We kiezen voor gezonde en unieke ingrediënten en bereiden uitgebalanceerde gerechten in een Wokki box voor een gezonde levensstijl."
},
{
"name": "The Tosti Club Breda A4, Vlaszak 2",
"coordinates": "51.588922458012384, 4.7804923888638",
"description": "Je kunt bij al onze vestigingen de hele dag terecht, want bij The Tosti Club eet je het klokje rond. Dus kom gezellig ontbijten, lunchen of voor een snelle hap aan het einde van de dag (wat dacht je van onze The Tosti Slice, onze variant op pizza!). Even geen zin in brood? Dan kunnen we je ook verblijden met onder andere acaï smoothiebowls, pancakes, granolas / yoghurt of gewoon een lekkere warme drank met gebak. Mogen we je de Red Velvet fudge cake aanraden?"
},
{
"name": "Gauchos Grote Markt 33",
"coordinates": "51.588449106286255, 4.77604936398091",
"description": "De middeleeuwse Grote Markt is een historische plek in het Bourgondische hart van Breda, ooit in handen van de Spaanse bezetter. Gauchos Grill-Restaurant combineert daar Brabantse gemoedelijkheid met professionele gastvrijheid. In onze Latijnse keuken bereiden wij op uw aanwijzing een malse Argentijnse steak of een smakelijk visgerecht van de grill."
},
{
"name": "De Boterhal Grote Markt 19",
"coordinates": "51.58798747205394, 4.776265846483903",
"description": "De Boterhal in Breda is een internationaal tapasrestaurant, speciaalbiercafé en wijnbar. Men kan gezellig bij ons lunchen, borrelen en dineren. Wij hebben een uitgebreide menukaart met een hele hoop bieren, wijnen, zowel per glas als per fles te verkrijgen, lunch en tapasgerechtjes. Naast het eten wat wij serveren hebben we ook een hoop bieren en wijnen. Naast de bieren op de kaart hebben wij wisselende bieren; vijf ketelbieren en vijf seizoensbieren."
}
],
"totalDistance": 955.0,
"totalTime": 342342
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -1,21 +1,29 @@
package com.a1.nextlocation;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.MenuItem;
import com.a1.nextlocation.R;
import com.a1.nextlocation.fragments.HomeFragment;
import com.a1.nextlocation.fragments.Refreshable;
import com.a1.nextlocation.fragments.RouteFragment;
import com.a1.nextlocation.fragments.SettingsFragment;
import com.a1.nextlocation.fragments.StatisticFragment;
import com.a1.nextlocation.recyclerview.CouponListManager;
import com.a1.nextlocation.recyclerview.LocationListManager;
import com.a1.nextlocation.recyclerview.RouteListManager;
import com.google.android.material.bottomnavigation.BottomNavigationView;
public class MainActivity extends AppCompatActivity {
import java.util.Locale;
public class MainActivity extends AppCompatActivity implements Refreshable {
private static final String TAG = MainActivity.class.getName();
private BottomNavigationView bottomNav;
/**
* onCreate method that creates the main activity
* @param savedInstanceState the saved instance state of the app
@@ -23,13 +31,51 @@ public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNav = findViewById(R.id.navbar);
// initialize saved language from sharedPreferences
setLocale(loadLocale());
setContentView(R.layout.activity_main);
bottomNav = findViewById(R.id.navigation_bar);
bottomNav.setOnNavigationItemSelectedListener(navListener);
/*System.out.println(Arrays.toString(getFilesDir().listFiles()));
FileIO<Route> fileIO = new FileIO<>();
fileIO.writeFileData(new Route("TERSTSET"), getApplicationContext());
Log.d(TAG, "onCreate: " + "FILE GESCHREVENN!!!!!");*/
LocationListManager.INSTANCE.setContext(this);
LocationListManager.INSTANCE.load();
CouponListManager.INSTANCE.setContext(this);
CouponListManager.INSTANCE.load();
RouteListManager.INSTANCE.setContext(this);
RouteListManager.INSTANCE.load();
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, new HomeFragment()).commit();
}
}
/**
* loads the saved language from SharedPreferences
* @return the language as string
*/
private String loadLocale(){
SharedPreferences sharedPreferences = getSharedPreferences("Settings", Activity.MODE_PRIVATE);
return sharedPreferences.getString("Language", "nl");
}
/**
* sets the language of the application to the desired one
* @param language the desired language
*/
private void setLocale(String language){
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = new Configuration();
configuration.setLocale(locale);
getBaseContext().getResources().updateConfiguration(configuration, getBaseContext().getResources().getDisplayMetrics());
}
private BottomNavigationView.OnNavigationItemSelectedListener navListener = item -> {
@@ -53,4 +99,14 @@ public class MainActivity extends AppCompatActivity {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, selectedFragment).commit();
return true;
};
/**
* refreshes bottom navigation
*/
@Override
public void refresh() {
bottomNav.getMenu().clear();
bottomNav.inflateMenu(R.menu.navmenu);
bottomNav.setSelectedItemId(R.id.settings);
}
}

View File

@@ -1,4 +1,42 @@
package com.a1.nextlocation.data;
import androidx.annotation.NonNull;
import org.jetbrains.annotations.NotNull;
public class Coupon {
/**
* fields need to be public for the database to be able to use them
*/
@NonNull
private String code;
@NonNull
private String reward;
public Coupon(@NonNull String code, @NotNull String reward) {
this.code = code;
this.reward = reward;
}
@NonNull
public String getCode() {
return code;
}
@NonNull
public String getReward() {
return reward;
}
public void setCode(@NonNull String code) {
this.code = code;
}
public void setReward(@NonNull String reward) {
this.reward = reward;
}
}

View File

@@ -1,4 +1,88 @@
package com.a1.nextlocation.data;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
public class Data {
private float distanceTraveled;
private int locationsVisited;
private int totalTime;
private List<Coupon> couponList;
private Location nextLocation;
private Location lastLocation;
private Route currentRoute;
public Data() {
this.distanceTraveled = 0;
this.locationsVisited = 0;
this.totalTime = 0;
couponList = new ArrayList<>();
}
public float getDistanceTraveled() {
return distanceTraveled;
}
public void setDistanceTraveled(float distanceTraveled) {
this.distanceTraveled = distanceTraveled;
}
public int getLocationsVisited() {
return locationsVisited;
}
public void setLocationsVisited(int locationsVisited) {
this.locationsVisited = locationsVisited;
}
public int getTotalTime() {
return totalTime;
}
public void setTotalTime(int totalTime) {
this.totalTime = totalTime;
}
public List<Coupon> getCouponList() {
return couponList;
}
public void setCouponList(List<Coupon> couponList) {
this.couponList = couponList;
}
public Location getNextLocation() {
return nextLocation;
}
public void setNextLocation(Location nextLocation) {
this.nextLocation = nextLocation;
}
public Location getLastLocation() {
return lastLocation;
}
public void setLastLocation(Location lastLocation) {
this.lastLocation = lastLocation;
}
public Route getCurrentRoute() {
return currentRoute;
}
public void setCurrentRoute(Route currentRoute) {
this.currentRoute = currentRoute;
}
}

View File

@@ -1,4 +1,103 @@
package com.a1.nextlocation.data;
public class FileIO {
import android.content.Context;
import android.content.res.AssetManager;
import android.os.Environment;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONArray;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
public class FileIO<T> {
private final String TAG = FileIO.class.getCanonicalName();
public T readFileData(Context context, String fileName, Type typeOf) {
Gson gson = new Gson();
AssetManager am = context.getAssets();
T res = null;
StringBuilder sb = new StringBuilder();
try {
InputStream is = am.open(fileName);
InputStreamReader inputStreamReader = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(inputStreamReader);
String line;
while ((line = reader.readLine())!= null) {
sb.append(line);
}
Log.d(TAG, "readFileData: got string: " + sb.toString());
res = gson.fromJson(sb.toString(),typeOf);
Log.d(TAG, "readFileData: got object: " + res);
reader.close();
inputStreamReader.close();
is.close();
} catch (IOException e) {
Log.d(TAG, "readFileData: exception! " + e.getLocalizedMessage());
e.printStackTrace();
}
return res;
}
// public void writeFileData(T objectToWrite, Context context) {
// //TODO make
// //object naar jsonobject
// //jsonarray toevoegen/maken
// //filewriter naar file
//
// String filename = "";
// if (objectToWrite instanceof Coupon){
// filename = "coupons.json";
// }
//
// if (objectToWrite instanceof Route){
// filename = "routes.json";
// }
//
// if (objectToWrite instanceof Location){
// filename = "locations.json";
// }
//
// try (FileOutputStream fileOutputStream = context.openFileOutput(filename, Context.MODE_PRIVATE)){
// String json = new Gson().toJson(objectToWrite);
//
// fileOutputStream.write(json.getBytes(StandardCharsets.UTF_8));
//
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }
//
// /*try (FileWriter fileWriter = new FileWriter(filename)){
//
// String json = new Gson().toJson(objectToWrite);
//
// fileWriter.append(json);
// fileWriter.flush();
//
// } catch (IOException e) {
// e.printStackTrace();
// }*/
// }
}

View File

@@ -1,4 +1,168 @@
package com.a1.nextlocation.data;
public class Location {
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.osmdroid.util.GeoPoint;
public class Location implements Parcelable {
@NonNull
private String name;
/**
* coordinates will be saved as for example: 2.434343,4.65656;3.656565,6.43434
* so lat1,long1;lat2,long2
*/
private String coordinates;
private String description;
@Nullable
private String imageUrl;
public Location(@NotNull String name, String coordinates, String description, @Nullable String imageUrl) {
this.name = name;
this.coordinates = coordinates;
this.description = description;
this.imageUrl = imageUrl;
}
public Location(@NotNull String name, double latCoord, double longCoord, String description, @Nullable String imageUrl) {
this(name,getStringFromCoordinates(latCoord,longCoord),description,imageUrl);
}
public Location(String name, android.location.Location loc, String description, String imageUrl) {
this(name,getStringFromCoordinates(loc.getLatitude(),loc.getLongitude()),description,imageUrl);
}
protected Location(Parcel in) {
name = in.readString();
coordinates = in.readString();
description = in.readString();
imageUrl = in.readString();
}
public static final Creator<Location> CREATOR = new Creator<Location>() {
@Override
public Location createFromParcel(Parcel in) {
return new Location(in);
}
@Override
public Location[] newArray(int size) {
return new Location[size];
}
};
@NotNull
public String getName() {
return name;
}
public void setName(@NotNull String name) {
this.name = name;
}
public String getCoordinates() {
return coordinates;
}
public void setCoordinates(String coordinates) {
this.coordinates = coordinates;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Nullable
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(@Nullable String imageUrl) {
this.imageUrl = imageUrl;
}
public double[] getCoordinatesAsDoubles() {
double[] res = new double[2];
res[1] = getLat();
res[0] = getLong();
return res;
}
public double getLat() {
return Double.parseDouble(this.coordinates.split(",")[0]);
}
public double getLong() {
return Double.parseDouble(this.coordinates.split(",")[1]);
}
public static String getStringFromCoordinates(double lat1, double long1) {
return long1 + "," + lat1;
}
/**
* calculates the distance between two coordinates
* @param lat1 the first latitude
* @param lon1 the first longitude
* @param lat2 the second latitude
* @param lon2 the second longitude
* @return the distance between the coordinates in meters
*/
public static double getDistance(double lat1, double lon1, double lat2, double lon2) {
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
lon1 = Math.toRadians(lon1);
lon2 = Math.toRadians(lon2);
double dlon = lon2 - lon1;
double dlat = lat2 - lat1;
double a = Math.pow(Math.sin(dlat / 2), 2)
+ Math.cos(lat1) * Math.cos(lat2)
* Math.pow(Math.sin(dlon / 2),2);
double c = 2 * Math.asin(Math.sqrt(a));
// Radius of earth in kilometers. Use 3956
// for miles
// if(miles) {
// double r = 3956;
// }
// else {
double r = 6371;
// }
// calculate the result
double distance = c * r;
distance *= 1000;
return Math.floor(distance);
}
public GeoPoint convertToGeoPoint() {
return new GeoPoint(this.getLat(),this.getLong());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeString(coordinates);
parcel.writeString(description);
parcel.writeString(imageUrl);
}
}

View File

@@ -1,4 +1,106 @@
package com.a1.nextlocation.data;
public class Route {
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class Route implements Parcelable {
@NonNull
private String name;
private String description;
private List<Location> locations;
private float totalDistance;
private int totalTime;
public Route(@NotNull String name) {
this.name = name;
this.locations = new ArrayList<>();
}
protected Route(Parcel in) {
this.name = in.readString();
this.locations = in.createTypedArrayList(Location.CREATOR);
this.totalDistance = in.readFloat();
this.totalTime = in.readInt();
}
public static final Creator<Route> CREATOR = new Creator<Route>() {
@Override
public Route createFromParcel(Parcel in) {
return new Route(in);
}
@Override
public Route[] newArray(int size) {
return new Route[size];
}
};
public void addLocation(Location location) {
this.locations.add(location);
}
@NotNull
public String getName() {
return name;
}
public void setName(@NotNull String name) {
this.name = name;
}
public List<Location> getLocations() {
return locations;
}
public void setLocations(List<Location> locations) {
this.locations = locations;
}
public float getTotalDistance() {
return totalDistance;
}
public int getTotalTime() {
//TODO calculate total time according to all locations in list
return totalTime;
}
public void setTotalDistance(float totalDistance) {
this.totalDistance = totalDistance;
}
public void setTotalTime(int totalTime) {
this.totalTime = totalTime;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeTypedList(locations);
parcel.writeFloat(totalDistance);
parcel.writeInt(totalTime);
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@@ -0,0 +1,80 @@
package com.a1.nextlocation.data;
import org.osmdroid.views.overlay.Polyline;
/**
* singleton to track the current route that is being followed
*/
public enum RouteHandler {
INSTANCE;
private boolean isFollowingRoute = false;
private Route currentRoute;
private int stepCount = 0;
private RouteFinishedListener routeFinishedListener;
private long startedTime;
private Polyline currentRouteLine;
public void setCurrentRouteLine(Polyline currentRouteLine) {
this.currentRouteLine = currentRouteLine;
}
public Polyline getCurrentRouteLine() {
return currentRouteLine;
}
public void setRouteFinishedListener(RouteFinishedListener routeFinishedListener) {
this.routeFinishedListener = routeFinishedListener;
}
public RouteFinishedListener getRouteFinishedListener() {
return routeFinishedListener;
}
public int getStepCount() {
return stepCount;
}
public void addStep() {
stepCount++;
}
public void finishRoute() {
stepCount = 0;
isFollowingRoute = false;
currentRoute = null;
currentRouteLine = null;
StaticData.INSTANCE.addTimeWalked(System.currentTimeMillis()-startedTime);
startedTime = 0;
}
public void followRoute(Route route) {
if (isFollowingRoute) {
StaticData.INSTANCE.addTimeWalked(System.currentTimeMillis()-startedTime);
}
this.currentRoute = route;
setFollowingRoute(true);
startedTime = System.currentTimeMillis();
}
public boolean isFollowingRoute(Route route) {
return isFollowingRoute && route.equals(currentRoute);
}
public void setFollowingRoute(boolean followingRoute) {
isFollowingRoute = followingRoute;
}
public boolean isFollowingRoute() {
return isFollowingRoute;
}
public Route getCurrentRoute() {
return currentRoute;
}
@FunctionalInterface
public interface RouteFinishedListener {
void onRouteFinish();
}
}

View File

@@ -0,0 +1,55 @@
package com.a1.nextlocation.data;
import java.util.ArrayList;
/**
* singleton to keep track of different global data
*/
public enum StaticData {
INSTANCE;
private double distanceTraveled = 0;
private int locationsVisited = 0;
private long timeWalked = 0;
private double zoom = 0;
public double getZoom() {
return zoom;
}
public void setZoom(double zoom) {
this.zoom = zoom;
}
private ArrayList<String> visitedNames = new ArrayList<>();
public void addDistance(double d) {
distanceTraveled += d;
}
public long getTimeWalked() {
return timeWalked;
}
public void addTimeWalked(long time) {
timeWalked += time;
}
public double getDistanceTraveled() {
return distanceTraveled;
}
public void visitLocation(Location location) {
if (!visitedNames.contains(location.getName())) {
locationsVisited++;
visitedNames.add(location.getName());
}
}
public int getLocationsVisited() {
return locationsVisited;
}
}

View File

@@ -1,26 +1,80 @@
package com.a1.nextlocation.fragments;
import android.app.AlertDialog;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Coupon;
import com.a1.nextlocation.recyclerview.CouponAdapter;
import com.a1.nextlocation.recyclerview.CouponListManager;
import java.util.List;
public class CouponFragment extends Fragment {
private RecyclerView couponRecyclerView;
private RecyclerView.LayoutManager layoutManager;
private List<Coupon> couponList;
private CouponAdapter couponAdapter;
private ImageButton imageButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_coupon, container, false);
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_coupon, container, false);
this.couponRecyclerView = view.findViewById(R.id.coupon_recyclerview);
this.couponRecyclerView.setHasFixedSize(true);
this.layoutManager = new LinearLayoutManager(this.getContext());
CouponListManager.INSTANCE.setContext(this.getContext());
CouponListManager.INSTANCE.load();
this.couponList = CouponListManager.INSTANCE.getCouponList();
this.couponAdapter = new CouponAdapter(this.getContext(), this.couponList, clickedPosition -> showPopup(this.couponList.get(clickedPosition)));
this.imageButton = view.findViewById(R.id.coupon_back_button);
this.imageButton.setOnClickListener(v -> {
StatisticFragment statisticFragment = new StatisticFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, statisticFragment).addToBackStack(null).commit();
});
this.couponRecyclerView.setLayoutManager(this.layoutManager);
this.couponRecyclerView.setAdapter(this.couponAdapter);
return view;
}
private void showPopup(Coupon coupon) {
AlertDialog.Builder activateBuilder = new AlertDialog.Builder(getContext());
AlertDialog.Builder couponCodeBuilder = new AlertDialog.Builder(getContext());
activateBuilder.setMessage(getResources().getString(R.string.activate_question));
activateBuilder.setCancelable(true);
activateBuilder.setPositiveButton(R.string.activate, (dialog, which) -> {
dialog.cancel();
couponCodeBuilder.setMessage("Code: " + coupon.getCode());
couponCodeBuilder.setPositiveButton(R.string.done, (dialog1, which1) -> {
dialog.cancel();
});
AlertDialog couponCodePopup = couponCodeBuilder.create();
couponCodePopup.show();
});
activateBuilder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.cancel());
AlertDialog couponPopup = activateBuilder.create();
couponPopup.show();
}
}

View File

@@ -1,27 +1,406 @@
package com.a1.nextlocation.fragments;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.RouteHandler;
import com.a1.nextlocation.data.StaticData;
import com.a1.nextlocation.json.DirectionsResult;
import com.a1.nextlocation.network.ApiHandler;
import com.a1.nextlocation.network.DirectionsListener;
import com.a1.nextlocation.recyclerview.LocationListManager;
public class HomeFragment extends Fragment {
import org.osmdroid.api.IMapController;
import org.osmdroid.config.Configuration;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.CustomZoomButtonsController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.Polyline;
import org.osmdroid.views.overlay.compass.CompassOverlay;
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
import java.util.ArrayList;
import java.util.List;
public class HomeFragment extends Fragment implements LocationListener {
private final String userAgent = "com.ai.nextlocation.fragments";
private ImageButton imageButton;
private ImageButton stopButton;
private MapView mapView;
private final int REQUEST_PERMISSIONS_REQUEST_CODE = 1;
private final String TAG = HomeFragment.class.getCanonicalName();
private Polyline roadOverlay;
private int color;
private Location currentLocation;
private Overlay allLocationsOverlay;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestPermissionsIfNecessary(
// if you need to show the current location request FINE_LOCATION permission
Manifest.permission.ACCESS_FINE_LOCATION,
// WRITE_EXTERNAL_STORAGE is required in order to show the map
Manifest.permission.WRITE_EXTERNAL_STORAGE);
color = requireContext().getColor(R.color.red);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false);
View view = inflater.inflate(R.layout.fragment_home, container, false);
// set up the location list button
this.imageButton = view.findViewById(R.id.location_list_button);
this.imageButton.setOnClickListener(v -> {
LocationFragment locationFragment = new LocationFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, locationFragment).addToBackStack(null).commit();
});
// set up the route stop button
stopButton = view.findViewById(R.id.home_stop_route_button);
stopButton.setOnClickListener(v -> {
stopRoute();
});
// show or hide the stop route button based on if we are following a route
if (RouteHandler.INSTANCE.isFollowingRoute()) {
stopButton.setVisibility(View.VISIBLE);
} else {
stopButton.setVisibility(View.GONE);
}
//register as a listener for a result of the API
ApiHandler.INSTANCE.addListener(this::onDirectionsAvailable);
return view;
}
/**
* stops the current route
*/
private void stopRoute() {
Log.d(TAG, "stopRoute: STOPPING ROUTE" );
RouteHandler.INSTANCE.finishRoute();
stopButton.setVisibility(View.GONE);
Toast.makeText(requireContext(), getResources().getString(R.string.route_stop_toast), Toast.LENGTH_SHORT).show();
mapView.getOverlays().remove(roadOverlay);
mapView.getOverlays().remove(allLocationsOverlay);
addLocations();
mapView.invalidate();
roadOverlay = null;
}
/**
* callback method that gets called when there are new directions available in the form of a {@link DirectionsResult} object.
*
* @param directionsResult the directions received from the api
*/
private void onDirectionsAvailable(DirectionsResult directionsResult) {
Log.d(TAG, "onDirectionsAvailable: got result! " + directionsResult);
ArrayList<GeoPoint> geoPoints = directionsResult.getGeoPoints();
roadOverlay = new Polyline();
roadOverlay.setPoints(geoPoints);
roadOverlay.setColor(color);
// pass the line to the route handler
RouteHandler.INSTANCE.setCurrentRouteLine(roadOverlay);
Log.d(TAG, "onDirectionsAvailable: successfully added road!");
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initMap(view);
}
/**
* This method initializes the map and all the things it needs
*
* @param view the view the map is on
*/
private void initMap(@NonNull View view) {
// set the user agent
Configuration.getInstance().setUserAgentValue(userAgent);
// create the map view
mapView = view.findViewById(R.id.map_view);
mapView.setDestroyMode(false);
mapView.setTag("mapView");
mapView.setMultiTouchControls(true);
// get the location provider
GpsMyLocationProvider gpsMyLocationProvider = new GpsMyLocationProvider(this.requireContext());
// add the compass overlay
CompassOverlay compassOverlay = new CompassOverlay(requireContext(), new InternalCompassOrientationProvider(requireContext()), mapView);
compassOverlay.enableCompass();
mapView.getOverlays().add(compassOverlay);
addLocations();
// add the location overlay
MyLocationNewOverlay mLocationOverlay = new MyLocationNewOverlay(gpsMyLocationProvider, mapView);
mLocationOverlay.enableFollowLocation();
mLocationOverlay.enableMyLocation();
mapView.getOverlays().add(mLocationOverlay);
// add the zoom controller
IMapController mapController = mapView.getController();
if (StaticData.INSTANCE.getZoom() == 0) {
StaticData.INSTANCE.setZoom(15.0);
}
mapController.setZoom(StaticData.INSTANCE.getZoom());
// add location manager and set the start point
LocationManager locationManager = (LocationManager) requireActivity().getSystemService(Context.LOCATION_SERVICE);
try {
// request location updates for the distance checking
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
// get the current location and set it as center
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (currentLocation == null) currentLocation = location;
if (location != null) {
GeoPoint start = new GeoPoint(location.getLatitude(), location.getLongitude());
mapController.setCenter(start);
}
} catch (SecurityException e) {
Log.d(TAG, "onViewCreated: exception while getting location: " + e.getLocalizedMessage());
requestPermissionsIfNecessary(
// if you need to show the current location request FINE_LOCATION permission
Manifest.permission.ACCESS_FINE_LOCATION,
// WRITE_EXTERNAL_STORAGE is required in order to show the map
Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
displayRoute();
}
/**
* displays the route that is currently being followed as a red line
*/
private void displayRoute() {
if (RouteHandler.INSTANCE.isFollowingRoute()) {
Log.d(TAG, "displayRoute: WE ARE FOLLOWING A ROUTE");
if (roadOverlay == null) {
if (RouteHandler.INSTANCE.getCurrentRouteLine() != null) {
roadOverlay = RouteHandler.INSTANCE.getCurrentRouteLine();
mapView.getOverlays().add(roadOverlay);
mapView.invalidate();
Log.d(TAG, "initMap: successfully added road!");
}
} else {
mapView.getOverlays().add(roadOverlay);
mapView.invalidate();
Log.d(TAG, "initMap: successfully added road!");
}
}
}
/**
* adds the locations of the current route to the map. If there is no current route, show all locations
*/
private void addLocations() {
// get the locations of the current route or all locations
List<com.a1.nextlocation.data.Location> locations = RouteHandler.INSTANCE.isFollowingRoute() ? RouteHandler.INSTANCE.getCurrentRoute().getLocations() : LocationListManager.INSTANCE.getLocationList();
final ArrayList<OverlayItem> items = new ArrayList<>(locations.size());
// marker icon
Drawable marker = ContextCompat.getDrawable(requireContext(), R.drawable.ic_baseline_location_on_24);
marker.setAlpha(255);
marker.setTint(getResources().getColor(R.color.primaryColour));
// add all locations to the overlay itemss
for (com.a1.nextlocation.data.Location location : locations) {
OverlayItem item = new OverlayItem(location.getName(), location.getDescription(), location.convertToGeoPoint());
item.setMarker(marker);
items.add(item);
}
// create the overlay that will hold all locations and add listeners
allLocationsOverlay = new ItemizedIconOverlay<OverlayItem>(items,
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
/**
* on sinlge click, navigate to that location's detail fragment
* @param index the index in the location list
* @param item the item that was clicked
* @return true
*/
@Override
public boolean onItemSingleTapUp(int index, OverlayItem item) {
com.a1.nextlocation.data.Location clicked = locations.get(index);
requireActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, new LocationDetailFragment(clicked)).commit();
return true;
}
/**
* on item long press, show that location's name in a toast message
* @param index the index in the location list
* @param item the item that was clicked
* @return true
*/
@Override
public boolean onItemLongPress(int index, OverlayItem item) {
com.a1.nextlocation.data.Location clicked = locations.get(index);
Toast.makeText(requireContext(), clicked.getName(), Toast.LENGTH_SHORT).show();
// create a route to the clicked location, didn't work and didn't have enough time to make it work ¯\_(ツ)_/¯
// Route route = new Route("Route to " + clicked.getName());
// route.addLocation(new com.a1.nextlocation.data.Location("Current location",currentLocation.getLatitude(),currentLocation.getLongitude(),"your location",null));
// route.addLocation(clicked);
// ApiHandler.INSTANCE.getDirections(route);
return true;
}
}, requireContext());
// add the overlay to the map
mapView.getOverlays().add(allLocationsOverlay);
Log.d(TAG, "addLocations: successfully added locations");
}
/**
* @param permissions tbe permissions we want to ask
* @author Ricky
* request the permissions needed for location and network, made by Ricky
*/
private void requestPermissionsIfNecessary(String... permissions) {
ArrayList<String> permissionsToRequest = new ArrayList<>();
if (this.getContext() != null)
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this.getContext(), permission)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
permissionsToRequest.add(permission);
}
}
if (permissionsToRequest.size() > 0 && this.getActivity() != null) {
ActivityCompat.requestPermissions(
this.getActivity(),
permissionsToRequest.toArray(new String[0]),
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
/**
* location callback that gets called each time the location is updated. It is used for updating the distance walked and checking if there are locations you have visited
*
* @param location the new location
*/
@Override
public void onLocationChanged(@NonNull Location location) {
// calculate the distance walked
if (currentLocation != null) {
double distance = currentLocation.distanceTo(location); // in meters
// can't walk 100 meters in a few seconds
if (distance < 100)
StaticData.INSTANCE.addDistance(distance);
}
currentLocation = location;
//new thread because we don't want the main thread to hang, this method gets called a lot
Thread t = new Thread(() -> {
com.a1.nextlocation.data.Location last = null;
if (RouteHandler.INSTANCE.isFollowingRoute()) {
List<com.a1.nextlocation.data.Location> locs = RouteHandler.INSTANCE.getCurrentRoute().getLocations();
last = locs.get(locs.size()-1);
}
for (com.a1.nextlocation.data.Location l : LocationListManager.INSTANCE.getLocationList()) {
// mark the location visited if we are less than 20 meters away
if (com.a1.nextlocation.data.Location.getDistance(currentLocation.getLatitude(), currentLocation.getLongitude(), l.getLat(), l.getLong()) < 20) {
StaticData.INSTANCE.visitLocation(l);
if (l.equals(last)) stopRoute();
}
}
StaticData.INSTANCE.setZoom(mapView.getZoomLevelDouble());
});
t.start();
}
// empty override methods for the LocationListener
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(@NonNull String provider) {
}
@Override
public void onProviderDisabled(@NonNull String provider) {
}
/**
* method that gets called when the app gets paused
*/
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
/**
* method that gets called when the app gets resumed
*/
@Override
public void onResume() {
super.onResume();
mapView.onResume();
}
}

View File

@@ -1,27 +1,75 @@
package com.a1.nextlocation.fragments;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Location;
public class LocationDetailFragment extends Fragment {
private static final String TAG = LocationDetailFragment.class.getCanonicalName();
private ImageButton imageButton;
private Location location;
private TextView titelText;
private TextView detailText;
private ImageView locationImage;
public LocationDetailFragment() {
}
public LocationDetailFragment(Location location) {
this.location = location;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_location_detail, container, false);
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_location_detail, container, false);
this.titelText = view.findViewById(R.id.detail_location_name);
this.titelText.setText(location.getName());
this.detailText = view.findViewById(R.id.detail_location_text);
this.detailText.setText(location.getDescription());
this.imageButton = view.findViewById(R.id.detail_location_back_button);
this.imageButton.setOnClickListener(v -> {
LocationFragment locationFragment = new LocationFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, locationFragment).addToBackStack(null).commit();
});
if (location != null) {
Log.d(TAG, "onCreateView: the location has a name of: " + location.getName());
}
this.locationImage = view.findViewById(R.id.detail_location_image);
Context context = this.locationImage.getContext();
int id = context.getResources().getIdentifier(this.location.getImageUrl(), "drawable", context.getPackageName());
this.locationImage.setImageResource(id);
return view;
}
public void setLocation(Location location) {
this.location = location;
}
}

View File

@@ -1,27 +1,68 @@
package com.a1.nextlocation.fragments;
import android.media.Image;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Location;
import com.a1.nextlocation.recyclerview.LocationAdapter;
import com.a1.nextlocation.recyclerview.LocationListManager;
import java.util.List;
public class LocationFragment extends Fragment {
private RecyclerView locationRecyclerView;
private LocationAdapter locationAdapter;
private RecyclerView.LayoutManager layoutManager;
private List<Location> locationList;
private ImageButton imageButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_location, container, false);
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_location, container, false);
this.locationRecyclerView = view.findViewById(R.id.location_recyclerview);
this.locationRecyclerView.setHasFixedSize(true);
this.layoutManager = new LinearLayoutManager(this.getContext());
this.imageButton = view.findViewById(R.id.location_back_button);
this.imageButton.setOnClickListener(v -> {
HomeFragment homeFragment = new HomeFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, homeFragment).addToBackStack(null).commit();
});
LocationListManager.INSTANCE.setContext(this.getContext());
LocationListManager.INSTANCE.load();
this.locationList = LocationListManager.INSTANCE.getLocationList();
this.locationAdapter = new LocationAdapter(this.getContext(), this.locationList, clickedPosition -> {
LocationDetailFragment locationDetailFragment = new LocationDetailFragment();
locationDetailFragment.setLocation(this.locationList.get(clickedPosition));
Bundle locationBundle = new Bundle();
locationBundle.putParcelable("location", this.locationList.get(clickedPosition));
locationDetailFragment.setLocation(this.locationList.get(clickedPosition));
locationDetailFragment.setArguments(locationBundle);
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, locationDetailFragment).addToBackStack(null).commit();
});
this.locationRecyclerView.setLayoutManager(this.layoutManager);
this.locationRecyclerView.setAdapter(this.locationAdapter);
return view;
}
}

View File

@@ -0,0 +1,5 @@
package com.a1.nextlocation.fragments;
public interface Refreshable {
void refresh();
}

View File

@@ -1,27 +1,104 @@
package com.a1.nextlocation.fragments;
import android.annotation.SuppressLint;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Location;
import com.a1.nextlocation.data.Route;
import com.a1.nextlocation.data.RouteHandler;
import com.a1.nextlocation.network.ApiHandler;
import java.util.ArrayList;
import java.util.List;
public class RouteDetailFragment extends Fragment {
private Route route;
private TextView routeDetailText;
private TextView routeName;
private TextView totalDistance;
private ImageButton imageButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@SuppressLint("SetTextI18n")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_route_detail, container, false);
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_route_detail, container, false);
if(getArguments().getParcelable("route") != null) {
this.route = getArguments().getParcelable("route");
}
this.routeName = view.findViewById(R.id.route_title);
this.routeName.setText(this.route.getName());
this.routeDetailText = view.findViewById(R.id.reoute_detail_tekst);
this.routeDetailText.setText(this.route.getDescription());
this.totalDistance = view.findViewById(R.id.total_distance);
String distance_tekst = getResources().getString(R.string.total_distance_route);
this.totalDistance.setText(distance_tekst + " " + calculateRoute(this.route.getLocations()) + "m");
this.imageButton = view.findViewById(R.id.route_detail_back_button);
this.imageButton.setOnClickListener(v -> {
RouteFragment routeFragment = new RouteFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, routeFragment).addToBackStack(null).commit();
});
Button startButton = view.findViewById(R.id.start_route_button);
startButton.setOnClickListener(this::startRoute);
return view;
}
/**
* Button onclick method that starts the route that is being viewed.
* @param view the button
*/
public void startRoute(View view) {
ApiHandler.INSTANCE.getDirections(route);
RouteHandler.INSTANCE.followRoute(route);
Toast.makeText(requireContext(),"Route started!",Toast.LENGTH_SHORT).show();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, new HomeFragment()).addToBackStack(null).commit();
}
/**
* Calculates the distance between points
* @param route the route that is calculated
* @return the total distance of a route
*/
public double calculateRoute(List<Location> route){
ArrayList<Location> routeArraylist = new ArrayList<>(route);
double totalDistance = 0;
Location firstLocation;
Location secondLocation;
System.out.println("Total locations: " + routeArraylist.size());
//Cycles through the arraylist
for(int i = 0; i < routeArraylist.size() - 1; i++) {
firstLocation = routeArraylist.get(i);
secondLocation = routeArraylist.get(i+1);
System.out.println("locations distance calculated: " + (i+1) + " and " + (i+2) + "\nThe added distance is: " + Location.getDistance(firstLocation.getLat(), firstLocation.getLong(), secondLocation.getLat(), secondLocation.getLong()));
//Calculates the distance between points
totalDistance += Location.getDistance(firstLocation.getLat(), firstLocation.getLong(), secondLocation.getLat(), secondLocation.getLong());
}
System.out.println("Total Distance: " + totalDistance);
return totalDistance;
}
}

View File

@@ -2,15 +2,39 @@ package com.a1.nextlocation.fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Route;
import com.a1.nextlocation.recyclerview.RouteAdapter;
import com.a1.nextlocation.recyclerview.RouteListManager;
import java.util.List;
import com.a1.nextlocation.data.Location;
import com.a1.nextlocation.data.Route;
import com.a1.nextlocation.json.DirectionsResult;
import com.a1.nextlocation.network.ApiHandler;
import com.a1.nextlocation.network.DirectionsListener;
public class RouteFragment extends Fragment {
private static final String TAG = RouteFragment.class.getCanonicalName();
private RecyclerView routeRecyclerView;
private RecyclerView.LayoutManager layoutManager;
private List<Route> routeList;
private RouteAdapter routeAdapter;
private ImageButton imageButton;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -19,9 +43,50 @@ public class RouteFragment extends Fragment {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_route, container, false);
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_route, container, false);
this.routeRecyclerView = view.findViewById(R.id.route_recyclerview);
this.routeRecyclerView.setHasFixedSize(true);
this.layoutManager = new LinearLayoutManager(this.getContext());
RouteListManager.INSTANCE.setContext(this.getContext());
RouteListManager.INSTANCE.load();
this.routeList = RouteListManager.INSTANCE.getRouteList();
this.routeAdapter = new RouteAdapter(this.getContext(), this.routeList, clickedPosition -> {
RouteDetailFragment routeDetailFragment = new RouteDetailFragment();
Bundle routeBundle = new Bundle();
routeBundle.putParcelable("route", this.routeList.get(clickedPosition));
routeDetailFragment.setArguments(routeBundle);
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, routeDetailFragment).addToBackStack(null).commit();
});
this.imageButton = view.findViewById(R.id.route_back_button);
this.imageButton.setOnClickListener(v -> {
HomeFragment homeFragment = new HomeFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, homeFragment).addToBackStack(null).commit();
});
this.routeRecyclerView.setLayoutManager(this.layoutManager);
this.routeRecyclerView.setAdapter(this.routeAdapter);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// ApiHandler.INSTANCE.getDirections(51.49017262451581, 4.289038164073164,51.47337383133509, 4.303535222390562);
// Route r = new Route("test");
// r.addLocation(new Location("test",51.574473766034046, 4.7628379328055175,"route",null));
// r.addLocation(new Location("test",51.577354223919876, 4.771120593941968,"route",null));
// r.addLocation(new Location("test",51.573033468635174, 4.782750651807139,"route",null));
// r.addLocation(new Location("test",51.56519104881196, 4.748246716295709,"route",null));
// r.addLocation(new Location("test",51.57367360644676, 4.74404101271347,"route",null));
// r.addLocation(new Location("test",51.57852769146427, 4.739878224473907,"route",null));
//// r.addLocation(new Location("test",51.489063681658145, 4.289596063527951,"route",null));
//// r.addLocation(new Location("test",51.483012677667766, 4.28003245468457,"route",null));
// ApiHandler.INSTANCE.getDirections(r);
}
}

View File

@@ -1,27 +1,178 @@
package com.a1.nextlocation.fragments;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import com.a1.nextlocation.R;
import org.jetbrains.annotations.NotNull;
import java.util.Locale;
public class SettingsFragment extends Fragment {
private SharedPreferences.Editor editor;
private ImageView imageButton;
SwitchCompat fontChanger;
private Refreshable refreshable;
@Override
public void onAttach(@NotNull Context context) {
super.onAttach(context);
refreshable = (Refreshable) context;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
editor = getContext().getSharedPreferences("Settings", Context.MODE_PRIVATE).edit();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_settings, container, false);
View view = inflater.inflate(R.layout.fragment_settings, container, false);
initializeLanguageDropdown(view);
this.imageButton = view.findViewById(R.id.settings_back_button);
this.imageButton.setOnClickListener(v -> {
HomeFragment homeFragment = new HomeFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, homeFragment).addToBackStack(null).commit();
});
fontChanger = view.findViewById(R.id.BigFont);
SharedPreferences sharedPreferences = requireActivity().getSharedPreferences("com.a1.nextlocation",0);
SharedPreferences.Editor editor = sharedPreferences.edit();
fontChanger.setChecked(sharedPreferences.getBoolean("switch", false));
if (fontChanger.isChecked()){
requireActivity().setTheme(R.style.Theme_NextLocationBig);
}else if (!fontChanger.isChecked()){
requireActivity().setTheme(R.style.Theme_NextLocation);
}
fontChanger.setOnClickListener(view1 -> {
if(fontChanger.isChecked())
{
requireActivity().setTheme(R.style.Theme_NextLocationBig);
editor.putBoolean("switch",true);
editor.apply();
}
if(!fontChanger.isChecked())
{
requireActivity().setTheme(R.style.Theme_NextLocation);
editor.putBoolean("switch",false);
editor.apply();
}
editor.commit();
});
return view;
}
private void initializeLanguageDropdown(View view) {
Spinner languageDropdown = view.findViewById(R.id.dropdown_menu_Settings);
String[] items = new String[]{getResources().getString(R.string.Dutch), getResources().getString(R.string.English), getResources().getString(R.string.Chinese)};
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_dropdown_item, items);
languageDropdown.setAdapter(arrayAdapter);
// set the language dropdown on the currently selected language stored in the sharedPreferences
languageDropdown.setSelection(languageToDropdownPosition(getContext().getSharedPreferences("Settings", Context.MODE_PRIVATE).getString("Language", "")));
long previousID = languageDropdown.getSelectedItemId();
languageDropdown.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
setLocale(dropdownPositionToLanguage(id));
// refresh fragment on language change
if (id != previousID) {
refresh();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
/**
* converts the languageDropdown position to the belonging language
*
* @param id desired position to convert
* @return the language belonging to the position of the languageDropdown
*/
private String dropdownPositionToLanguage(long id) {
switch ((int) id) {
case 0:
return "nl";
case 1:
return "en";
default:
return "";
}
}
/**
* converts language to the languageDropdown position
*
* @param language desired language to convert
* @return the position of the language in the languageDropdown
*/
private int languageToDropdownPosition(String language) {
switch (language) {
case "nl":
return 0;
case "en":
return 1;
default:
return 1;
}
}
/**
* reloads the fragment
*/
private void refresh() {
Fragment currentFragment = getActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_layout);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.detach(currentFragment);
fragmentTransaction.attach(currentFragment);
fragmentTransaction.commit();
refreshable.refresh();
}
/**
* changes the current language to the desired language and saves this setting in SharedPreferences
*
* @param language the desired language to translate to
*/
private void setLocale(String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.setLocale(locale);
getContext().getResources().updateConfiguration(config, getContext().getResources().getDisplayMetrics());
editor.putString("Language", language);
editor.apply();
}
}

View File

@@ -2,26 +2,78 @@ package com.a1.nextlocation.fragments;
import android.os.Bundle;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Coupon;
import com.a1.nextlocation.data.StaticData;
import com.a1.nextlocation.recyclerview.CouponAdapter;
import com.a1.nextlocation.recyclerview.CouponListManager;
import java.util.List;
public class StatisticFragment extends Fragment {
private List<Coupon> couponList;
private ImageView imageButton;
private ImageView couponButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_statistic, container, false);
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_statistic, container, false);
TextView distance = view.findViewById(R.id.statistics_km);
TextView locs = view.findViewById(R.id.statistics_locations_visited);
TextView timeText = view.findViewById(R.id.statistics_time_value);
double dist = StaticData.INSTANCE.getDistanceTraveled()/1000;
distance.setText("" + String.format("%.1f",dist) + " km");
locs.setText("" + StaticData.INSTANCE.getLocationsVisited());
long seconds = StaticData.INSTANCE.getTimeWalked() / 1000;
long p1 = seconds % 60;
long p2 = seconds / 60;
long p3 = p2 % 60;
p2 = p2 / 60;
timeText.setText(p2 + ":" + p3 + ":" + p1);
this.couponList = CouponListManager.INSTANCE.getCouponList();
CouponAdapter adapter = new CouponAdapter(this.getContext(), this.couponList);
TextView couponNumber = view.findViewById(R.id.couponAmount);
couponNumber.setText(String.valueOf(adapter.getItemCount()));
this.imageButton = view.findViewById(R.id.statistics_back_button);
this.imageButton.setOnClickListener(v -> {
HomeFragment homeFragment = new HomeFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, homeFragment).addToBackStack(null).commit();
});
this.couponButton = view.findViewById(R.id.coupon_button);
this.couponButton.setOnClickListener(v -> {
CouponFragment couponFragment = new CouponFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, couponFragment).addToBackStack(null).commit();
});
ConstraintLayout constraintLayout = view.findViewById(R.id.Box4);
constraintLayout.setOnClickListener(v -> {
CouponFragment couponFragment = new CouponFragment();
((FragmentActivity) view.getContext()).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, couponFragment).addToBackStack(null).commit();
});
return view;
}
}

View File

@@ -0,0 +1,191 @@
package com.a1.nextlocation.json;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import org.json.JSONArray;
import org.osmdroid.util.GeoPoint;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DirectionsResult {
private static final String TAG = DirectionsResult.class.getCanonicalName();
private List<DirectionsStep> steps = new ArrayList<>();
private double distance;
private double duration;
private double[][] wayPointCoordinates;
private GeoPoint[] startAndEndPoint = new GeoPoint[2];
public List<DirectionsStep> getSteps() {
return steps;
}
public void setSteps(List<DirectionsStep> steps) {
this.steps = steps;
}
public double getDistance() {
return distance;
}
public void setDistance(double distance) {
this.distance = distance;
}
public double getDuration() {
return duration;
}
public void setDuration(double duration) {
this.duration = duration;
}
public void addStep(DirectionsStep step) {
this.steps.add(step);
}
public GeoPoint[] getStartAndEndPoint() {
return startAndEndPoint;
}
/**
* converts all the geopoints in all the steps into an arraylist to display it on the map
* @return the list of geopoints
*/
public ArrayList<GeoPoint> getGeoPoints() {
int size = 0;
// we'll have a lot of waypoints, so calculate the size first so that the list won't have to be extended (o p t i m i z e)
for (int i = 0; i < this.getSteps().size(); i++) {
size += this.getSteps().get(i).getWaypoints().length;
}
ArrayList<GeoPoint> res = new ArrayList<>(size);
for (DirectionsStep step : this.getSteps()) {
Collections.addAll(res, step.getWaypoints());
}
return res;
}
/**
* parses a given json string into this object. It gets all the waypoints and steps and combines them so that every step also has the correct coordinates associated with it
*
* @param json the json string to parse.
*/
public void parse(String json) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonObject feature = JsonParser.parseString(json).getAsJsonObject().get("features").getAsJsonArray().get(0).getAsJsonObject();
JsonObject properties = feature.get("properties").getAsJsonObject();
JsonArray wayPointCoordinates = feature.get("geometry").getAsJsonObject().getAsJsonArray("coordinates");
this.wayPointCoordinates = new double[wayPointCoordinates.size()][2];
// fill the way point coordinates list for later use
for (int i = 0; i < wayPointCoordinates.size(); i++) {
JsonElement j = wayPointCoordinates.get(i);
JsonArray arr = j.getAsJsonArray();
this.wayPointCoordinates[i][0] = arr.get(0).getAsDouble();
this.wayPointCoordinates[i][1] = arr.get(1).getAsDouble();
}
JsonArray segments = properties.getAsJsonArray("segments");
parseSegments(segments,gson);
startAndEndPoint[0] = this.getSteps().get(0).getWaypoints()[0];
startAndEndPoint[1] = this.getSteps().get(this.getSteps().size()-1).getWaypoints()[1];
}
/**
* parses the given json string into this object. This method is used for when you have requested directions from the API for a {@link com.a1.nextlocation.data.Route route object}
* @param json the json string
*/
public void parseRoute(String json) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonArray routes = JsonParser.parseString(json).getAsJsonObject().getAsJsonArray("routes");
for (JsonElement element : routes) {
JsonObject route = element.getAsJsonObject();
JsonObject summary = route.getAsJsonObject("summary");
this.distance = summary.get("distance").getAsDouble();
this.duration = summary.get("duration").getAsDouble();
JsonPrimitive geometry = route.getAsJsonPrimitive("geometry");
JsonArray wayPointCoordinates = GeometryDecoder.decodeGeometry(geometry.getAsString(), false);
this.wayPointCoordinates = new double[wayPointCoordinates.size()][2];
// fill the way point coordinates list for later use
for (int i = 0; i < wayPointCoordinates.size(); i++) {
JsonElement j = wayPointCoordinates.get(i);
JsonArray arr = j.getAsJsonArray();
this.wayPointCoordinates[i][0] = arr.get(0).getAsDouble();
this.wayPointCoordinates[i][1] = arr.get(1).getAsDouble();
}
JsonArray segments = route.getAsJsonArray("segments");
parseSegments(segments,gson);
}
}
/**
* parses different segments, and the steps in it using {@link DirectionsResult#parseSteps(JsonArray, Gson) the method for parsing steps}
* @param segments the segments to parse
* @param gson the gson object to use
*/
private void parseSegments(JsonArray segments, Gson gson) {
//unfold the individual segments
for (JsonElement e : segments) {
JsonObject segment = e.getAsJsonObject();
setDistance(segment.get("distance").getAsDouble());
setDuration(segment.get("duration").getAsDouble());
JsonArray steps = segment.getAsJsonArray("steps");
parseSteps(steps,gson);
}
}
/**
* parses the given steps into this object, transforms them into a {@link DirectionsStep} object.
* @param steps the steps to parse
* @param gson the gson object to use
*/
private void parseSteps(JsonArray steps, Gson gson) {
for (JsonElement j : steps) {
// parse everything into a directionsstep
DirectionsStep step = gson.fromJson(j, DirectionsStep.class);
double lat;
double longl;
// kinda stinky but it works
for (int i = 0; i < 2; i++) {
lat = this.wayPointCoordinates[step.getWay_points().get(i)][0];
longl = this.wayPointCoordinates[step.getWay_points().get(i)][1];
step.getWaypoints()[i] = new GeoPoint(lat, longl);
}
addStep(step);
Log.d(TAG, "parse: added step" + step);
}
}
}

View File

@@ -0,0 +1,72 @@
package com.a1.nextlocation.json;
import org.osmdroid.util.GeoPoint;
import java.util.ArrayList;
/**
* pojo class that holds the step object from the api response
*/
public class DirectionsStep {
private double distance;
private double duration;
private String instruction;
private String name;
/**
* these are the actual waypoints that the step refers to. The first is the beginning of the step, and the second is what it leads to.
* The second geopoint is always the first geopoint of the next step in the list of the {@link DirectionsResult} object.
*/
private GeoPoint[] waypoints = new GeoPoint[2];
/**
* this is a list of the waypoints that are in the response, it is called way_points so it can be automatically serialized with gson
*/
private ArrayList<Integer> way_points;
public double getDistance() {
return distance;
}
public void setDistance(double distance) {
this.distance = distance;
}
public double getDuration() {
return duration;
}
public void setDuration(double duration) {
this.duration = duration;
}
public String getInstruction() {
return instruction;
}
public void setInstruction(String instruction) {
this.instruction = instruction;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Integer> getWay_points() {
return way_points;
}
public void setWay_points(ArrayList<Integer> way_points) {
this.way_points = way_points;
}
public GeoPoint[] getWaypoints() {
return waypoints;
}
public void setWaypoints(GeoPoint[] waypoints) {
this.waypoints = waypoints;
}
}

View File

@@ -0,0 +1,63 @@
package com.a1.nextlocation.json;
import com.google.gson.JsonArray;
import org.json.JSONArray;
import org.json.JSONException;
/**
* source: https://github.com/GIScience/openrouteservice-docs#geometry-decoding
*/
public class GeometryDecoder {
public static JsonArray decodeGeometry(String encodedGeometry, boolean inclElevation) {
JsonArray geometry = new JsonArray();
int len = encodedGeometry.length();
int index = 0;
int lat = 0;
int lng = 0;
int ele = 0;
while (index < len) {
int result = 1;
int shift = 0;
int b;
do {
b = encodedGeometry.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lat += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
result = 1;
shift = 0;
do {
b = encodedGeometry.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
if(inclElevation){
result = 1;
shift = 0;
do {
b = encodedGeometry.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
ele += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
}
JsonArray location = new JsonArray();
location.add(lat / 1E5);
location.add(lng / 1E5);
if(inclElevation){
location.add((float) (ele / 100));
}
geometry.add(location);
}
return geometry;
}
}

View File

@@ -0,0 +1,187 @@
package com.a1.nextlocation.network;
import android.util.Log;
import com.a1.nextlocation.data.Location;
import com.a1.nextlocation.data.Route;
import com.a1.nextlocation.json.DirectionsResult;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Singleton that handles all API calls
*/
public enum ApiHandler {
INSTANCE;
private static String TAG = ApiHandler.class.getCanonicalName();
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
private final String BASE_URL = "https://api.openrouteservice.org/v2/directions/";
private final String API_KEY = "5b3ce3597851110001cf6248d4eee2099f724255918adc71cc502b2a";
private final String DIRECTIONS_MODE = "foot-walking";
private List<DirectionsListener> listeners = new ArrayList<>();
private OkHttpClient client = new OkHttpClient();
/**
* gets directions from the start location to the end location
* @param startLocation the start location
* @param endLocation the end location
*/
public void getDirections(Location startLocation, Location endLocation) {
getDirections(startLocation.getCoordinates(),endLocation.getCoordinates());
}
/**
* gets directions from the start location latitude and longitude and the end location latitude and longitude
* @param startLat the start latitude
* @param startLong the start longitude
* @param endLat the end latitude
* @param endLong the end longitude
*/
public void getDirections(double startLat, double startLong, double endLat, double endLong) {
getDirections(startLong + "," + startLat, endLong + "," + endLat);
}
/**
* Gets the directions from the start location to the end location. An example location would be "3.543543,5.7675765"
* @param startLocation the start location represented as <i>startlat,startlong</i>
* @param endLocation the end location represented as <i>endlat,endlong</i>
*/
public void getDirections(String startLocation, String endLocation) {
// build the url
String requestUrl = BASE_URL + DIRECTIONS_MODE + "?api_key=" + API_KEY + "&start=" +startLocation + "&end=" + endLocation;
// start a new thread to do the request, because we don't want to be networking on our main thread
Thread t = new Thread(() -> {
// build a request from the url
Request request = new Request.Builder().url(requestUrl).build();
// try to get the response
try (Response response = client.newCall(request).execute()) {
if (response.body() != null) {
String responseString = Objects.requireNonNull(response.body()).string();
Log.d(TAG, "getDirections: got response: " + responseString);
// convert the response into a result object
DirectionsResult result = new DirectionsResult();
result.parse(responseString);
Log.d(TAG, "getDirections: " + result.getSteps().size());
// notify the listeners
for (DirectionsListener listener : listeners) {
listener.onDirectionsAvailable(result);
}
}
} catch (IOException e) {
Log.d(TAG, "getDirections: caught exception: " + e.getLocalizedMessage());
}
});
t.start();
// try {
// t.join();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
/**
* adds a listener for when a result of an api call is available
* @param listener the new listener
*/
public void addListener(DirectionsListener listener) {
this.listeners.add(listener);
}
/**
* gets directions for the given {@link Route}
* @param route the route to get directions for
*/
public void getDirections(Route route) {
// add the coordinates to the list
ArrayList<double[]> allCoords = new ArrayList<>();
for (Location location : route.getLocations()) {
allCoords.add(location.getCoordinatesAsDoubles());
}
// convert it to a json string
String body = "{\"coordinates\":" + new Gson().toJson(allCoords) + "}";
String requestUrl = BASE_URL + DIRECTIONS_MODE + "?api_key=" + API_KEY;
// new thread, because we don't want to be networking on our main thread
Thread t = new Thread(() -> {
// add the body to the request
RequestBody requestBody = RequestBody.create(body,JSON);
Request request = new Request.Builder()
.url(requestUrl)
.post(requestBody)
.build();
try (Response response = client.newCall(request).execute()) {
if (response.body() != null) {
String responseString = Objects.requireNonNull(response.body()).string();
Log.d(TAG, "getDirections: got response: " + responseString);
// kinda lazy, but we had time pressure
if (responseString.startsWith("{\"error")) {
Log.e(TAG, "getDirections: ERROR IN REQUEST!");
return;
}
// convert the result into a DirectionsResult
DirectionsResult result = new DirectionsResult();
result.parseRoute(responseString);
Log.d(TAG, "getDirections: " + result.getSteps().size());
//notify the listeners
for (DirectionsListener listener : listeners) {
listener.onDirectionsAvailable(result);
}
}
} catch (IOException e) {
Log.d(TAG, "getDirections: caught exception: " + e.getLocalizedMessage());
}
});
t.start();
// wait for when we have a result from the api until we can continue, otherwise the route will be drawn before we get the result
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,8 @@
package com.a1.nextlocation.network;
import com.a1.nextlocation.data.Route;
import com.a1.nextlocation.json.DirectionsResult;
public interface DirectionsListener {
void onDirectionsAvailable(DirectionsResult result);
}

View File

@@ -1,8 +1,79 @@
package com.a1.nextlocation.recyclerview;
public class CouponAdapter {
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.widget.TextView;
class CouponViewHolder {
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Coupon;
import java.util.List;
public class CouponAdapter extends RecyclerView.Adapter<CouponAdapter.CouponViewHolder> {
private Context appContext;
private List<Coupon> couponList;
private OnItemClickListener clickListener;
public interface OnItemClickListener {
void onItemClick(int clickedPosition);
}
class CouponViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView couponCode;
private TextView couponReward;
public CouponViewHolder(@NonNull View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
public void setTextViewName(String text){
this.couponReward = itemView.findViewById(R.id.coupon_name);
this.couponReward.setText(text);
}
@Override
public void onClick(View v) {
clickListener.onItemClick(getAdapterPosition());
}
}
public CouponAdapter(Context context, List<Coupon> coupon, OnItemClickListener listener){
this.appContext = context;
this.couponList = coupon;
this.clickListener = listener;
}
public CouponAdapter(Context context, List<Coupon> coupon) {
this.appContext = context;
this.couponList = coupon;
}
@NonNull
@Override
public CouponViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.coupon_item, parent, false);
return new CouponViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull CouponViewHolder holder, int position) {
Coupon coupon = couponList.get(position);
holder.setTextViewName(coupon.getReward());
}
@Override
public int getItemCount() {
return couponList.size();
}
}

View File

@@ -1,4 +1,34 @@
package com.a1.nextlocation.recyclerview;
public class CouponListManager {
import android.content.Context;
import com.a1.nextlocation.data.Coupon;
import java.util.ArrayList;
import java.util.List;
public enum CouponListManager {
INSTANCE;
private List<Coupon> couponList;
private Context context;
public void setContext(Context context) {
this.context = context;
this.couponList = new ArrayList<>();
}
public List<Coupon> getCouponList() {
return couponList;
}
public Coupon getCoupon(int place) {
return couponList.get(place);
}
public void load(){
CouponLoader couponLoader = new CouponLoader(this.context);
this.couponList = couponLoader.load();
}
}

View File

@@ -1,4 +1,30 @@
package com.a1.nextlocation.recyclerview;
public class CouponLoader {
import android.content.Context;
import android.util.Log;
import com.a1.nextlocation.data.Coupon;
import com.a1.nextlocation.data.FileIO;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.List;
public class CouponLoader implements Loader<List<Coupon>> {
private final Context context;
private final String TAG = CouponLoader.class.getCanonicalName();
public CouponLoader(Context context) {
this.context = context;
}
@Override
public ArrayList<Coupon> load() {
FileIO<ArrayList<Coupon>> fileIO = new FileIO<>();
ArrayList<Coupon> res = fileIO.readFileData(context, "coupons.json",new TypeToken<ArrayList<Coupon>>(){}.getType());
Log.d(TAG, "load: " + res);
return res == null ? new ArrayList<>() : res;
}
}

View File

@@ -0,0 +1,42 @@
package com.a1.nextlocation.recyclerview;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import org.osmdroid.api.IMapView;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedOverlay;
import org.osmdroid.views.overlay.OverlayItem;
import java.util.ArrayList;
public class CustomOverlay extends ItemizedOverlay<OverlayItem> {
private final MapView mapView;
private ArrayList<OverlayItem> overlayItems = new ArrayList<>();
public CustomOverlay(Drawable pDefaultMarker, MapView mapView) {
super(pDefaultMarker);
this.mapView = mapView;
}
public void addOverlayItem(OverlayItem item) {
overlayItems.add(item);
populate();
}
@Override
protected OverlayItem createItem(int i) {
return overlayItems.get(i);
}
@Override
public int size() {
return overlayItems.size();
}
@Override
public boolean onSnapToItem(int x, int y, Point snapPoint, IMapView mapView) {
return true;
}
}

View File

@@ -0,0 +1,5 @@
package com.a1.nextlocation.recyclerview;
public interface Loader<T> {
T load();
}

View File

@@ -1,8 +1,82 @@
package com.a1.nextlocation.recyclerview;
public class LocationAdapter {
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
class LocationViewHolder {
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Location;
import java.util.List;
public class LocationAdapter extends RecyclerView.Adapter<LocationAdapter.LocationViewHolder> {
private Context appContext;
private List<Location> locationList;
private OnItemClickListener clickListener;
public interface OnItemClickListener {
void onItemClick(int clickedPosition);
}
class LocationViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView locationName;
private ImageView locationImage;
public LocationViewHolder(@NonNull View itemView) {
super(itemView);
this.locationName = itemView.findViewById(R.id.location_name);
this.locationImage = itemView.findViewById(R.id.location_image);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
clickListener.onItemClick(getAdapterPosition());
}
public void setTextViewText(String text){
this.locationName = itemView.findViewById(R.id.location_name);
locationName.setText(text);
}
public void setImageViewImage(String text){
this.locationImage = itemView.findViewById(R.id.location_image);
Context context = locationImage.getContext();
int id = context.getResources().getIdentifier(text, "drawable", context.getPackageName());
locationImage.setImageResource(id);
}
}
public LocationAdapter(Context context, List<Location> location, OnItemClickListener listener){
this.appContext = context;
this.locationList = location;
this.clickListener = listener;
}
@NonNull
@Override
public LocationAdapter.LocationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.location_item, parent, false);
return new LocationViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull LocationAdapter.LocationViewHolder holder, int position) {
Location location = locationList.get(position);
holder.setTextViewText(location.getName());
holder.setImageViewImage(location.getImageUrl());
}
@Override
public int getItemCount() {
return locationList.size();
}
}

View File

@@ -1,4 +1,36 @@
package com.a1.nextlocation.recyclerview;
public class LocationListManager {
import android.content.Context;
import com.a1.nextlocation.data.Location;
import org.osmdroid.util.GeoPoint;
import java.util.ArrayList;
import java.util.List;
public enum LocationListManager {
INSTANCE;
private List<Location> locationList;
private Context context;
public void setContext(Context context) {
this.context = context;
this.locationList = new ArrayList<>();
}
public List<Location> getLocationList() {
return locationList;
}
public Location getLocation(int place) {
return locationList.get(place);
}
public void load() {
LocationLoader locationLoader = new LocationLoader(this.context);
this.locationList = locationLoader.load();
}
}

View File

@@ -1,4 +1,28 @@
package com.a1.nextlocation.recyclerview;
public class LocationLoader {
import android.content.Context;
import com.a1.nextlocation.data.FileIO;
import com.a1.nextlocation.data.Location;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class LocationLoader implements Loader<List<Location>> {
private final Context context;
public LocationLoader(Context context) {
this.context = context;
}
@Override
public ArrayList<Location> load() {
FileIO<ArrayList<Location>> fileIO = new FileIO<>();
ArrayList<Location> res = fileIO.readFileData(context,"locations.json",new TypeToken<ArrayList<Location>>(){}.getType());
return res == null ? new ArrayList<>() : res;
}
}

View File

@@ -1,8 +1,73 @@
package com.a1.nextlocation.recyclerview;
public class RouteAdapter {
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
class RouteViewHolder {
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Location;
import com.a1.nextlocation.data.Route;
import java.util.List;
public class RouteAdapter extends RecyclerView.Adapter<RouteAdapter.RouteViewHolder>{
private Context appContext;
private List<Route> routeList;
private CouponAdapter.OnItemClickListener clickListener;
public interface OnItemClickListener {
void onItemClick(int clickedPosition);
}
class RouteViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView routeName;
public RouteViewHolder(@NonNull View itemView) {
super(itemView);
this.routeName = itemView.findViewById(R.id.route_name);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
clickListener.onItemClick(getAdapterPosition());
}
public void setTextViewText(String text){
this.routeName = itemView.findViewById(R.id.route_name);
this.routeName.setText(text);
}
}
public RouteAdapter(Context context, List<Route> route, CouponAdapter.OnItemClickListener listener){
appContext = context;
routeList = route;
clickListener = listener;
}
@NonNull
@Override
public RouteAdapter.RouteViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.route_item, parent, false);
return new RouteViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull RouteAdapter.RouteViewHolder holder, int position) {
Route route = routeList.get(position);
holder.setTextViewText(route.getName());
}
@Override
public int getItemCount() {
return routeList.size();
}
}

View File

@@ -1,4 +1,34 @@
package com.a1.nextlocation.recyclerview;
public class RouteListManager {
import android.content.Context;
import com.a1.nextlocation.data.Route;
import java.util.ArrayList;
import java.util.List;
public enum RouteListManager{
INSTANCE;
private List<Route> routeList;
private Context context;
public void setContext(Context context) {
this.context = context;
this.routeList = new ArrayList<>();
}
public List<Route> getRouteList() {
return routeList;
}
public Route getRoute(int place) {
return routeList.get(place);
}
public void load() {
RouteLoader routeLoader = new RouteLoader(this.context);
this.routeList = routeLoader.load();
}
}

View File

@@ -1,4 +1,29 @@
package com.a1.nextlocation.recyclerview;
public class RouteLoader {
import android.content.Context;
import com.a1.nextlocation.data.FileIO;
import com.a1.nextlocation.data.Location;
import com.a1.nextlocation.data.Route;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class RouteLoader implements Loader<List<Route>> {
private final Context context;
public RouteLoader(Context context) {
this.context = context;
}
@Override
public ArrayList<Route> load() {
FileIO<ArrayList<Route>> fileIO = new FileIO<>();
ArrayList<Route> res = fileIO.readFileData(context, "routes.json",new TypeToken<ArrayList<Route>>(){}.getType());
return res == null ? new ArrayList<>() : res;
}
}

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#333333"
android:alpha="0.6">
<path
android:fillColor="@android:color/white"
android:pathData="M8,16h8V8H8V16zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2L12,2z"
android:fillType="evenOdd"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M17.77,3.77l-1.77,-1.77l-10,10l10,10l1.77,-1.77l-8.23,-8.23z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M7,18h2L9,6L7,6v12zM11,22h2L13,2h-2v20zM3,14h2v-4L3,10v4zM15,18h2L17,6h-2v12zM19,10v4h2v-4h-2z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@color/primaryColour"
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M14,6l-1,-2L5,4v17h2v-7h5l1,2h7L20,6h-6zM18,14h-4l-1,-2L7,12L7,6h5l1,2h5v6z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M8,5v14l11,-7z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
</vector>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primaryColour"
tools:context=".fragments.LocationDetailFragment">
<TextView
android:id="@+id/detail_location_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text=""
android:textColor="@color/white"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/detail_location_image"
android:layout_width="309dp"
android:layout_height="283dp"
android:layout_marginStart="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detail_location_name"
tools:src="@tools:sample/avatars" />
<TextView
android:id="@+id/detail_location_text"
android:layout_width="309dp"
android:layout_height="283dp"
android:layout_marginEnd="30dp"
android:background="@color/secondaryColour"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detail_location_name" />
<ImageButton
android:id="@+id/detail_location_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:backgroundTint="@color/primaryColour"
android:src="@drawable/ic_back_button_24"
app:layout_constraintBottom_toBottomOf="@+id/detail_location_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/detail_location_name"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/primaryColour"
tools:context=".fragments.RouteDetailFragment">
<Button
android:id="@+id/start_route_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/secondaryColour"
android:text="@string/start_route"
android:textColor="@color/buttonColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/reoute_detail_tekst"
app:layout_constraintStart_toStartOf="@+id/reoute_detail_tekst"
app:layout_constraintTop_toBottomOf="@+id/reoute_detail_tekst"
app:layout_constraintVertical_bias="0.873" />
<ImageButton
android:id="@+id/routeDetailBackButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/ic_back_button_24"
app:layout_constraintBottom_toBottomOf="@+id/route_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/route_title"
app:layout_constraintEnd_toStartOf="@id/route_title"
/>
<TextView
android:id="@+id/route_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="250dp"
android:text="titel"
android:textColor="@color/white"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/route_detail_image"
app:layout_constraintEnd_toStartOf="@+id/reoute_detail_tekst"
app:layout_constraintStart_toEndOf="@id/routeDetailBackButton"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/route_detail_image"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_marginEnd="350dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/reoute_detail_tekst"
android:layout_width="0dp"
android:layout_height="10dp"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:layout_marginBottom="200dp"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/route_detail_image"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -4,35 +4,26 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mainActivity"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fragment_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/scroller_devider"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<View
android:id="@+id/scroller_devider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
app:layout_constraintBottom_toTopOf="@id/navbar"
app:layout_constraintTop_toBottomOf="@+id/top_bar"
app:layout_constraintBottom_toTopOf="@id/navigation_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/navbar"
android:showAsAction="always|withText"
android:id="@+id/navigation_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/white"
app:itemIconTint="@color/primaryColour"
app:itemIconTint="@color/secondaryColour"
app:itemTextColor="@color/primaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -40,6 +31,38 @@
app:menu="@menu/navmenu"
/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/top_bar"
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/fragment_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@color/primaryColour"/>
<ImageButton
android:id="@+id/info_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_info_24"
android:backgroundTint="@color/primaryColour"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar"
android:tint="@color/secondaryColour"
/>
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textColor="@color/secondaryColour"
android:textSize="25sp"
app:layout_constraintBottom_toBottomOf="@id/top_bar"
app:layout_constraintStart_toEndOf="@id/info_button"
app:layout_constraintTop_toTopOf="@id/top_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:id="@+id/couponItem"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/name_box"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:background="@color/secondaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/coupon_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text=""
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,14 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.CouponFragment">
android:background="@color/primaryColour"
android:id="@+id/couponFragment"
tools:context=".fragments.LocationFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
android:id="@+id/coupon_RV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="9dp"
android:layout_marginTop="20dp"
android:text="@string/statistics"
android:textSize="20sp"
app:layout_constraintStart_toEndOf="@id/coupon_back_button"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>
<ImageButton
android:id="@+id/coupon_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="12dp"
android:background="@drawable/ic_back_button_24"
android:backgroundTint="@color/buttonColour"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/coupon_recyclerview"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/coupon_back_button" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,14 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/homeFragment"
tools:context=".fragments.HomeFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
<org.osmdroid.views.MapView
android:id="@+id/map_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
android:layout_height="match_parent">
</org.osmdroid.views.MapView>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="@+id/location_list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:backgroundTint="@color/secondaryColour"
android:src="@drawable/ic_baseline_outlined_flag_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/home_stop_route_button"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/location_list_button"
android:backgroundTint="@color/secondaryColour"
android:src="@drawable/ic_stop_icon"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@@ -1,14 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primaryColour"
android:id="@+id/locationFragment"
tools:context=".fragments.LocationFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/location_RV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="9dp"
android:layout_marginTop="20dp"
android:text="@string/locations"
android:textSize="20sp"
app:layout_constraintStart_toEndOf="@id/location_back_button"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/location_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="12dp"
android:background="@drawable/ic_back_button_24"
android:backgroundTint="@color/buttonColour"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/location_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
android:layout_marginTop="60dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/location_RV" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,14 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primaryColour"
android:id="@+id/locationDetailFragment"
tools:context=".fragments.LocationDetailFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
android:id="@+id/detail_location_name"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text=""
android:textColor="@color/white"
android:textSize="30sp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>
<ImageView
android:id="@+id/detail_location_image"
android:layout_width="357dp"
android:layout_height="196dp"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detail_location_name"
tools:src="@tools:sample/avatars" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="20dp"
android:background="@color/secondaryColour"
android:text=""
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detail_location_image">
<TextView
android:id="@+id/detail_location_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/secondaryColour"
android:text=""
/>
</ScrollView>
<ImageButton
android:id="@+id/detail_location_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="12dp"
android:backgroundTint="@color/primaryColour"
android:src="@drawable/ic_back_button_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,14 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primaryColour"
android:id="@+id/routeFragment"
tools:context=".fragments.RouteFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
<ImageButton
android:id="@+id/route_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/ic_back_button_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>
<TextView
android:id="@+id/route_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="9dp"
android:text="@string/routes"
android:textSize="20sp"
app:layout_constraintStart_toEndOf="@id/route_back_button"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/route_recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/primaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/route_back_button" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,14 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/primaryColour"
android:id="@+id/routeDetailFragment"
tools:context=".fragments.RouteDetailFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
<ImageButton
android:id="@+id/route_detail_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:background="@drawable/ic_back_button_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>
<TextView
android:id="@+id/route_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/route_detail_image"
android:text=""
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_margin="40dp"
android:id="@+id/route_detail_image"
app:layout_constraintTop_toBottomOf="@id/route_detail_back_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/reoute_detail_tekst" />
<TextView
android:id="@+id/reoute_detail_tekst"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="56dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/route_detail_image" />
<Button
android:id="@+id/start_route_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:backgroundTint="@color/secondaryColour"
android:text="@string/start_route"
android:textColor="@color/buttonColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/total_distance" />
<TextView
android:id="@+id/total_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="141dp"
android:layout_marginBottom="19dp"
android:text="@string/total_distance"
android:background="@color/secondaryColour"
android:textColor="@color/buttonColour"
app:layout_constraintBottom_toTopOf="@+id/start_route_button"
app:layout_constraintTop_toBottomOf="@+id/reoute_detail_tekst"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:layout_editor_absoluteX="169dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,14 +1,222 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/primaryColour"
android:id="@+id/settingFragment"
tools:context=".fragments.SettingsFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/settings_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:backgroundTint="@color/primaryColour"
android:src="@drawable/ic_back_button_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/settings"
android:textColor="@color/white"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/name_box"
android:layout_width="match_parent"
android:layout_height="70dp"
app:layout_constraintBottom_toTopOf="@id/Box2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView"
android:background="@color/secondaryColour"
android:layout_marginHorizontal="20dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/language"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/Balk"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<Spinner
android:id="@+id/dropdown_menu_Settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/Balk"
app:layout_constraintTop_toTopOf="parent"
android:tooltipText="Taal"
android:spinnerMode="dropdown"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/Box2"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
android:background="@color/secondaryColour"
app:layout_constraintBottom_toTopOf="@id/Box3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/name_box"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/imperial_system"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/Balk2"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/settingsImperialButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/Balk2"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/Box3"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
android:background="@color/secondaryColour"
app:layout_constraintBottom_toTopOf="@id/Box4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/Box2"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/_65_mode"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/Balk3"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/BigFont"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/Balk3"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/Box4"
android:layout_width="match_parent"
android:layout_height="70dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/Box3"
android:background="@color/secondaryColour"
android:layout_marginHorizontal="20dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/colorblind"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/Balk4"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/settingsEyesButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/Balk4"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,14 +1,239 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primaryColour"
android:id="@+id/statisticsFragment"
tools:context=".fragments.StatisticFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/statistics"
android:textColor="@color/white"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/name_box"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
android:background="@color/secondaryColour"
app:layout_constraintBottom_toTopOf="@id/Box2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/total_distance"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/Balk"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/statistics_km"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/Balk"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/Box2"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
android:background="@color/secondaryColour"
app:layout_constraintBottom_toTopOf="@id/Box3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/name_box"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/visited_locations"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/Balk2"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/statistics_locations_visited"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/Balk2"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/Box3"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
android:background="@color/secondaryColour"
app:layout_constraintBottom_toTopOf="@id/Box4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/Box2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/total_time"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/Balk3"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/statistics_time_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/Balk3"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/Box4"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
android:background="@color/secondaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.85"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/Box3">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/coupons_collected"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/Balk4"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/couponAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/Balk4"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/coupon_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:background="@drawable/ic_back_button_24"
android:scaleX="-1"
app:layout_constraintBottom_toBottomOf="@+id/couponAmount"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/couponAmount" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageButton
android:id="@+id/statistics_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:background="@drawable/ic_back_button_24"
android:backgroundTint="@color/buttonColour"
android:src="@drawable/ic_back_button_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="50dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/secondaryColour"
android:id="@+id/locationItem"
android:layout_margin="20dp">
<ImageView
android:id="@+id/location_image"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/location_name"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="@+id/location_name"
android:layout_width="321dp"
android:layout_height="47dp"
android:gravity="left"
android:text=""
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="50dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/secondaryColour"
android:id="@+id/routeItem"
android:layout_margin="20dp">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/route_Image"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<TextView
android:id="@+id/route_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/route_Image"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -4,25 +4,25 @@
<item
android:id="@+id/locations"
android:title="@string/locations"
android:icon="@drawable/ic_placeholder"
android:icon="@drawable/ic_baseline_outlined_flag_24"
/>
<item
android:id="@+id/routes"
android:title="@string/routes"
android:icon="@drawable/ic_placeholder"
android:icon="@drawable/ic_baseline_location_on_24"
/>
<item
android:id="@+id/statistics"
android:title="@string/statistics"
android:icon="@drawable/ic_placeholder"
android:icon="@drawable/ic_baseline_graphic_eq_24"
/>
<item
android:id="@+id/settings"
android:title="@string/settings"
android:icon="@drawable/ic_placeholder"
android:icon="@drawable/ic_baseline_settings_24"
/>
</menu>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/icon_background"/>
<foreground android:drawable="@mipmap/icon_foreground"/>
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/icon_background"/>
<foreground android:drawable="@mipmap/icon_foreground"/>
</adaptive-icon>

Some files were not shown because too many files have changed in this diff Show More