Skip to content

An assessment of showing list of vehicles in google map and list view using free now API.

Notifications You must be signed in to change notification settings

zigeorge/FreeNowAssessment

Repository files navigation

Android candidate test (Applicant Coding Challenge)

Task 1

Loading data from given api and showing them in a list.

Task 2

Implement a map Activity/Fragment with Google Maps. Show all available vehicles on the map. Use the bounds of the map to request the vehicles. The map should zoom in and center on a specific vehicle when it is selected in the previously implemented list.

Project structure

The project is structured following the guideline of [Android Architecture Components]. The ui package contains activity and fragments which renders the data on the screen and viewModel is used to contain and manage the state. Additionally there are vo and adapter packages which contain ViewObject and adapters. The repositories and data packages are part of the data layer where repositories handle the business logic. The data package contains retrofit client for API calls and room for local data storage and sync. To manage dependencies between components dagger-hilt is used and the module is kept in di package other package contains the followings

  • ConnectivityObserver helps to observe connectivity
  • BitmapHelper helps to draw marker from vector drawable
  • Constants constant object/values
  • Ext extension functions or helper functions Clean architecture and SOLID principle has been strictly maintain during the process of the development. Unit Test, Integration Test and E2E Testing has also been respectively implemented.

Generic

In MainActivity [Navigation Component] is used to host all the fragments in the NavHostFragment. A [Bottom Navigation View] is implemented so that user can easily navigate between fragments. [Dagger-hilt] is used for dependency injection. Turbine is used to test flow and Truth for easy assertion in unit tests. Retrofit is used for API services and Room for storing and managing data locally. api is implemented in VehicleApi.

Show useful vehicle information

Here, we have a JSON as API response which contains a list of vehicle information (id, coordinate, fleetType, state and heading) In the VehiclesFragment, list of all available vehicles as SingleVehicle is shown. Each list item contains the value of type, address-line and state GeoCoder is used to convert all Coordinate from VehicleData into address-line The API often returns 100 or more vehicle information, hence, paging-3 is used to slow loading the items in the list and provide a better user experience. VehicleDao provides access to VehicleDB which is used to store all new data from the list or update if a change occurs in the existing vehicle data. When the app is live, it will request api every 20 seconds using coroutine's Dispatchers.IO context. [Kotlin Flow] is used for data streaming. Hence, with the change syncing in vehicles table, paging-3 library have PagingSource API which maps data from Flow and stream it to VehicleRecyclerViewAdapter which is a PagingDataAdapter VehicleListViewModel holds the state of all the data so that the list page survives the configuration changes.

Show all vehicle as markers in the map

In the MapFragment all vehicle is shown as markers. Here, a carIcon is represented as custom marker which is created using bitmap-helper. Response from the VehicleApi is fetched and mapped into List of VehicleMarker which is set on the map as markers according to their LatLng. All the basic gestures(e.g., zoom, pan) are enabled in the map. When a SingleVehicle is selected from VehiclesFragment, MapFragment opens and zoom in towards the selected VehicleMarker. MarkerInfoWindowAdapter is used to show the details of a marker in the map when tapped.

Update data

It occurred to me that the VehicleApi response is always changing. Hence, I developed VehicleDataSource to load data from API and then sync with VehicleDB. Upon receiving data from API the app is deleting all vehicle information that are not in the latest data set. Then, it updates any existing vehicle information and add new vehicle information in VerhiclrDB. DELETE FROM vehicles WHERE vehicleId NOT IN (:list) is the query to delete all vehicle information not in the latest data set. VehicleDataSource repeats the whole process every 20 seconds in a Dispatchers.IO coroutine context. This enables zero loading time and a very neat user experience.

Libraries

Releases

No releases published

Packages

 
 
 

Languages