diff --git a/onebusaway-android/src/amazon/java/org/onebusaway/android/map/googlemapsv2/BaseMapFragment.java b/onebusaway-android/src/amazon/java/org/onebusaway/android/map/googlemapsv2/BaseMapFragment.java
index e92541b63..5df6d1174 100644
--- a/onebusaway-android/src/amazon/java/org/onebusaway/android/map/googlemapsv2/BaseMapFragment.java
+++ b/onebusaway-android/src/amazon/java/org/onebusaway/android/map/googlemapsv2/BaseMapFragment.java
@@ -38,6 +38,7 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
@@ -52,6 +53,7 @@
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.DialogFragment;
@@ -65,6 +67,7 @@
import com.amazon.geo.mapsv2.model.CameraPosition;
import com.amazon.geo.mapsv2.model.LatLng;
import com.amazon.geo.mapsv2.model.LatLngBounds;
+import com.amazon.geo.mapsv2.model.MapStyleOptions;
import com.amazon.geo.mapsv2.model.Marker;
import com.amazon.geo.mapsv2.model.Polyline;
import com.amazon.geo.mapsv2.model.PolylineOptions;
@@ -333,6 +336,15 @@ public void onMapReady(com.amazon.geo.mapsv2.AmazonMap map) {
mMap.setOnMarkerClickListener(mapClickListeners);
mMap.setOnMapClickListener(mapClickListeners);
+ if (
+ AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES || (
+ AppCompatDelegate.getDefaultNightMode() != AppCompatDelegate.MODE_NIGHT_NO &&
+ (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
+ )
+ ) {
+ mMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(getContext(), R.raw.dark_map));
+ }
+
initMap(mLastSavedInstanceState);
}
diff --git a/onebusaway-android/src/google/java/org/onebusaway/android/map/googlemapsv2/BaseMapFragment.java b/onebusaway-android/src/google/java/org/onebusaway/android/map/googlemapsv2/BaseMapFragment.java
index 071a5693a..8f3e0d57c 100644
--- a/onebusaway-android/src/google/java/org/onebusaway/android/map/googlemapsv2/BaseMapFragment.java
+++ b/onebusaway-android/src/google/java/org/onebusaway/android/map/googlemapsv2/BaseMapFragment.java
@@ -27,6 +27,7 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
@@ -41,6 +42,7 @@
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.DialogFragment;
@@ -54,6 +56,7 @@
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
+import com.google.android.gms.maps.model.MapStyleOptions;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
@@ -322,6 +325,15 @@ public void onMapReady(com.google.android.gms.maps.GoogleMap map) {
mMap.setOnMarkerClickListener(mapClickListeners);
mMap.setOnMapClickListener(mapClickListeners);
+ if (
+ AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES || (
+ AppCompatDelegate.getDefaultNightMode() != AppCompatDelegate.MODE_NIGHT_NO &&
+ (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
+ )
+ ) {
+ mMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(getContext(), R.raw.dark_map));
+ }
+
initMap(mLastSavedInstanceState);
}
diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/ui/PreferencesActivity.java b/onebusaway-android/src/main/java/org/onebusaway/android/ui/PreferencesActivity.java
index 2ba708992..7260d090f 100644
--- a/onebusaway-android/src/main/java/org/onebusaway/android/ui/PreferencesActivity.java
+++ b/onebusaway-android/src/main/java/org/onebusaway/android/ui/PreferencesActivity.java
@@ -46,6 +46,7 @@
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
@@ -117,6 +118,8 @@ public class PreferencesActivity extends PreferenceActivity
ListPreference preferredUnits;
+ ListPreference mThemePref;
+
private FirebaseAnalytics mFirebaseAnalytics;
@SuppressWarnings("deprecation")
@@ -188,6 +191,10 @@ public void onCreate(Bundle savedInstanceState) {
preferredUnits = (ListPreference) findPreference(
getString(R.string.preference_key_preferred_units));
+ mThemePref = (ListPreference) findPreference(
+ getString(R.string.preference_key_app_theme));
+ mThemePref.setOnPreferenceChangeListener(this);
+
settings.registerOnSharedPreferenceChangeListener(this);
PreferenceScreen preferenceScreen = getPreferenceScreen();
@@ -236,6 +243,7 @@ protected void onResume() {
changePreferenceSummary(getString(R.string.preference_key_region));
changePreferenceSummary(getString(R.string.preference_key_preferred_units));
+ changePreferenceSummary(getString(R.string.preference_key_app_theme));
changePreferenceSummary(getString(R.string.preference_key_otp_api_url));
// Remove preferences for notifications if no trip planning
@@ -300,6 +308,9 @@ private void changePreferenceSummary(String preferenceKey) {
} else if (preferenceKey
.equalsIgnoreCase(getString(R.string.preference_key_preferred_units))) {
preferredUnits.setSummary(preferredUnits.getValue());
+ } else if (preferenceKey
+ .equalsIgnoreCase(getString(R.string.preference_key_app_theme))) {
+ mThemePref.setSummary(mThemePref.getValue());
} else if (preferenceKey
.equalsIgnoreCase(getString(R.string.preference_key_otp_api_url))) {
String customOtpApiUrl = Application.get().getCustomOtpApiUrl();
@@ -567,6 +578,11 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
} else if (key.equalsIgnoreCase(getString(R.string.preference_key_preferred_units))) {
// Change the preferred units description
changePreferenceSummary(key);
+ } else if (key.equalsIgnoreCase(getString(R.string.preference_key_app_theme))) {
+ // Change the app theme preference description
+ changePreferenceSummary(key);
+ // Update the app theme
+ setAppTheme(settings.getString(key, getString(R.string.preferences_app_theme_option_system_default)));
} else if (key.equalsIgnoreCase(getString(R.string.preference_key_auto_select_region))) {
//Analytics
boolean autoSelect = settings
@@ -650,4 +666,16 @@ public void onRegionTaskFinished(boolean currentRegionChanged) {
NavHelp.goHome(this, false);
}
}
+
+ private void setAppTheme(String themeValue) {
+ if (themeValue.equalsIgnoreCase(Application.get().getString(R.string.preferences_app_theme_option_system_default))) {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
+ }
+ if (themeValue.equalsIgnoreCase(Application.get().getString(R.string.preferences_app_theme_option_dark))) {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
+ }
+ if (themeValue.equalsIgnoreCase(Application.get().getString(R.string.preferences_app_theme_option_light))) {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
+ }
+ }
}
diff --git a/onebusaway-android/src/main/res/raw/dark_map.json b/onebusaway-android/src/main/res/raw/dark_map.json
new file mode 100644
index 000000000..3bc432a92
--- /dev/null
+++ b/onebusaway-android/src/main/res/raw/dark_map.json
@@ -0,0 +1,191 @@
+[
+ {
+ "featureType": "all",
+ "elementType": "geometry",
+ "stylers": [
+ {
+ "color": "#242f3e"
+ }
+ ]
+ },
+ {
+ "featureType": "all",
+ "elementType": "labels.text.stroke",
+ "stylers": [
+ {
+ "lightness": -80
+ }
+ ]
+ },
+ {
+ "featureType": "administrative",
+ "elementType": "labels.text.fill",
+ "stylers": [
+ {
+ "color": "#746855"
+ }
+ ]
+ },
+ {
+ "featureType": "administrative.locality",
+ "elementType": "labels.text.fill",
+ "stylers": [
+ {
+ "color": "#d59563"
+ }
+ ]
+ },
+ {
+ "featureType": "poi",
+ "elementType": "labels.text.fill",
+ "stylers": [
+ {
+ "color": "#d59563"
+ }
+ ]
+ },
+ {
+ "featureType": "poi.park",
+ "elementType": "geometry",
+ "stylers": [
+ {
+ "color": "#263c3f"
+ }
+ ]
+ },
+ {
+ "featureType": "poi.park",
+ "elementType": "labels.text.fill",
+ "stylers": [
+ {
+ "color": "#6b9a76"
+ }
+ ]
+ },
+ {
+ "featureType": "road",
+ "elementType": "geometry.fill",
+ "stylers": [
+ {
+ "color": "#2b3544"
+ }
+ ]
+ },
+ {
+ "featureType": "road",
+ "elementType": "labels.text.fill",
+ "stylers": [
+ {
+ "color": "#9ca5b3"
+ }
+ ]
+ },
+ {
+ "featureType": "road.arterial",
+ "elementType": "geometry.fill",
+ "stylers": [
+ {
+ "color": "#38414e"
+ }
+ ]
+ },
+ {
+ "featureType": "road.arterial",
+ "elementType": "geometry.stroke",
+ "stylers": [
+ {
+ "color": "#212a37"
+ }
+ ]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "geometry.fill",
+ "stylers": [
+ {
+ "color": "#746855"
+ }
+ ]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "geometry.stroke",
+ "stylers": [
+ {
+ "color": "#1f2835"
+ }
+ ]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "labels.text.fill",
+ "stylers": [
+ {
+ "color": "#f3d19c"
+ }
+ ]
+ },
+ {
+ "featureType": "road.local",
+ "elementType": "geometry.fill",
+ "stylers": [
+ {
+ "color": "#38414e"
+ }
+ ]
+ },
+ {
+ "featureType": "road.local",
+ "elementType": "geometry.stroke",
+ "stylers": [
+ {
+ "color": "#212a37"
+ }
+ ]
+ },
+ {
+ "featureType": "transit",
+ "elementType": "geometry",
+ "stylers": [
+ {
+ "color": "#2f3948"
+ }
+ ]
+ },
+ {
+ "featureType": "transit.station",
+ "elementType": "labels.text.fill",
+ "stylers": [
+ {
+ "color": "#d59563"
+ }
+ ]
+ },
+ {
+ "featureType": "water",
+ "elementType": "geometry",
+ "stylers": [
+ {
+ "color": "#17263c"
+ }
+ ]
+ },
+ {
+ "featureType": "water",
+ "elementType": "labels.text.fill",
+ "stylers": [
+ {
+ "color": "#515c6d"
+ }
+ ]
+ },
+ {
+ "featureType": "water",
+ "elementType": "labels.text.stroke",
+ "stylers": [
+ {
+ "lightness": -20
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/onebusaway-android/src/main/res/values/arrays.xml b/onebusaway-android/src/main/res/values/arrays.xml
index 45c15ad85..12c3c2b20 100644
--- a/onebusaway-android/src/main/res/values/arrays.xml
+++ b/onebusaway-android/src/main/res/values/arrays.xml
@@ -96,6 +96,11 @@
- @string/preferences_preferred_units_option_metric
- @string/preferences_preferred_units_option_imperial
+
+ - @string/preferences_app_theme_option_system_default
+ - @string/preferences_app_theme_option_light
+ - @string/preferences_app_theme_option_dark
+
- @string/preferences_arrival_info_style_options_a
- @string/preferences_arrival_info_style_options_b
diff --git a/onebusaway-android/src/main/res/values/donottranslate.xml b/onebusaway-android/src/main/res/values/donottranslate.xml
index 8aae006c6..68a73584f 100644
--- a/onebusaway-android/src/main/res/values/donottranslate.xml
+++ b/onebusaway-android/src/main/res/values/donottranslate.xml
@@ -34,6 +34,7 @@
preference_powered_by_oba
preference_about
preference_preferred_units
+ preference_app_theme
preference_arrival_info_style
preference_show_negative_arrivals
preference_show_zoom_controls
diff --git a/onebusaway-android/src/main/res/values/strings.xml b/onebusaway-android/src/main/res/values/strings.xml
index 5e55bb452..e9b94844a 100644
--- a/onebusaway-android/src/main/res/values/strings.xml
+++ b/onebusaway-android/src/main/res/values/strings.xml
@@ -622,6 +622,11 @@
Metric (km, m)
Imperial (mi, ft)
+ App Theme
+ System Default
+ Light Theme
+ Dark Theme
+
Show departed buses
Include buses that just left as
negative arrival times
diff --git a/onebusaway-android/src/main/res/values/themes.xml b/onebusaway-android/src/main/res/values/themes.xml
index 27c40afda..dd73e5d7d 100644
--- a/onebusaway-android/src/main/res/values/themes.xml
+++ b/onebusaway-android/src/main/res/values/themes.xml
@@ -23,5 +23,7 @@
- @color/theme_accent
- @style/cursorColor
+
+ - true
\ No newline at end of file
diff --git a/onebusaway-android/src/main/res/xml/preferences.xml b/onebusaway-android/src/main/res/xml/preferences.xml
index d99082a19..30b12b4ba 100644
--- a/onebusaway-android/src/main/res/xml/preferences.xml
+++ b/onebusaway-android/src/main/res/xml/preferences.xml
@@ -67,7 +67,13 @@
android:entries="@array/preferred_units_options"
android:entryValues="@array/preferred_units_options"
android:key="@string/preference_key_preferred_units"
- android:title="@string/preferences_preferred_units_title">
+ android:title="@string/preferences_preferred_units_title" />
+