Skip to content

Commit aa7895f

Browse files
committed
Improved global UI.
Fixed few bugs New screenshots and offline data
1 parent f5425c9 commit aa7895f

21 files changed

+838
-162
lines changed

Data/Hiver 2015/L4/L4.R0.Trajectory.txt

+552
Large diffs are not rendered by default.

Screenshots/Screenshot 1.png

-121 Bytes
Loading

Screenshots/Screenshot 2.png

14.3 KB
Loading

Screenshots/Screenshot 3.png

720 KB
Loading

Screenshots/Screenshot 4.png

14.6 KB
Loading

Screenshots/Screenshot 5.png

115 KB
Loading

TramUrWay.Android/Activities/Line/LineActivity.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,14 @@ protected override void OnCreate(Bundle savedInstanceState)
9696
viewPager = FindViewById<ViewPager>(Resource.Id.LineActivity_ViewPager);
9797
viewPager.OffscreenPageLimit = fragments.Count;
9898
viewPager.Adapter = new TabFragmentsAdapter(SupportFragmentManager, fragments.ToArray());
99-
viewPager.SetCurrentItem(1, false);
99+
100+
if (extras != null && extras.ContainsKey("Route"))
101+
{
102+
int routeId = extras.GetInt("Route");
103+
viewPager.SetCurrentItem(1 + routeId, false);
104+
}
105+
else
106+
viewPager.SetCurrentItem(1, false);
100107

101108
TabLayout tabLayout = FindViewById<TabLayout>(Resource.Id.LineActivity_Tabs);
102109
tabLayout.SetBackgroundColor(color);

TramUrWay.Android/Activities/Line/LineMapFragment.cs

+64-44
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.Linq;
44
using System.Threading;
55
using System.Threading.Tasks;
6-
6+
using Android.Animation;
77
using Android.Gms.Maps;
88
using Android.Gms.Maps.Model;
99
using Android.Graphics;
@@ -13,12 +13,43 @@
1313
using Android.Utilities;
1414
using Android.Views;
1515

16-
using Java.Lang;
16+
using Activity = Android.App.Activity;
1717

1818
namespace TramUrWay.Android
1919
{
20-
public class LineMapFragment : TabFragment, IOnMapReadyCallback
20+
public class LineMapFragment : TabFragment, IOnMapReadyCallback, GoogleMap.IOnMapLoadedCallback
2121
{
22+
public class MarkerAnimator : Java.Lang.Object, ValueAnimator.IAnimatorUpdateListener
23+
{
24+
private Activity activity;
25+
private Marker marker;
26+
private Transport transport;
27+
private Action<LatLng> positionUpdater;
28+
29+
public MarkerAnimator(Activity activity, Marker marker, Transport transport, Action<LatLng> positionUpdater)
30+
{
31+
this.activity = activity;
32+
this.marker = marker;
33+
this.transport = transport;
34+
this.positionUpdater = positionUpdater;
35+
}
36+
37+
public void OnAnimationUpdate(ValueAnimator animation)
38+
{
39+
float progress = transport.Progress + (transport.NextProgress - transport.Progress) * animation.AnimatedFraction;
40+
int index = transport.Step.Trajectory.TakeWhile(s => s.Index <= progress).Count();
41+
42+
bool last = index >= transport.Step.Trajectory.Length;
43+
TrajectoryStep from = transport.Step.Trajectory[index - 1];
44+
TrajectoryStep to = last ? transport.TimeStep.Step.Trajectory.First() : transport.Step.Trajectory[index];
45+
46+
progress = (progress - from.Index) / ((last ? 1 : to.Index) - from.Index);
47+
LatLng position = new LatLng(from.Position.Latitude + (to.Position.Latitude - from.Position.Latitude) * progress, from.Position.Longitude + (to.Position.Longitude - from.Position.Longitude) * progress);
48+
49+
positionUpdater(position);
50+
}
51+
}
52+
2253
private const int StopIconSize = 10;
2354
private const int TransportIconSize = 22;
2455

@@ -29,6 +60,7 @@ public class LineMapFragment : TabFragment, IOnMapReadyCallback
2960

3061
private SupportMapFragment mapFragment;
3162
private GoogleMap googleMap;
63+
private Dictionary<Transport, Marker> transportMarkers = new Dictionary<Transport, Marker>();
3264

3365
private BitmapDescriptor stopBitmapDescriptor;
3466
private BitmapDescriptor transportBitmapDescriptor;
@@ -67,56 +99,18 @@ public void OnMapReady(GoogleMap googleMap)
6799
googleMap.UiSettings.MapToolbarEnabled = true;
68100

69101
// Register events
102+
mapFragment.View.Post(OnMapLoaded);
70103
//googleMap.CameraChange += GoogleMap_CameraChange;
71104
//googleMap.MarkerClick += GoogleMap_MarkerClick;
72105
//googleMap.MapClick += GoogleMap_MapClick;
73106

74107
// Preload icons
75108
Task iconLoader = Task.Run(() =>
76109
{
77-
float density = Resources.DisplayMetrics.Density;
78-
Paint paint = new Paint();
79-
80-
// Station icon
81-
int stopIconSize = (int)(StopIconSize * density);
82-
Bitmap stopBitmap = Bitmap.CreateBitmap(stopIconSize, stopIconSize, Bitmap.Config.Argb8888);
83-
Canvas stopCanvas = new Canvas(stopBitmap);
84-
85-
paint.SetARGB(color.A, color.R, color.G, color.B);
86-
stopCanvas.DrawCircle(stopIconSize / 2, stopIconSize / 2, stopIconSize / 2, paint);
87-
88-
paint.SetARGB(0xFF, 0xFF, 0xFF, 0xFF);
89-
stopCanvas.DrawCircle(stopIconSize / 2, stopIconSize / 2, stopIconSize / 2 - (int)(density * 2), paint);
90-
91-
stopBitmapDescriptor = BitmapDescriptorFactory.FromBitmap(stopBitmap);
92-
93-
// Line icon
94-
int transportIconSize = (int)(TransportIconSize * density);
95-
Drawable transportDrawable = Resources.GetDrawable(Resource.Drawable.train);
96-
Drawable transportDrawableOutline = Resources.GetDrawable(Resource.Drawable.train_glow);
97-
98-
Bitmap transportBitmap = Bitmap.CreateBitmap(transportIconSize, transportIconSize, Bitmap.Config.Argb8888);
99-
Canvas transportCanvas = new Canvas(transportBitmap);
100-
101-
transportDrawableOutline.SetBounds(0, 0, transportIconSize, transportIconSize);
102-
transportDrawableOutline.Draw(transportCanvas);
103-
104-
transportDrawable.SetColorFilter(color, PorterDuff.Mode.SrcIn);
105-
transportDrawable.SetBounds(0, 0, transportIconSize, transportIconSize);
106-
transportDrawable.Draw(transportCanvas);
107-
108-
transportBitmapDescriptor = BitmapDescriptorFactory.FromBitmap(transportBitmap);
110+
stopBitmapDescriptor = BitmapDescriptorFactory.FromBitmap(Utils.GetStopIconForLine(Activity, line, StopIconSize));
111+
transportBitmapDescriptor = BitmapDescriptorFactory.FromBitmap(Utils.GetTransportIconForLine(Activity, line, TransportIconSize));
109112
});
110113

111-
// Compute global line bounds to initialize camera
112-
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
113-
foreach (Route route in line.Routes)
114-
foreach (Step step in route.Steps)
115-
boundsBuilder.Include(new LatLng(step.Stop.Position.Latitude, step.Stop.Position.Longitude));
116-
117-
CameraUpdate cameraUpdate = CameraUpdateFactory.NewLatLngBounds(boundsBuilder.Build(), 100);
118-
googleMap.MoveCamera(cameraUpdate);
119-
120114
// Add a polyline between steps
121115
foreach (Route route in line.Routes)
122116
{
@@ -154,12 +148,38 @@ public void OnMapReady(GoogleMap googleMap)
154148
googleMap.AddMarker(marker);
155149
}
156150
}
151+
public void OnMapLoaded()
152+
{
153+
// Compute global line bounds to initialize camera
154+
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
155+
foreach (Route route in line.Routes)
156+
foreach (Step step in route.Steps)
157+
boundsBuilder.Include(new LatLng(step.Stop.Position.Latitude, step.Stop.Position.Longitude));
158+
159+
CameraUpdate cameraUpdate = CameraUpdateFactory.NewLatLngBounds(boundsBuilder.Build(), 100);
160+
googleMap.MoveCamera(cameraUpdate);
161+
}
157162

158163
public void OnRefreshing()
159164
{
160165
}
161166
public void OnRefreshed(IEnumerable<TimeStep> timeSteps, IEnumerable<Transport> transports)
162167
{
168+
List<Transport> unusedTransports = transportMarkers.Keys.ToList();
169+
170+
foreach (Transport transport in transports)
171+
{
172+
Marker marker;
173+
174+
if (!transportMarkers.TryGetValue(transport, out marker))
175+
{
176+
177+
}
178+
else
179+
{
180+
unusedTransports.Remove(transport);
181+
}
182+
}
163183
}
164184
}
165185
}

TramUrWay.Android/Activities/Main/MainActivity.cs

+24-5
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ protected override void OnCreate(Bundle savedInstanceState)
6161
// Tabs
6262
viewPager = FindViewById<ViewPager>(Resource.Id.MainActivity_ViewPager);
6363
viewPager.Adapter = fragmentsAdapter = new TabFragmentsAdapter(SupportFragmentManager, favoritesFragment, linesFragment, stopsFragment);
64+
viewPager.PageSelected += ViewPager_PageSelected;
6465

6566
TabLayout tabLayout = FindViewById<TabLayout>(Resource.Id.MainActivity_Tabs);
6667
tabLayout.SetupWithViewPager(viewPager);
@@ -132,17 +133,35 @@ public override bool OnCreateOptionsMenu(IMenu menu)
132133
return base.OnCreateOptionsMenu(menu);
133134
}
134135

136+
private void ViewPager_PageSelected(object sender, ViewPager.PageSelectedEventArgs e)
137+
{
138+
if (e.Position != 2 && !string.IsNullOrEmpty(searchView?.Query))
139+
{
140+
RunOnUiThread(() =>
141+
{
142+
lastSearch = " ";
143+
144+
searchView.SetQuery("", true);
145+
stopsFragment.OnQueryTextChanged(sender, new QueryTextChangeEventArgs(true, ""));
146+
});
147+
}
148+
}
135149
private void SearchView_QueryTextChange(object sender, QueryTextChangeEventArgs e)
136150
{
137-
searchView.Post(() =>
151+
if (e.NewText.Length > 0)
138152
{
139-
viewPager.SetCurrentItem(2, true);
140-
stopsFragment.OnQueryTextChanged(sender, e);
141-
});
153+
RunOnUiThread(() =>
154+
{
155+
if (viewPager.CurrentItem != 2)
156+
viewPager.SetCurrentItem(2, true);
157+
158+
stopsFragment.OnQueryTextChanged(sender, e);
159+
});
160+
}
142161

143162
if (lastSearch.Length > 1 && e.NewText.Length == 0)
144163
{
145-
searchView.Post(() =>
164+
RunOnUiThread(() =>
146165
{
147166
searchView.ClearFocus();
148167
searchView.Iconified = true;

TramUrWay.Android/Activities/StopActivity.cs

+4
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ await Task.Run(() =>
254254
}
255255
private void OnRefreshed()
256256
{
257+
swipeRefresh.Post(() => swipeRefresh.Refreshing = false);
258+
257259
if (stop != null && timeSteps != null)
258260
{
259261
TimeStep[] lineSteps = timeSteps.Where(s => s.Step.Stop.Line == line)
@@ -268,6 +270,8 @@ private void OnRefreshed()
268270

269271
otherLabel.Visibility = otherSteps.Length == 0 ? ViewStates.Gone : ViewStates.Visible;
270272
}
273+
274+
swipeRefresh.PostDelayed(() => swipeRefresh.Refreshing = false, 1000);
271275
}
272276
}
273277
}

TramUrWay.Android/Adapters/RouteAdapter.cs

+32-8
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ namespace TramUrWay.Android
2020
{
2121
public class StepViewHolder : RecyclerView.ViewHolder
2222
{
23-
public View Rail { get; }
23+
public View Rail1 { get; }
24+
public View Rail2 { get; }
2425
public ImageView Icon1 { get; }
2526
public ImageView Icon2 { get; }
27+
public ImageView Dot { get; }
2628
public TextView Name { get; }
2729
public TextView Description { get; }
2830
public ImageView Favorite { get; }
@@ -31,9 +33,11 @@ public class StepViewHolder : RecyclerView.ViewHolder
3133

3234
public StepViewHolder(View itemView) : base(itemView)
3335
{
34-
Rail = itemView.FindViewById(Resource.Id.StepItem_Rail);
36+
Rail1 = itemView.FindViewById(Resource.Id.StepItem_Rail1);
37+
Rail2 = itemView.FindViewById(Resource.Id.StepItem_Rail2);
3538
Icon1 = itemView.FindViewById<ImageView>(Resource.Id.StepItem_Icon1);
3639
Icon2 = itemView.FindViewById<ImageView>(Resource.Id.StepItem_Icon2);
40+
Dot = itemView.FindViewById<ImageView>(Resource.Id.StepItem_Dot);
3741
Name = itemView.FindViewById<TextView>(Resource.Id.StepItem_Name);
3842
Description = itemView.FindViewById<TextView>(Resource.Id.StepItem_Description);
3943
Favorite = itemView.FindViewById<ImageView>(Resource.Id.StepItem_Favorite);
@@ -44,6 +48,9 @@ public StepViewHolder(View itemView) : base(itemView)
4448

4549
public class RouteAdapter : RecyclerView.Adapter, View.IOnClickListener
4650
{
51+
private const int StopIconSize = 32;
52+
private const int TransportIconSize = 48;
53+
4754
public override int ItemCount
4855
{
4956
get
@@ -58,6 +65,9 @@ public override int ItemCount
5865
private Transport[] stepTransports;
5966
private Color color;
6067

68+
private Bitmap stopBitmap;
69+
private Bitmap transportBitmap;
70+
6171
public RouteAdapter(Route route)
6272
{
6373
Route = route;
@@ -75,17 +85,30 @@ public void Update(IEnumerable<TimeStep> timeSteps, IEnumerable<Transport> trans
7585
}
7686

7787
stepTimes = Route.Steps.Select(s => timeSteps.Where(t => t.Step == s).ToArray()).ToArray();
78-
stepTransports = Route.Steps.Select(s => transports.FirstOrDefault(t => t.TimeStep.Step == s)).ToArray();
88+
stepTransports = Route.Steps.Select(s => transports.FirstOrDefault(t => t.Step == s)).ToArray();
7989

8090
NotifyDataSetChanged();
8191
}
8292

8393
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
8494
{
95+
// Late load icons
96+
if (stopBitmap == null)
97+
{
98+
stopBitmap = Utils.GetStopIconForLine(parent.Context, Route.Line, StopIconSize);
99+
transportBitmap = Utils.GetTransportIconForLine(parent.Context, Route.Line, TransportIconSize);
100+
}
101+
85102
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.StepItem, parent, false);
86103
itemView.SetOnClickListener(this);
87104

88-
return new StepViewHolder(itemView) { FavoriteClick = Favorite_Click };
105+
StepViewHolder viewHolder = new StepViewHolder(itemView) { FavoriteClick = Favorite_Click };
106+
107+
viewHolder.Icon1.SetImageBitmap(transportBitmap);
108+
viewHolder.Icon2.SetImageBitmap(transportBitmap);
109+
viewHolder.Dot.SetImageBitmap(stopBitmap);
110+
111+
return viewHolder;
89112
}
90113
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
91114
{
@@ -97,10 +120,11 @@ public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int positi
97120
{
98121
viewHolder.Name.Text = step.Stop.Name;
99122

100-
// Update colors
101-
viewHolder.Rail.SetBackgroundColor(color);
102-
viewHolder.Icon1.SetColorFilter(color);
103-
viewHolder.Icon2.SetColorFilter(color);
123+
viewHolder.Rail1.SetBackgroundColor(color);
124+
viewHolder.Rail2.SetBackgroundColor(color);
125+
126+
viewHolder.Rail1.Visibility = position == 0 ? ViewStates.Gone : ViewStates.Visible;
127+
viewHolder.Rail2.Visibility = position == Route.Steps.Length - 1 ? ViewStates.Gone : ViewStates.Visible;
104128
}
105129

106130
// Update texts

TramUrWay.Android/Adapters/TimeStepsAdapter.cs

+6
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ public void OnClick(View view)
7272
{
7373
TimeStepViewHolder viewHolder = viewHolders.First(vh => vh.ItemView == view);
7474
TimeStep timeStep = timeSteps[viewHolder.AdapterPosition];
75+
76+
Intent intent = new Intent(view.Context, typeof(LineActivity));
77+
intent.PutExtra("Line", timeStep.Step.Route.Line.Id);
78+
intent.PutExtra("Route", timeStep.Step.Route.Id);
79+
80+
view.Context.StartActivity(intent);
7581
}
7682
}
7783
}

TramUrWay.Android/Assets/L4.json

+1-1
Large diffs are not rendered by default.

TramUrWay.Android/Model/Transport.cs

+11-8
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,22 @@ public static void Update(this List<Transport> me, IEnumerable<TimeStep> steps,
3838
{
3939
Dictionary<Step, TimeStep> stepTimeSteps = timeSteps.GroupBy(s => s.Step)
4040
.ToDictionary(g => g.Key, g => g.OrderBy(s => s.Date).First());
41-
Step step = route.Steps.First();
42-
Step nextStep = step.Next;
41+
Step step = null;
42+
Step nextStep = route.Steps.First();
4343

4444
for (; nextStep != null; step = nextStep, nextStep = nextStep.Next)
4545
{
46-
TimeStep timeStep, nextTimeStep;
46+
TimeStep nextTimeStep;
4747
if (!stepTimeSteps.TryGetValue(nextStep, out nextTimeStep))
4848
continue;
4949

50-
stepTimeSteps.TryGetValue(step, out timeStep);
51-
if (timeStep != null && timeStep.Date < nextTimeStep.Date)
50+
TimeStep timeStep = null;
51+
if (step != null)
52+
stepTimeSteps.TryGetValue(step, out timeStep);
53+
54+
if (step == null || (timeStep != null && timeStep.Date < nextTimeStep.Date))
5255
{
53-
timeSteps.Remove(timeStep);
56+
timeSteps.Remove(nextTimeStep);
5457
//if (nextTimeStep != null)
5558
// timeSteps.Remove(nextTimeStep);
5659
}
@@ -152,11 +155,11 @@ public static void UpdateProgress(this List<Transport> me, DateTime dateTime)
152155
if (duration == TimeSpan.Zero)
153156
duration = TimeSpan.FromMinutes(2);
154157

155-
float progress = (float)(1 - Math.Min(diff.TotalMinutes, duration.TotalMinutes) / duration.TotalMinutes);
158+
float progress = (float)(1 - diff.TotalMinutes / duration.TotalMinutes);
156159
if (progress < 0) progress = 0;
157160
if (progress > 1) progress = 1;
158161

159-
float nextProgress = (float)(1 - Math.Min(diff.Subtract(TimeSpan.FromSeconds(1)).TotalMinutes, duration.TotalMinutes) / duration.TotalMinutes);
162+
float nextProgress = (float)(1 - diff.Subtract(TimeSpan.FromSeconds(1)).TotalMinutes / duration.TotalMinutes);
160163
if (nextProgress < 0) nextProgress = 0;
161164
if (nextProgress > 1) nextProgress = 1;
162165

0 commit comments

Comments
 (0)