add openhack files

This commit is contained in:
Ryan Peters
2022-11-03 16:41:13 -04:00
commit b2c9f7e29f
920 changed files with 118861 additions and 0 deletions

View File

@ -0,0 +1,489 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Android.OS;
using Android.Support.V4.Content;
using Android.Views;
using Android.Widget;
using MyDriving.Droid.Services;
using MyDriving.ViewModel;
using MvvmHelpers;
using MyDriving.DataObjects;
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using System;
using Android.Graphics;
using Android.Graphics.Drawables;
using Plugin.Permissions;
using Plugin.Permissions.Abstractions;
using System.Threading.Tasks;
using MyDriving.Droid.Activities;
using MyDriving.Utils;
using MyDriving.Droid.Helpers;
using Android.Support.Design.Widget;
using System.Collections.Specialized;
using System.Collections.Generic;
using Android.Views.Animations;
using Android.Animation;
namespace MyDriving.Droid.Fragments
{
public class FragmentCurrentTrip : Android.Support.V4.App.Fragment, IOnMapReadyCallback
{
List<LatLng> allPoints;
Marker carMarker;
TextView distance, distanceUnits, time, load, consumption, consumptionUnits;
Polyline driveLine;
Color? driveLineColor;
FloatingActionButton fab;
GoogleMap map;
MapView mapView;
bool setZoom = true;
LinearLayout stats;
ObservableRangeCollection<TripPoint> trailPointList;
CurrentTripViewModel viewModel;
public void OnMapReady(GoogleMap googleMap)
{
map = googleMap;
if (viewModel != null)
SetupMap();
}
public static FragmentCurrentTrip NewInstance() => new FragmentCurrentTrip {Arguments = new Bundle()};
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
HasOptionsMenu = true;
var view = inflater.Inflate(Resource.Layout.fragment_current_trip, null);
mapView = view.FindViewById<MapView>(Resource.Id.map);
mapView.OnCreate(savedInstanceState);
fab = view.FindViewById<FloatingActionButton>(Resource.Id.fab);
time = view.FindViewById<TextView>(Resource.Id.text_time);
distance = view.FindViewById<TextView>(Resource.Id.text_distance);
distanceUnits = view.FindViewById<TextView>(Resource.Id.text_distance_units);
consumption = view.FindViewById<TextView>(Resource.Id.text_consumption);
consumptionUnits = view.FindViewById<TextView>(Resource.Id.text_consumption_units);
load = view.FindViewById<TextView>(Resource.Id.text_load);
stats = view.FindViewById<LinearLayout>(Resource.Id.stats);
stats.Visibility = ViewStates.Invisible;
return view;
}
public override void OnActivityCreated(Bundle savedInstanceState)
{
mapView.GetMapAsync(this);
base.OnActivityCreated(savedInstanceState);
}
void StartFadeAnimation(bool fadeIn)
{
//handle first run
if (!viewModel.IsRecording && stats.Visibility == ViewStates.Invisible)
return;
var start = fadeIn ? 0f : 1f;
var end = fadeIn ? 1f : 0f;
stats.Alpha = fadeIn ? 0f : 1f;
stats.Visibility = ViewStates.Visible;
var timerAnimator = ValueAnimator.OfFloat(start, end);
timerAnimator.SetDuration(Java.Util.Concurrent.TimeUnit.Seconds.ToMillis(1));
timerAnimator.SetInterpolator(new AccelerateInterpolator());
timerAnimator.Update +=
(sender, e) => { Activity.RunOnUiThread(() => stats.Alpha = (float) e.Animation.AnimatedValue); };
timerAnimator.Start();
}
void OnLocationServiceConnected(object sender, ServiceConnectedEventArgs e)
{
viewModel = GeolocationHelper.Current.LocationService.ViewModel;
viewModel.PropertyChanged += OnPropertyChanged;
ResetTrip();
}
void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(viewModel.CurrentPosition):
var latlng = viewModel.CurrentPosition.ToLatLng();
UpdateCar(latlng);
UpdateCamera(latlng);
break;
case nameof(viewModel.CurrentTrip):
TripSummaryActivity.ViewModel = viewModel.TripSummary;
ResetTrip();
StartActivity(new Android.Content.Intent(Activity, typeof (TripSummaryActivity)));
break;
case "Stats":
UpdateStats();
break;
}
}
void UpdateStats()
{
Activity?.RunOnUiThread(() =>
{
time.Text = viewModel.ElapsedTime;
consumption.Text = viewModel.FuelConsumption;
consumptionUnits.Text = viewModel.FuelConsumptionUnits;
load.Text = viewModel.EngineLoad;
distanceUnits.Text = viewModel.DistanceUnits;
distance.Text = viewModel.CurrentTrip.TotalDistanceNoUnits;
});
}
void ResetTrip()
{
trailPointList = viewModel.CurrentTrip.Points as ObservableRangeCollection<TripPoint>;
trailPointList.CollectionChanged += OnTrailUpdated;
carMarker = null;
map?.Clear();
allPoints?.Clear();
allPoints = null;
SetupMap();
UpdateStats();
StartFadeAnimation(viewModel.IsRecording);
Activity.SupportInvalidateOptionsMenu();
}
void AddStartMarker(LatLng start)
{
Activity?.RunOnUiThread(() =>
{
var logicalDensity = Resources.DisplayMetrics.Density;
var thicknessPoints = (int) Math.Ceiling(20*logicalDensity + .5f);
var b = ContextCompat.GetDrawable(Activity, Resource.Drawable.ic_start_point) as BitmapDrawable;
var finalIcon = Bitmap.CreateScaledBitmap(b.Bitmap, thicknessPoints, thicknessPoints, false);
var startMarker = new MarkerOptions();
startMarker.SetPosition(start);
startMarker.SetIcon(BitmapDescriptorFactory.FromBitmap(finalIcon));
startMarker.Anchor(.5f, .5f);
map.AddMarker(startMarker);
});
}
void AddEndMarker(LatLng end)
{
Activity?.RunOnUiThread(() =>
{
var logicalDensity = Resources.DisplayMetrics.Density;
var thicknessPoints = (int) Math.Ceiling(20*logicalDensity + .5f);
var b = ContextCompat.GetDrawable(Activity, Resource.Drawable.ic_end_point) as BitmapDrawable;
var finalIcon = Bitmap.CreateScaledBitmap(b.Bitmap, thicknessPoints, thicknessPoints, false);
var endMarker = new MarkerOptions();
endMarker.SetPosition(end);
endMarker.SetIcon(BitmapDescriptorFactory.FromBitmap(finalIcon));
endMarker.Anchor(.5f, .5f);
map.AddMarker(endMarker);
});
}
void OnTrailUpdated(object sender, NotifyCollectionChangedEventArgs e)
{
Activity?.RunOnUiThread(() =>
{
var item = viewModel.CurrentTrip.Points[viewModel.CurrentTrip.Points.Count - 1];
if (carMarker != null)
UpdateMap(item);
else
SetupMap();
});
}
void UpdateCarIcon(bool recording)
{
Activity?.RunOnUiThread(() =>
{
var logicalDensity = Resources.DisplayMetrics.Density;
var thicknessCar = (int) Math.Ceiling(26*logicalDensity + .5f);
var b =
ContextCompat.GetDrawable(Activity,
recording ? Resource.Drawable.ic_car_red : Resource.Drawable.ic_car_blue) as BitmapDrawable;
//var b = ContextCompat.GetDrawable(Activity, Resource.Drawable.ic_car) as BitmapDrawable;
var finalIcon = Bitmap.CreateScaledBitmap(b.Bitmap, thicknessCar, thicknessCar, false);
carMarker?.SetIcon(BitmapDescriptorFactory.FromBitmap(finalIcon));
fab.SetImageResource(recording ? Resource.Drawable.ic_stop : Resource.Drawable.ic_start);
});
}
void SetupMap()
{
if (map == null)
return;
if (mapView.Width == 0)
{
mapView.PostDelayed(SetupMap, 500);
return;
}
if (viewModel.CurrentTrip.HasSimulatedOBDData)
{
var activity = (BaseActivity) Activity;
activity.SupportActionBar.Title = "Current Trip (Sim OBD)";
}
TripPoint start = null;
if (viewModel.CurrentTrip.Points.Count != 0)
start = viewModel.CurrentTrip.Points[0];
UpdateMap(start, false);
if (start != null)
{
UpdateCamera(carMarker.Position);
AddStartMarker(start.ToLatLng());
}
}
void UpdateMap(TripPoint point, bool updateCamera = true)
{
if (map == null)
return;
//Get trail position or current potion to move car
var latlng = point == null
? viewModel?.CurrentPosition?.ToLatLng()
: point.ToLatLng();
Activity?.RunOnUiThread(() =>
{
UpdateCar(latlng);
driveLine?.Remove();
var polyOptions = new PolylineOptions();
if (allPoints == null)
{
allPoints = viewModel.CurrentTrip.Points.ToLatLngs();
}
else if (point != null)
{
allPoints.Add(point.ToLatLng());
}
polyOptions.Add(allPoints.ToArray());
if (!driveLineColor.HasValue)
driveLineColor = new Color(ContextCompat.GetColor(Activity, Resource.Color.recording_accent));
polyOptions.InvokeColor(driveLineColor.Value);
driveLine = map.AddPolyline(polyOptions);
if (updateCamera)
UpdateCamera(latlng);
});
}
void UpdateCar(LatLng latlng)
{
if (latlng == null || map == null)
return;
Activity?.RunOnUiThread(() =>
{
if (carMarker == null)
{
var car = new MarkerOptions();
car.SetPosition(latlng);
car.Anchor(.5f, .5f);
carMarker = map.AddMarker(car);
UpdateCarIcon(viewModel.IsRecording);
return;
}
carMarker.Position = latlng;
});
}
void UpdateCamera(LatLng latlng)
{
if (map == null)
return;
Activity?.RunOnUiThread(() =>
{
if (setZoom)
{
map.MoveCamera(CameraUpdateFactory.NewLatLngZoom(latlng, 14));
setZoom = false;
}
else
{
map.MoveCamera(CameraUpdateFactory.NewLatLng(latlng));
}
});
}
public override void OnStop()
{
base.OnStop();
GeolocationHelper.Current.LocationServiceConnected -= OnLocationServiceConnected;
if (viewModel != null)
viewModel.PropertyChanged -= OnPropertyChanged;
if (trailPointList != null)
trailPointList.CollectionChanged -= OnTrailUpdated;
if (fab != null)
fab.Click -= OnRecordButtonClick;
//If we are recording then don't stop the background service
if ((viewModel?.IsRecording).GetValueOrDefault())
return;
GeolocationHelper.Current.LocationService.StopLocationUpdates();
GeolocationHelper.StopLocationService();
}
public override async void OnStart()
{
base.OnStart();
GeolocationHelper.Current.LocationServiceConnected += OnLocationServiceConnected;
if (fab != null)
fab.Click += OnRecordButtonClick;
await StartLocationService();
}
async Task StartLocationService()
{
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
status = results[Permission.Location];
}
if (status == PermissionStatus.Granted)
{
if ((viewModel == null || !viewModel.IsRecording) && !GeolocationHelper.Current.IsRunning)
await GeolocationHelper.StartLocationService();
else
OnLocationServiceConnected(null, null);
}
else if (status != PermissionStatus.Unknown)
{
Toast.MakeText(Activity, "Location permission is not granted, can't track location",
ToastLength.Long);
}
}
catch (Exception ex)
{
Logger.Instance.Report(ex);
}
}
#region Options Menu & User Actions
public override void OnCreateOptionsMenu(IMenu menu, MenuInflater inflater)
{
//if((viewModel?.IsRecording).GetValueOrDefault())
// inflater.Inflate(Resource.Menu.menu_current_trip, menu);
base.OnCreateOptionsMenu(menu, inflater);
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.menu_take_photo:
if (!(viewModel?.IsBusy).GetValueOrDefault())
viewModel?.TakePhotoCommand.Execute(null);
break;
}
return base.OnOptionsItemSelected(item);
}
async void OnRecordButtonClick(object sender, EventArgs e)
{
if (viewModel?.CurrentPosition == null || viewModel.IsBusy)
return;
if (viewModel.NeedSave)
{
await viewModel.SaveRecordingTripAsync();
}
if (viewModel.IsRecording)
{
if (!await viewModel.StopRecordingTrip())
return;
AddEndMarker(viewModel.CurrentPosition.ToLatLng());
UpdateCarIcon(false);
var activity = (BaseActivity) Activity;
activity.SupportActionBar.Title = "Current Trip";
await viewModel.SaveRecordingTripAsync();
}
else
{
if (!await viewModel.StartRecordingTrip())
return;
AddStartMarker(viewModel.CurrentPosition.ToLatLng());
Activity.SupportInvalidateOptionsMenu();
UpdateCarIcon(true);
UpdateStats();
StartFadeAnimation(true);
if (viewModel.CurrentTrip.HasSimulatedOBDData)
{
var activity = (BaseActivity) Activity;
activity.SupportActionBar.Title = "Current Trip (Sim OBD)";
}
}
}
#endregion
#region MapView Lifecycle Events
public override void OnResume()
{
base.OnResume();
mapView?.OnResume();
}
public override void OnPause()
{
base.OnPause();
mapView?.OnPause();
}
public override void OnDestroy()
{
base.OnDestroy();
mapView?.OnDestroy();
}
public override void OnSaveInstanceState(Bundle outState)
{
base.OnSaveInstanceState(outState);
mapView?.OnSaveInstanceState(outState);
}
public override void OnLowMemory()
{
base.OnLowMemory();
mapView?.OnLowMemory();
}
#endregion
}
}

View File

@ -0,0 +1,78 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Android.OS;
using Fragment = Android.Support.V4.App.Fragment;
using Android.Views;
using Android.Widget;
using Android.Content;
using MyDriving.Droid.Activities;
namespace MyDriving.Droid.Fragments
{
public class FragmentGettingStarted1 : Fragment
{
public static FragmentGettingStarted1 NewInstance() => new FragmentGettingStarted1 {Arguments = new Bundle()};
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
return inflater.Inflate(Resource.Layout.fragment_started_1, null);
}
}
public class FragmentGettingStarted2 : Fragment
{
public static FragmentGettingStarted2 NewInstance() => new FragmentGettingStarted2 {Arguments = new Bundle()};
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
return inflater.Inflate(Resource.Layout.fragment_started_2, null);
}
}
public class FragmentGettingStarted3 : Fragment
{
public static FragmentGettingStarted3 NewInstance() => new FragmentGettingStarted3 {Arguments = new Bundle()};
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
return inflater.Inflate(Resource.Layout.fragment_started_3, null);
}
}
public class FragmentGettingStarted4 : Fragment
{
public static FragmentGettingStarted4 NewInstance() => new FragmentGettingStarted4 {Arguments = new Bundle()};
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
return inflater.Inflate(Resource.Layout.fragment_started_4, null);
}
}
public class FragmentGettingStarted5 : Fragment
{
public static FragmentGettingStarted5 NewInstance() => new FragmentGettingStarted5 {Arguments = new Bundle()};
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
var view = inflater.Inflate(Resource.Layout.fragment_started_5, null);
view.FindViewById<Button>(Resource.Id.button_close).Click += (sender, args) =>
{
var intent = new Intent(Activity, typeof (LoginActivity));
intent.AddFlags(ActivityFlags.ClearTop);
Activity.StartActivity(intent);
Activity.Finish();
};
return view;
}
}
}

View File

@ -0,0 +1,209 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Android.OS;
using Android.Support.V4.App;
using Android.Views;
using Android.Support.V7.Widget;
using Android.Support.V4.Widget;
using Android.Widget;
using MyDriving.ViewModel;
using System;
using MyDriving.Droid.Activities;
using Android.Content;
namespace MyDriving.Droid.Fragments
{
public class FragmentPastTrips : Fragment
{
TripAdapter adapter;
LinearLayoutManager layoutManager;
RecyclerView recyclerView;
SwipeRefreshLayout refresher;
PastTripsViewModel viewModel;
public static FragmentPastTrips NewInstance() => new FragmentPastTrips {Arguments = new Bundle()};
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
var view = inflater.Inflate(Resource.Layout.fragment_past_trips, null);
viewModel = new PastTripsViewModel();
recyclerView = view.FindViewById<RecyclerView>(Resource.Id.recyclerView);
refresher = view.FindViewById<SwipeRefreshLayout>(Resource.Id.refresher);
refresher.Refresh += (sender, e) => viewModel.LoadPastTripsCommand.Execute(null);
adapter = new TripAdapter(Activity, viewModel);
adapter.ItemClick += OnItemClick;
adapter.ItemLongClick += OnItemLongClick;
layoutManager = new LinearLayoutManager(Activity) {Orientation = LinearLayoutManager.Vertical};
recyclerView.SetLayoutManager(layoutManager);
recyclerView.SetAdapter(adapter);
recyclerView.ClearOnScrollListeners();
recyclerView.AddOnScrollListener(new TripsOnScrollListenerListener(viewModel, layoutManager));
return view;
}
public override async void OnStart()
{
base.OnStart();
viewModel.PropertyChanged += ViewModel_PropertyChanged;
if (viewModel.Trips.Count == 0)
await viewModel.ExecuteLoadPastTripsCommandAsync();
}
void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(viewModel.IsBusy):
refresher.Refreshing = viewModel.IsBusy;
break;
}
}
public override void OnStop()
{
base.OnStop();
viewModel.PropertyChanged -= ViewModel_PropertyChanged;
}
void OnItemClick(object sender, TripClickEventArgs args)
{
var trip = viewModel.Trips[args.Position];
var intent = new Intent(Activity, typeof (PastTripDetailsActivity));
intent.PutExtra("Id", trip.Id);
intent.PutExtra("Rating", trip.Rating);
PastTripDetailsActivity.Trip = trip;
Activity.StartActivity(intent);
}
async void OnItemLongClick(object sender, TripClickEventArgs args)
{
var trip = viewModel.Trips[args.Position];
await viewModel.ExecuteDeleteTripCommand(trip);
}
class TripsOnScrollListenerListener : RecyclerView.OnScrollListener
{
readonly LinearLayoutManager layoutManager;
readonly PastTripsViewModel viewModel;
public TripsOnScrollListenerListener(PastTripsViewModel viewModel, LinearLayoutManager layoutManager)
{
this.layoutManager = layoutManager;
this.viewModel = viewModel;
}
public override void OnScrolled(RecyclerView recyclerView, int dx, int dy)
{
base.OnScrolled(recyclerView, dx, dy);
if (viewModel.IsBusy || viewModel.Trips.Count == 0 || !viewModel.CanLoadMore)
return;
var lastVisiblePosition = layoutManager.FindLastCompletelyVisibleItemPosition();
if (lastVisiblePosition == RecyclerView.NoPosition)
return;
//if we are at the bottom and can load more.
if (lastVisiblePosition == viewModel.Trips.Count - 1)
viewModel.LoadMorePastTripCommand.Execute(null);
}
}
}
public class TripViewHolder : RecyclerView.ViewHolder
{
public TripViewHolder(View itemView, Action<TripClickEventArgs> listener,
Action<TripClickEventArgs> listenerLong) : base(itemView)
{
itemView.LongClickable = true;
Title = itemView.FindViewById<TextView>(Resource.Id.text_title);
Distance = itemView.FindViewById<TextView>(Resource.Id.text_distance);
Date = itemView.FindViewById<TextView>(Resource.Id.text_date);
Photo = itemView.FindViewById<ImageView>(Resource.Id.photo);
itemView.Click +=
(sender, e) => listener(new TripClickEventArgs {View = sender as View, Position = AdapterPosition});
itemView.LongClick +=
(sender, e) => listenerLong(new TripClickEventArgs {View = sender as View, Position = AdapterPosition});
}
public TextView Title { get; set; }
public TextView Date { get; set; }
public TextView Distance { get; set; }
public ImageView Photo { get; set; }
}
public class TripClickEventArgs : EventArgs
{
public View View { get; set; }
public int Position { get; set; }
}
public class TripAdapter : RecyclerView.Adapter
{
readonly Android.App.Activity activity;
readonly PastTripsViewModel viewModel;
public TripAdapter(Android.App.Activity activity, PastTripsViewModel viewModel)
{
this.activity = activity;
this.viewModel = viewModel;
this.viewModel.Trips.CollectionChanged +=
(sender, e) => { this.activity.RunOnUiThread(NotifyDataSetChanged); };
}
public override int ItemCount => viewModel.Trips.Count;
public event EventHandler<TripClickEventArgs> ItemClick;
public event EventHandler<TripClickEventArgs> ItemLongClick;
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) =>
new TripViewHolder(LayoutInflater.From(parent.Context).Inflate(Resource.Layout.item_trip, parent, false),
OnClick, OnClickLong);
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var vh = holder as TripViewHolder;
if (vh == null)
return;
var trip = viewModel.Trips[position];
vh.Title.Text = trip.Name;
vh.Distance.Text = trip.TotalDistance;
vh.Date.Text = trip.TimeAgo;
vh.Photo.Visibility = (trip?.Photos?.Count).GetValueOrDefault() > 0 ||
!string.IsNullOrWhiteSpace(trip.MainPhotoUrl)
? ViewStates.Visible
: ViewStates.Gone;
if (vh.Photo.Visibility == ViewStates.Visible)
{
if ((trip?.Photos?.Count).GetValueOrDefault() > 0)
Square.Picasso.Picasso.With(activity).Load($"file://{trip.Photos[0].PhotoUrl}").Into(vh.Photo);
else
Square.Picasso.Picasso.With(activity).Load(trip.MainPhotoUrl).Into(vh.Photo);
}
}
void OnClick(TripClickEventArgs args)
{
ItemClick?.Invoke(this, args);
}
void OnClickLong(TripClickEventArgs args)
{
ItemLongClick?.Invoke(this, args);
}
}
}

View File

@ -0,0 +1,97 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Android.OS;
using Android.Support.V4.App;
using Android.Views;
using MyDriving.Droid.Controls;
using Refractored.Controls;
using MyDriving.Utils;
using MyDriving.ViewModel;
using Android.Widget;
namespace MyDriving.Droid.Fragments
{
public class FragmentProfile : Fragment
{
CircleImageView circleImage;
TextView distance,
maxSpeed,
time,
stops,
accelerations,
trips,
fuelUsed,
distanceUnits,
profileRating,
profileGreat;
LinearLayout profileAll;
RatingCircle ratingCircle;
bool refresh = true;
ProfileViewModel viewModel;
public static FragmentProfile NewInstance() => new FragmentProfile {Arguments = new Bundle()};
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
var view = inflater.Inflate(Resource.Layout.fragment_profile, null);
ratingCircle = view.FindViewById<RatingCircle>(Resource.Id.rating_circle);
circleImage = view.FindViewById<CircleImageView>(Resource.Id.profile_image);
viewModel = new ProfileViewModel();
Square.Picasso.Picasso.With(Activity).Load(Settings.Current.UserProfileUrl).Into(circleImage);
trips = view.FindViewById<TextView>(Resource.Id.text_trips);
time = view.FindViewById<TextView>(Resource.Id.text_time);
distance = view.FindViewById<TextView>(Resource.Id.text_distance);
maxSpeed = view.FindViewById<TextView>(Resource.Id.text_max_speed);
fuelUsed = view.FindViewById<TextView>(Resource.Id.text_fuel_consumption);
accelerations = view.FindViewById<TextView>(Resource.Id.text_hard_accelerations);
stops = view.FindViewById<TextView>(Resource.Id.text_hard_breaks);
profileAll = view.FindViewById<LinearLayout>(Resource.Id.text_profile_all);
profileGreat = view.FindViewById<TextView>(Resource.Id.text_profile_great);
profileRating = view.FindViewById<TextView>(Resource.Id.text_profile_rating);
profileAll.Visibility = ViewStates.Invisible;
UpdateUI();
return view;
}
public override void OnStart()
{
base.OnStart();
if (refresh)
{
refresh = false;
viewModel.UpdateProfileAsync().ContinueWith(t => UpdateUI());
}
}
void UpdateUI()
{
Activity.RunOnUiThread(() =>
{
trips.Text = viewModel.TotalTrips.ToString();
time.Text = viewModel.TotalTimeDisplay;
distance.Text = viewModel.TotalDistanceDisplay;
maxSpeed.Text = viewModel.MaxSpeedDisplay;
fuelUsed.Text = viewModel.FuelDisplay;
accelerations.Text = viewModel.HardAccelerations.ToString();
stops.Text = viewModel.HardStops.ToString();
ratingCircle.Rating = viewModel.DrivingSkills;
profileGreat.Text = $"Driving Skills: {viewModel.DrivingSkillsPlacementBucket.Description}";
profileRating.Text = $"{viewModel.DrivingSkills.ToString()}%";
profileAll.Visibility = ViewStates.Visible;
});
}
}
}

View File

@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Android.OS;
using Android.Support.V7.Preferences;
using MyDriving.ViewModel;
namespace MyDriving.Droid.Fragments
{
public class FragmentSettings : PreferenceFragmentCompat
{
SettingsViewModel viewModel;
public static FragmentSettings NewInstance() => new FragmentSettings {Arguments = new Bundle()};
public override void OnCreatePreferences(Bundle p0, string p1)
{
AddPreferencesFromResource(Resource.Xml.preferences);
viewModel = new SettingsViewModel();
}
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
FindPreference("url_privacy").PreferenceClick +=
(sender, args) => viewModel.OpenBrowserCommand.Execute(viewModel.PrivacyPolicyUrl);
FindPreference("url_copyright").PreferenceClick +=
(sender, args) => viewModel.OpenBrowserCommand.Execute(viewModel.PrivacyPolicyUrl);
FindPreference("url_xamarin").PreferenceClick +=
(sender, args) => viewModel.OpenBrowserCommand.Execute(viewModel.XamarinUrl);
FindPreference("url_terms").PreferenceClick +=
(sender, args) => viewModel.OpenBrowserCommand.Execute(viewModel.TermsOfUseUrl);
FindPreference("url_open_notice").PreferenceClick +=
(sender, args) => viewModel.OpenBrowserCommand.Execute(viewModel.OpenSourceNoticeUrl);
FindPreference("url_github").PreferenceClick +=
(sender, args) => viewModel.OpenBrowserCommand.Execute(viewModel.SourceOnGitHubUrl);
FindPreference("leave_feedback").PreferenceClick +=
(sender, args) => HockeyApp.FeedbackManager.ShowFeedbackActivity(Activity);
}
}
}