Update stats view layout

This commit is contained in:
Jimmy Shih
2013-05-07 09:51:00 -07:00
parent afa47ba26e
commit dfa60a44f6
20 changed files with 521 additions and 555 deletions
+2 -9
View File
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/ScrollView" > style="@style/StatsScrollView" >
<LinearLayout <LinearLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -44,14 +44,7 @@ limitations under the License.
<TextView <TextView
android:text="@string/marker_detail_statistics_title" android:text="@string/marker_detail_statistics_title"
style="@style/TextLarge.WithTopMargin" /> style="@style/TextLarge.WithTopMargin" />
<TableLayout <include layout="@layout/stats_content" />
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingTop="8dp"
android:shrinkColumns="0,2"
android:stretchColumns="0,2" >
<include layout="@layout/stats_core" />
</TableLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
+7 -36
View File
@@ -15,42 +15,13 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/ScrollView" > style="@style/StatsScrollView" >
<TableLayout <LinearLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:padding="8dp" android:orientation="vertical"
android:shrinkColumns="0,2" android:paddingLeft="8dp"
android:stretchColumns="0,2" > android:paddingRight="8dp" >
<!-- Speed on one line --> <include layout="@layout/stats_content" />
<TableRow> </LinearLayout>
<TextView
android:id="@+id/stats_speed_label"
style="@style/StatsLabel" />
</TableRow>
<TableRow>
<TextView
android:id="@+id/stats_speed_value"
style="@style/StatsValue" />
</TableRow>
<include layout="@layout/stats_core" />
<TableRow android:id="@+id/stats_coordinate_label_table_row" >
<TextView
android:text="@string/stats_latitude"
style="@style/StatsLabel" />
<TextView
android:layout_column="2"
android:text="@string/stats_longitude"
style="@style/StatsLabel" />
</TableRow>
<TableRow android:id="@+id/stats_coordinate_value_table_row" >
<TextView
android:id="@+id/stats_latitude_value"
style="@style/StatsValue" />
<TextView style="@style/StatsSpacer" />
<TextView
android:id="@+id/stats_longitude_value"
style="@style/StatsValue" />
</TableRow>
</TableLayout>
</ScrollView> </ScrollView>
+132
View File
@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Row 1: distance and speed -->
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<include
android:id="@+id/stats_distance"
layout="@layout/stats_large_item" />
<View style="@style/StatsVerticalSpacer" />
<include
android:id="@+id/stats_speed"
layout="@layout/stats_large_item" />
</LinearLayout>
<!-- Row 2: total time and average speed -->
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<include
android:id="@+id/stats_total_time"
layout="@layout/stats_large_item" />
<View style="@style/StatsVerticalSpacer" />
<include
android:id="@+id/stats_average_speed"
layout="@layout/stats_large_item" />
</LinearLayout>
<!-- Row 3: horizontal line -->
<View style="@style/StatsHorizontalLine" />
<!-- Row 3: moving time and average moving speed -->
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<include
android:id="@+id/stats_moving_time"
layout="@layout/stats_small_item" />
<View style="@style/StatsVerticalSpacer" />
<include
android:id="@+id/stats_average_moving_time"
layout="@layout/stats_small_item" />
</LinearLayout>
<!-- Row 4: empty and max speed -->
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<LinearLayout style="@style/StatsSmallItemContainer" />
<View style="@style/StatsVerticalSpacer" />
<include
android:id="@+id/stats_max_speed"
layout="@layout/stats_small_item" />
</LinearLayout>
<!-- Row 5: horizontal line -->
<View
android:id="@+id/stats_grade_elevation_horizontal_line"
style="@style/StatsHorizontalLine" />
<!-- Row 5: grade and elevation -->
<LinearLayout
android:id="@+id/stats_grade_elevation_container"
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<!-- Grade -->
<LinearLayout style="@style/StatsSmallItemContainer" >
<!-- Grade label -->
<TextView
android:text="@string/stats_grade"
style="@style/StatsSmallLabel" />
<!-- Grade min -->
<include
android:id="@+id/stats_grade_min"
layout="@layout/stats_small_item_1line" />
<!-- Grade max -->
<include
android:id="@+id/stats_grade_max"
layout="@layout/stats_small_item_1line" />
</LinearLayout>
<View style="@style/StatsVerticalSpacer" />
<!-- Elevation -->
<LinearLayout style="@style/StatsSmallItemContainer" >
<!-- Elevation label -->
<TextView
android:text="@string/stats_elevation"
style="@style/StatsSmallLabel" />
<!-- Elevation -->
<include
android:id="@+id/stats_elevation"
layout="@layout/stats_small_item_1line" />
<!-- Elevation gain -->
<include
android:id="@+id/stats_elevation_gain"
layout="@layout/stats_small_item_1line" />
<!-- Elevation min -->
<include
android:id="@+id/stats_elevation_min"
layout="@layout/stats_small_item_1line" />
<!-- Elevation max -->
<include
android:id="@+id/stats_elevation_max"
layout="@layout/stats_small_item_1line" />
</LinearLayout>
</LinearLayout>
<!-- Row 6: horizontal line -->
<View
android:id="@+id/stats_coordinate_horizontal_line"
style="@style/StatsHorizontalLine" />
<!-- Row 6: latitude and longitude -->
<LinearLayout
android:id="@+id/stats_coordinate_container"
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<include
android:id="@+id/stats_latitude"
layout="@layout/stats_small_item" />
<View style="@style/StatsVerticalSpacer" />
<include
android:id="@+id/stats_longitude"
layout="@layout/stats_small_item" />
</LinearLayout>
</merge>
-140
View File
@@ -1,140 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2012 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Total distance -->
<TableRow>
<TextView
android:text="@string/stats_distance"
style="@style/StatsLabel" />
</TableRow>
<TableRow>
<TextView
android:id="@+id/stats_distance_value"
style="@style/StatsValue" />
</TableRow>
<!-- Total time/moving time -->
<TableRow>
<TextView
android:text="@string/stats_total_time"
style="@style/StatsLabel" />
<TextView
android:id="@+id/stats_moving_time_label"
android:layout_column="2"
android:text="@string/stats_moving_time"
style="@style/StatsLabel" />
</TableRow>
<TableRow>
<TextView
android:id="@+id/stats_total_time_value"
style="@style/StatsValue" />
<TextView
android:id="@+id/stats_moving_time_spacer"
style="@style/StatsSpacer" />
<TextView
android:id="@+id/stats_moving_time_value"
style="@style/StatsValue" />
</TableRow>
<!-- Average speed/average moving speed (average pace/average moving pace) -->
<TableRow>
<TextView
android:id="@+id/stats_average_speed_label"
style="@style/StatsLabel" />
<TextView
android:id="@+id/stats_average_moving_speed_label"
android:layout_column="2"
style="@style/StatsLabel" />
</TableRow>
<TableRow>
<TextView
android:id="@+id/stats_average_speed_value"
style="@style/StatsValue" />
<TextView
android:id="@+id/stats_average_moving_speed_spacer"
style="@style/StatsSpacer" />
<TextView
android:id="@+id/stats_average_moving_speed_value"
style="@style/StatsValue" />
</TableRow>
<!-- Max speed (fastest pace) -->
<TableRow>
<TextView
android:id="@+id/stats_max_speed_label"
style="@style/StatsLabel" />
</TableRow>
<TableRow>
<TextView
android:id="@+id/stats_max_speed_value"
style="@style/StatsValue" />
</TableRow>
<!-- Elevation and elevation gain -->
<TableRow android:id="@+id/stats_elevation_label_table_row1" >
<TextView
android:text="@string/stats_elevation"
style="@style/StatsLabel" />
<TextView
android:layout_column="2"
android:text="@string/stats_elevation_gain"
style="@style/StatsLabel" />
</TableRow>
<TableRow android:id="@+id/stats_elevation_value_table_row1" >
<TextView
android:id="@+id/stats_elevation_value"
style="@style/StatsValue" />
<TextView style="@style/StatsSpacer" />
<TextView
android:id="@+id/stats_elevation_gain_value"
style="@style/StatsValue" />
</TableRow>
<!-- Min and max elevation -->
<TableRow android:id="@+id/stats_elevation_label_table_row2" >
<TextView
android:text="@string/stats_min_elevation"
style="@style/StatsLabel" />
<TextView
android:layout_column="2"
android:text="@string/stats_max_elevation"
style="@style/StatsLabel" />
</TableRow>
<TableRow android:id="@+id/stats_elevation_value_table_row2" >
<TextView
android:id="@+id/stats_min_elevation_value"
style="@style/StatsValue" />
<TextView style="@style/StatsSpacer" />
<TextView
android:id="@+id/stats_max_elevation_value"
style="@style/StatsValue" />
</TableRow>
<!-- Min and max grade -->
<TableRow android:id="@+id/stats_grade_label_table_row" >
<TextView
android:text="@string/stats_min_grade"
style="@style/StatsLabel" />
<TextView
android:layout_column="2"
android:text="@string/stats_max_grade"
style="@style/StatsLabel" />
</TableRow>
<TableRow android:id="@+id/stats_grade_value_table_row" >
<TextView
android:id="@+id/stats_min_grade_value"
style="@style/StatsValue" />
<TextView style="@style/StatsSpacer" />
<TextView
android:id="@+id/stats_max_grade_value"
style="@style/StatsValue" />
</TableRow>
</merge>
+33
View File
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/stats_large_item_id"
style="@style/StatsLargeItemContainer" >
<!-- Distance label -->
<TextView
android:id="@+id/stats_label"
style="@style/StatsLargeLabel" />
<!-- Distance value -->
<LinearLayout style="@style/StatsLargeValueContainer" >
<TextView
android:id="@+id/stats_value"
style="@style/StatsLargeValue" />
<TextView
android:id="@+id/stats_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
+32
View File
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/stats_small_item_id"
style="@style/StatsSmallItemContainer" >
<TextView
android:id="@+id/stats_label"
style="@style/StatsSmallLabel" />
<!-- Distance value -->
<LinearLayout style="@style/StatsSmallValueContainer" >
<TextView
android:id="@+id/stats_value"
style="@style/StatsSmallValue" />
<TextView
android:id="@+id/stats_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
Copyright 2012 Google Inc. Copyright 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/ScrollView"> android:id="@+id/stats_small_1line_id"
<TableLayout style="@style/StatsSmallValueContainer" >
android:layout_height="wrap_content" <TextView
android:layout_width="match_parent" android:id="@+id/stats_value"
android:padding="8dp" style="@style/StatsSmallValue" />
android:shrinkColumns="0,2" <TextView
android:stretchColumns="0,2" > android:id="@+id/stats_unit"
<include layout="@layout/stats_core" /> style="@style/StatsUnit" />
</TableLayout> <TextView
</ScrollView> android:id="@+id/stats_label"
android:layout_gravity="bottom"
android:paddingLeft="8dp"
style="@style/StatsSmallLabel" />
</LinearLayout>
+17
View File
@@ -30,6 +30,23 @@ limitations under the License.
<item name="android:orientation">horizontal</item> <item name="android:orientation">horizontal</item>
<item name="android:measureWithLargestChild">true</item> <item name="android:measureWithLargestChild">true</item>
</style> </style>
<style name="StatsSmallLabel" parent="@style/TextSmall">
<!-- same as StatsSmallLabel in values/styles.xml except adding textAllCaps -->
<item name="android:gravity">right</item>
<item name="android:layout_gravity">right</item>
<item name="android:singleLine">false</item>
<item name="android:textAllCaps">true</item>
<item name="android:textStyle">bold</item>
</style>
<style name="StatsLargeLabel" parent="@style/TextSmall">
<!-- same as StatsLargeLabel in values/styles.xml except adding textAllCaps -->
<item name="android:gravity">right</item>
<item name="android:layout_gravity">right</item>
<item name="android:singleLine">false</item>
<item name="android:textAllCaps">true</item>
<item name="android:textColor">@color/stats_large_label</item>
<item name="android:textStyle">bold</item>
</style>
<style name="TextChooseActivity"> <style name="TextChooseActivity">
<!-- Same as TextChooseActivity in values/styles.xml except removing textSize and using textAppearance --> <!-- Same as TextChooseActivity in values/styles.xml except removing textSize and using textAppearance -->
<item name="android:textAppearance">?android:attr/textAppearanceListItemSmall</item> <item name="android:textAppearance">?android:attr/textAppearanceListItemSmall</item>
+1 -3
View File
@@ -53,9 +53,7 @@ limitations under the License.
<string name="share_track_key">shareTrack</string> <string name="share_track_key">shareTrack</string>
<string name="split_frequency_key">splitFrequency</string> <string name="split_frequency_key">splitFrequency</string>
<string name="stats_show_coordinate_key">statsShowCoordinate</string> <string name="stats_show_coordinate_key">statsShowCoordinate</string>
<string name="stats_show_elevation_key">statsShowElevation</string> <string name="stats_show_grade_elevation_key">statsShowGradeElevation</string>
<string name="stats_show_grade_key">statsShowGrade</string>
<string name="stats_show_moving_time_key">statsShowMovingTime</string>
<string name="track_color_mode_medium_key">trackColorModeMedium</string> <string name="track_color_mode_medium_key">trackColorModeMedium</string>
<string name="track_color_mode_percentage_key">trackColorModePercentage</string> <string name="track_color_mode_percentage_key">trackColorModePercentage</string>
<string name="track_color_mode_slow_key">trackColorModeSlow</string> <string name="track_color_mode_slow_key">trackColorModeSlow</string>
+19 -53
View File
@@ -2089,12 +2089,12 @@ limitations under the License.
Character limit: ~23 (1 line)"> Character limit: ~23 (1 line)">
Latitude/Longitude Latitude/Longitude
</string> </string>
<string name="settings_stats_grade" <string name="settings_stats_grade_elevation"
translation_description="In the 'Stats settings, the option to show grade. Grade is the amount translation_description="In the 'Stats settings, the option to show grade and elevation. Grade
of inclination to the horizontal, also known as slope or incline. is the amount of inclination to the horizontal, also known as slope or incline.
Character limit: ~23 (1 line)"> Character limit: ~23 (1 line)">
Grade Grade/Elevation
</string> </string>
<string name="settings_stats_rate_title" <string name="settings_stats_rate_title"
translation_description="In the 'Stats' settings, the option to change the preferred rate, translation_description="In the 'Stats' settings, the option to change the preferred rate,
@@ -2209,14 +2209,19 @@ limitations under the License.
Character limit: ~23 (1 line)"> Character limit: ~23 (1 line)">
Elevation Elevation
</string> </string>
<string name="stats_elevation_gain"
translation_description="In the 'Stats' page, the elevation gain.">
Elevation gain
</string>
<string name="stats_fastest_pace" <string name="stats_fastest_pace"
translation_description="In the 'Stats' page, the fastest pace."> translation_description="In the 'Stats' page, the fastest pace.">
Fastest pace Fastest pace
</string> </string>
<string name="stats_gain"
translation_description="In the 'Stats' page, the gain of a value. E.g, gain in elevation.">
Gain
</string>
<string name="stats_grade"
translation_description="In the 'Stats' page, the grade. Grade is the amount of inclination to
the horizontal, also known as slope or incline.">
Grade
</string>
<string name="stats_latitude" <string name="stats_latitude"
translation_description="In the 'Stats' page, the latitude."> translation_description="In the 'Stats' page, the latitude.">
Latitude Latitude
@@ -2225,25 +2230,17 @@ limitations under the License.
translation_description="In the 'Stats' page, the longitude."> translation_description="In the 'Stats' page, the longitude.">
Longitude Longitude
</string> </string>
<string name="stats_max_elevation" <string name="stats_max"
translation_description="In the 'Stats' page, the maximum elevation."> translation_description="In the 'Stats' page, the maximum of a value.">
Max elevation Max
</string>
<string name="stats_max_grade"
translation_description="In the 'Stats' page, the maximum grade.">
Max grade
</string> </string>
<string name="stats_max_speed" <string name="stats_max_speed"
translation_description="In the 'Stats' page, the maximum speed."> translation_description="In the 'Stats' page, the maximum speed.">
Max speed Max speed
</string> </string>
<string name="stats_min_elevation" <string name="stats_min"
translation_description="In the 'Stats' page, the minimum elevation."> translation_description="In the 'Stats' page, the minimum of a value.">
Min elevation Min
</string>
<string name="stats_min_grade"
translation_description="In the 'Stats' page, the minimum grade.">
Min grade
</string> </string>
<string name="stats_moving_time" <string name="stats_moving_time"
translation_description="In the 'Stats' page, the moving time."> translation_description="In the 'Stats' page, the moving time.">
@@ -2464,13 +2461,6 @@ limitations under the License.
translation_description="In a setting picker, the value to always enable the option."> translation_description="In a setting picker, the value to always enable the option.">
Always Always
</string> </string>
<string name="value_coordinate_degree"
translation_description="To display a latitude or longitude coordinate in degree. E.g.,
'2.2 \u00B0'. \u00B0 is the unicode value for the degree symbol.
%1$s: a string value of the coordinate. E.g., '2.2'.">
%1$s \u00B0
</string>
<string name="value_float_feet" <string name="value_float_feet"
translation_description="Display a float value in feet (ft). translation_description="Display a float value in feet (ft).
@@ -2483,12 +2473,6 @@ limitations under the License.
%1$.2f: a float number. E.g., '2.22'."> %1$.2f: a float number. E.g., '2.22'.">
%1$.2f km %1$.2f km
</string> </string>
<string name="value_float_kilometer_hour"
translation_description="Display a float value in kilometers per hour (km/h).
%1$.2f: a float number. E.g., '2.22'.">
%1$.2f km/h
</string>
<string name="value_float_meter" <string name="value_float_meter"
translation_description="Display a float value in meters (m). translation_description="Display a float value in meters (m).
@@ -2501,12 +2485,6 @@ limitations under the License.
%1$.2f: a float number. E.g., '2.22'."> %1$.2f: a float number. E.g., '2.22'.">
%1$.2f mi %1$.2f mi
</string> </string>
<string name="value_float_mile_hour"
translation_description="Display a float value in miles per hour (mi/h).
%1$.2f: a float number. E.g., '2.22'.">
%1$.2f mi/h
</string>
<string name="value_float_mile_poor_gps" <string name="value_float_mile_poor_gps"
translation_description="In a setting picker, the string format to display a float value in translation_description="In a setting picker, the string format to display a float value in
miles (mi), recommended when having poor GPS signal. miles (mi), recommended when having poor GPS signal.
@@ -2514,18 +2492,6 @@ limitations under the License.
%1$.1f: a float number. E.g., '2.2'."> %1$.1f: a float number. E.g., '2.2'.">
%1$.1f mi (poor GPS) %1$.1f mi (poor GPS)
</string> </string>
<string name="value_float_minute_kilometer"
translation_description="Display a float value in minutes per kilometer (min/km).
%1$.2f: a float number. E.g., '2.22'.">
%1$.2f min/km
</string>
<string name="value_float_minute_mile"
translation_description="Display a float value in minutes per mile (min/mi).
%1$.2f: a float number. E.g., '2.22'.">
%1$.2f min/mi
</string>
<string name="value_integer_feet" <string name="value_integer_feet"
translation_description="In a setting picker, the string format to display an integer value in translation_description="In a setting picker, the string format to display an integer value in
feet (ft). feet (ft).
+73 -15
View File
@@ -130,24 +130,82 @@ limitations under the License.
<item name="android:paddingRight">8dp</item> <item name="android:paddingRight">8dp</item>
<item name="android:textColor">@android:color/primary_text_light</item> <item name="android:textColor">@android:color/primary_text_light</item>
</style> </style>
<!-- stats label --> <!-- stats horizontal line -->
<style name="StatsLabel" parent="@style/TextMedium"> <style name="StatsHorizontalLine">
<item name="android:layout_weight">1</item> <item name="android:background">@color/stats_separator</item>
<item name="android:layout_width">0dp</item> <item name="android:layout_height">1dp</item>
<item name="android:layout_width">match_parent</item>
</style> </style>
<!-- stats spacer --> <!-- stats large item container -->
<style name="StatsSpacer"> <style name="StatsLargeItemContainer">
<item name="android:layout_height">match_parent</item> <item name="android:layout_gravity">top</item>
<item name="android:layout_width">8dp</item> <item name="android:layout_height">wrap_content</item>
</style> <item name="android:layout_weight">10</item>
<!-- stats value -->
<style name="StatsValue" parent="@style/TextLarge">
<item name="android:background">@android:color/background_light</item>
<item name="android:gravity">right</item>
<item name="android:layout_weight">1</item>
<item name="android:layout_width">0dp</item> <item name="android:layout_width">0dp</item>
<item name="android:orientation">vertical</item>
<item name="android:paddingBottom">6dp</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item> <item name="android:paddingRight">8dp</item>
<item name="android:textColor">@android:color/primary_text_light</item> <item name="android:paddingTop">6dp</item>
</style>
<!-- stats large label -->
<style name="StatsLargeLabel" parent="@style/TextSmall">
<item name="android:gravity">right</item>
<item name="android:layout_gravity">right</item>
<item name="android:singleLine">false</item>
<item name="android:textColor">@color/stats_large_label</item>
<item name="android:textStyle">bold</item>
</style>
<!-- stats large value -->
<style name="StatsLargeValue">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:singleLine">true</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">32sp</item>
<item name="android:textStyle">bold</item>
</style>
<!-- stats large value container -->
<style name="StatsLargeValueContainer">
<item name="android:layout_gravity">right</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginTop">-4dp</item>
<item name="android:layout_width">wrap_content</item>
</style>
<!-- stats scroll view -->
<style name="StatsScrollView" parent="@style/ScrollView">
<item name="android:scrollbarStyle">outsideOverlay</item>
</style>
<!-- stats small item container -->
<style name="StatsSmallItemContainer" parent="@style/StatsLargeItemContainer">
<item name="android:paddingTop">12dp</item>
</style>
<!-- stats small label -->
<style name="StatsSmallLabel" parent="@style/TextSmall">
<item name="android:gravity">right</item>
<item name="android:layout_gravity">right</item>
<item name="android:singleLine">false</item>
<item name="android:textStyle">bold</item>
</style>
<!-- stats small value -->
<style name="StatsSmallValue" parent="@style/TextLarge">
<item name="android:singleLine">true</item>
<item name="android:textColor">@android:color/white</item>
</style>
<!-- stats small value container -->
<style name="StatsSmallValueContainer" parent="@style/StatsLargeValueContainer">
<item name="android:layout_marginTop">-2dp</item>
</style>
<!-- stats unit -->
<style name="StatsUnit" parent="@style/TextSmall">
<item name="android:paddingLeft">4dp</item>
<item name="android:singleLine">true</item>
</style>
<!-- stats vertical spacer -->
<style name="StatsVerticalSpacer">
<item name="android:layout_height">match_parent</item>
<item name="android:layout_weight">1</item>
<item name="android:layout_width">0dp</item>
</style> </style>
<!-- text choose activity --> <!-- text choose activity -->
<style name="TextChooseActivity"> <style name="TextChooseActivity">
+2 -10
View File
@@ -29,16 +29,8 @@ limitations under the License.
<PreferenceCategory android:title="@string/settings_show" > <PreferenceCategory android:title="@string/settings_show" >
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="false" android:defaultValue="false"
android:key="@string/stats_show_moving_time_key" android:key="@string/stats_show_grade_elevation_key"
android:title="@string/stats_moving_time" /> android:title="@string/settings_stats_grade_elevation" />
<CheckBoxPreference
android:defaultValue="false"
android:key="@string/stats_show_elevation_key"
android:title="@string/stats_elevation" />
<CheckBoxPreference
android:defaultValue="false"
android:key="@string/stats_show_grade_key"
android:title="@string/settings_stats_grade" />
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="false" android:defaultValue="false"
android:key="@string/stats_show_coordinate_key" android:key="@string/stats_show_coordinate_key"
@@ -42,7 +42,7 @@ public class AggregatedStatsActivity extends AbstractMyTracksActivity {
@Override @Override
protected int getLayoutResId() { protected int getLayoutResId() {
return R.layout.aggregated_stats; return R.layout.stats;
} }
/** /**
@@ -102,7 +102,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
public void run() { public void run() {
if (isResumed()) { if (isResumed()) {
lastLocation = null; lastLocation = null;
StatsUtils.setLocationValues(getActivity(), lastLocation, true); StatsUtils.setLocationValues(getActivity(), lastLocation, isSelectedTrackRecording());
} }
} }
}); });
@@ -118,11 +118,12 @@ public class StatsFragment extends Fragment implements TrackDataListener {
if (isResumed()) { if (isResumed()) {
if (isSelectedTrackRecording() && !isSelectedTrackPaused()) { if (isSelectedTrackRecording() && !isSelectedTrackPaused()) {
lastLocation = location; lastLocation = location;
StatsUtils.setLocationValues(getActivity(), location, true); StatsUtils.setLocationValues(getActivity(), location, isSelectedTrackRecording());
} else { } else {
if (lastLocation != null) { if (lastLocation != null) {
lastLocation = null; lastLocation = null;
StatsUtils.setLocationValues(getActivity(), lastLocation, true); StatsUtils.setLocationValues(
getActivity(), lastLocation, isSelectedTrackRecording());
} }
} }
} }
@@ -277,6 +278,6 @@ public class StatsFragment extends Fragment implements TrackDataListener {
*/ */
private void updateUi(FragmentActivity activity) { private void updateUi(FragmentActivity activity) {
StatsUtils.setTripStatisticsValues(activity, lastTripStatistics); StatsUtils.setTripStatisticsValues(activity, lastTripStatistics);
StatsUtils.setLocationValues(activity, lastLocation, true); StatsUtils.setLocationValues(activity, lastLocation, isSelectedTrackRecording());
} }
} }
@@ -98,9 +98,7 @@ public class PreferencesUtils {
public static final String SHARE_TRACK_DEFAULT = "DRIVE"; public static final String SHARE_TRACK_DEFAULT = "DRIVE";
public static final int SPLIT_FREQUENCY_DEFAULT = 0; public static final int SPLIT_FREQUENCY_DEFAULT = 0;
public static final boolean STATS_SHOW_COORDINATE_DEFAULT = false; public static final boolean STATS_SHOW_COORDINATE_DEFAULT = false;
public static final boolean STATS_SHOW_ELEVATION_DEFAULT = false; public static final boolean STATS_SHOW_GRADE_ELEVATION_DEFAULT = false;
public static final boolean STATS_SHOW_GRADE_DEFAULT = false;
public static final boolean STATS_SHOW_MOVING_TIME_DEFAULT = false;
public static final String TRACK_COLOR_MODE_DEFAULT = "SINGLE"; public static final String TRACK_COLOR_MODE_DEFAULT = "SINGLE";
public static final int TRACK_COLOR_MODE_MEDIUM_DEFAULT = 15; public static final int TRACK_COLOR_MODE_MEDIUM_DEFAULT = 15;
public static final int TRACK_COLOR_MODE_PERCENTAGE_DEFAULT = 25; public static final int TRACK_COLOR_MODE_PERCENTAGE_DEFAULT = 25;
@@ -24,6 +24,8 @@ import android.location.Location;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import java.util.Locale;
/** /**
* Utilities for updating the statistics UI labels and values. * Utilities for updating the statistics UI labels and values.
* *
@@ -31,6 +33,12 @@ import android.widget.TextView;
*/ */
public class StatsUtils { public class StatsUtils {
private static final String COORDINATE_DEGREE = "\u00B0";
private static final String GRADE_PERCENTAGE = "%";
private static final String ELEVATION_FORMAT = "%1$.2f";
private static final String GRADE_FORMAT = "%1$d";
private StatsUtils() {} private StatsUtils() {}
/** /**
@@ -38,48 +46,49 @@ public class StatsUtils {
* *
* @param activity the activity * @param activity the activity
* @param location the location * @param location the location
* @param showAll true to show all the fields, false to show only the * @param isRecording true if recording
* elevation field
*/ */
public static void setLocationValues(Activity activity, Location location, boolean showAll) { public static void setLocationValues(Activity activity, Location location, boolean isRecording) {
boolean metricUnits = PreferencesUtils.getBoolean( boolean metricUnits = PreferencesUtils.getBoolean(
activity, R.string.metric_units_key, PreferencesUtils.METRIC_UNITS_DEFAULT); activity, R.string.metric_units_key, PreferencesUtils.METRIC_UNITS_DEFAULT);
boolean reportSpeed = PreferencesUtils.getBoolean( boolean reportSpeed = PreferencesUtils.getBoolean(
activity, R.string.report_speed_key, PreferencesUtils.REPORT_SPEED_DEFAULT); activity, R.string.report_speed_key, PreferencesUtils.REPORT_SPEED_DEFAULT);
// Set elevation
boolean showElevation = PreferencesUtils.getBoolean(
activity, R.string.stats_show_elevation_key, PreferencesUtils.STATS_SHOW_ELEVATION_DEFAULT);
if (showElevation) {
double altitude = location == null ? Double.NaN : location.getAltitude();
setElevationValue(activity, R.id.stats_elevation_value, altitude, metricUnits);
}
if (!showAll) {
return;
}
// Set speed/pace // Set speed/pace
setSpeedLabel( double speed = !isRecording || location == null ? Double.NaN : location.getSpeed();
activity, R.id.stats_speed_label, R.string.stats_speed, R.string.stats_pace, reportSpeed); setSpeed(activity, R.id.stats_speed, R.string.stats_speed, R.string.stats_pace, speed,
double speed = location == null ? Double.NaN : location.getSpeed(); metricUnits, reportSpeed);
setSpeedValue(activity, R.id.stats_speed_value, speed, metricUnits, reportSpeed);
// Set elevation
boolean showGradeElevation = PreferencesUtils.getBoolean(activity,
R.string.stats_show_grade_elevation_key,
PreferencesUtils.STATS_SHOW_GRADE_ELEVATION_DEFAULT);
View elevation = activity.findViewById(R.id.stats_elevation);
if (showGradeElevation && isRecording) {
double altitude = location == null ? Double.NaN : location.getAltitude();
elevation.setVisibility(View.VISIBLE);
setElevationValue(activity, R.id.stats_elevation, -1, altitude, metricUnits);
} else {
elevation.setVisibility(View.GONE);
}
// Set coordinate // Set coordinate
boolean showCoordinate = PreferencesUtils.getBoolean(activity, boolean showCoordinate = PreferencesUtils.getBoolean(activity,
R.string.stats_show_coordinate_key, PreferencesUtils.STATS_SHOW_COORDINATE_DEFAULT); R.string.stats_show_coordinate_key, PreferencesUtils.STATS_SHOW_COORDINATE_DEFAULT);
View coordinateLabelTableRow = activity.findViewById(R.id.stats_coordinate_label_table_row); View coordinateHorizontalLine = activity.findViewById(R.id.stats_coordinate_horizontal_line);
View coordinateValueTableRow = activity.findViewById(R.id.stats_coordinate_value_table_row); View coordinateContainer = activity.findViewById(R.id.stats_coordinate_container);
if (coordinateLabelTableRow == null || coordinateValueTableRow == null) {
return; if (showCoordinate && isRecording) {
}
coordinateLabelTableRow.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
coordinateValueTableRow.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
if (showCoordinate) {
double latitude = location == null ? Double.NaN : location.getLatitude(); double latitude = location == null ? Double.NaN : location.getLatitude();
double longitude = location == null ? Double.NaN : location.getLongitude(); double longitude = location == null ? Double.NaN : location.getLongitude();
setCoordinateValue(activity, R.id.stats_latitude_value, latitude); coordinateHorizontalLine.setVisibility(View.VISIBLE);
setCoordinateValue(activity, R.id.stats_longitude_value, longitude); coordinateContainer.setVisibility(View.VISIBLE);
setCoordinateValue(activity, R.id.stats_latitude, R.string.stats_latitude, latitude);
setCoordinateValue(activity, R.id.stats_longitude, R.string.stats_longitude, longitude);
} else {
coordinateHorizontalLine.setVisibility(View.GONE);
coordinateContainer.setVisibility(View.GONE);
} }
} }
@@ -90,7 +99,7 @@ public class StatsUtils {
* @param totalTime the total time * @param totalTime the total time
*/ */
public static void setTotalTimeValue(Activity activity, long totalTime) { public static void setTotalTimeValue(Activity activity, long totalTime) {
setTimeValue(activity, R.id.stats_total_time_value, totalTime); setTimeValue(activity, R.id.stats_total_time, R.string.stats_total_time, totalTime);
} }
/** /**
@@ -104,249 +113,206 @@ public class StatsUtils {
activity, R.string.metric_units_key, PreferencesUtils.METRIC_UNITS_DEFAULT); activity, R.string.metric_units_key, PreferencesUtils.METRIC_UNITS_DEFAULT);
boolean reportSpeed = PreferencesUtils.getBoolean( boolean reportSpeed = PreferencesUtils.getBoolean(
activity, R.string.report_speed_key, PreferencesUtils.REPORT_SPEED_DEFAULT); activity, R.string.report_speed_key, PreferencesUtils.REPORT_SPEED_DEFAULT);
boolean showMovingTime = PreferencesUtils.getBoolean(activity,
R.string.stats_show_moving_time_key, PreferencesUtils.STATS_SHOW_MOVING_TIME_DEFAULT);
// Set total distance // Set total distance
double totalDistance = tripStatistics == null ? Double.NaN : tripStatistics.getTotalDistance(); double totalDistance = tripStatistics == null ? Double.NaN : tripStatistics.getTotalDistance();
setDistanceValue(activity, R.id.stats_distance_value, totalDistance, metricUnits); setDistanceValue(activity, totalDistance, metricUnits);
// Set total time // Set total time
setTimeValue(activity, R.id.stats_total_time_value, setTimeValue(activity, R.id.stats_total_time, R.string.stats_total_time,
tripStatistics != null ? tripStatistics.getTotalTime() : -1L); tripStatistics != null ? tripStatistics.getTotalTime() : -1L);
// Set moving time // Set average speed/pace
setItemVisibility(activity, R.id.stats_moving_time_label, R.id.stats_moving_time_spacer,
R.id.stats_moving_time_value, showMovingTime);
if (showMovingTime) {
setTimeValue(activity, R.id.stats_moving_time_value,
tripStatistics != null ? tripStatistics.getMovingTime() : -1L);
}
// Set average speed
setSpeedLabel(activity, R.id.stats_average_speed_label, R.string.stats_average_speed,
R.string.stats_average_pace, reportSpeed);
double averageSpeed = tripStatistics != null ? tripStatistics.getAverageSpeed() : Double.NaN; double averageSpeed = tripStatistics != null ? tripStatistics.getAverageSpeed() : Double.NaN;
setSpeedValue(activity, R.id.stats_average_speed_value, averageSpeed, metricUnits, reportSpeed); setSpeed(activity, R.id.stats_average_speed, R.string.stats_average_speed,
R.string.stats_average_pace, averageSpeed, metricUnits, reportSpeed);
// Set average moving speed // Set moving time
setItemVisibility(activity, R.id.stats_average_moving_speed_label, setTimeValue(activity, R.id.stats_moving_time, R.string.stats_moving_time,
R.id.stats_average_moving_speed_spacer, R.id.stats_average_moving_speed_value, tripStatistics != null ? tripStatistics.getMovingTime() : -1L);
showMovingTime);
if (showMovingTime) {
setSpeedLabel(activity, R.id.stats_average_moving_speed_label,
R.string.stats_average_moving_speed, R.string.stats_average_moving_pace, reportSpeed);
double averageMovingSpeed = tripStatistics != null ? tripStatistics.getAverageMovingSpeed()
: Double.NaN;
setSpeedValue(activity, R.id.stats_average_moving_speed_value, averageMovingSpeed,
metricUnits, reportSpeed);
}
// Set max speed // Set average moving speed/pace
setSpeedLabel(activity, R.id.stats_max_speed_label, R.string.stats_max_speed, double averageMovingSpeed = tripStatistics != null ? tripStatistics.getAverageMovingSpeed()
R.string.stats_fastest_pace, reportSpeed); : Double.NaN;
setSpeed(activity, R.id.stats_average_moving_time, R.string.stats_average_moving_speed,
R.string.stats_average_moving_pace, averageMovingSpeed, metricUnits, reportSpeed);
// Set max speed/pace
double maxSpeed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed(); double maxSpeed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed();
setSpeedValue(activity, R.id.stats_max_speed_value, maxSpeed, metricUnits, reportSpeed); setSpeed(activity, R.id.stats_max_speed, R.string.stats_max_speed, R.string.stats_fastest_pace,
maxSpeed, metricUnits, reportSpeed);
// Set elevation // Set grade/elevation
boolean showElevation = PreferencesUtils.getBoolean( boolean showGradeElevation = PreferencesUtils.getBoolean(activity,
activity, R.string.stats_show_elevation_key, PreferencesUtils.STATS_SHOW_ELEVATION_DEFAULT); R.string.stats_show_grade_elevation_key,
View elevationLabelTableRow1 = activity.findViewById(R.id.stats_elevation_label_table_row1); PreferencesUtils.STATS_SHOW_GRADE_ELEVATION_DEFAULT);
View elevationValueTableRow1 = activity.findViewById(R.id.stats_elevation_value_table_row1); View gradeElevationHorizontalLine = activity.findViewById(
View elevationLabelTableRow2 = activity.findViewById(R.id.stats_elevation_label_table_row2); R.id.stats_grade_elevation_horizontal_line);
View elevationValueTableRow2 = activity.findViewById(R.id.stats_elevation_value_table_row2); View gradeElevationContainer = activity.findViewById(R.id.stats_grade_elevation_container);
if (elevationLabelTableRow1 == null
|| elevationValueTableRow1 == null if (showGradeElevation) {
|| elevationLabelTableRow2 == null gradeElevationHorizontalLine.setVisibility(View.VISIBLE);
|| elevationValueTableRow2 == null) { gradeElevationContainer.setVisibility(View.VISIBLE);
return; // Set grade
} double minGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMinGrade();
elevationLabelTableRow1.setVisibility(showElevation ? View.VISIBLE : View.GONE); double maxGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMaxGrade();
elevationValueTableRow1.setVisibility(showElevation ? View.VISIBLE : View.GONE); setGradeValue(activity, R.id.stats_grade_min, R.string.stats_min, minGrade);
elevationLabelTableRow2.setVisibility(showElevation ? View.VISIBLE : View.GONE); setGradeValue(activity, R.id.stats_grade_max, R.string.stats_max, maxGrade);
elevationValueTableRow2.setVisibility(showElevation ? View.VISIBLE : View.GONE);
if (showElevation) { // Set elevation
double elevationGain = tripStatistics == null ? Double.NaN double elevationGain = tripStatistics == null ? Double.NaN
: tripStatistics.getTotalElevationGain(); : tripStatistics.getTotalElevationGain();
double minElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation(); double minElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation();
double maxElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation(); double maxElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation();
setElevationValue(activity, R.id.stats_elevation_gain_value, elevationGain, metricUnits); setElevationValue(
setElevationValue(activity, R.id.stats_min_elevation_value, minElevation, metricUnits); activity, R.id.stats_elevation_gain, R.string.stats_gain, elevationGain, metricUnits);
setElevationValue(activity, R.id.stats_max_elevation_value, maxElevation, metricUnits); setElevationValue(
} activity, R.id.stats_elevation_min, R.string.stats_min, minElevation, metricUnits);
setElevationValue(
// Set grade activity, R.id.stats_elevation_max, R.string.stats_max, maxElevation, metricUnits);
boolean showGrade = PreferencesUtils.getBoolean( } else {
activity, R.string.stats_show_grade_key, PreferencesUtils.STATS_SHOW_GRADE_DEFAULT); gradeElevationHorizontalLine.setVisibility(View.GONE);
View gradeLabelTableRow = activity.findViewById(R.id.stats_grade_label_table_row); gradeElevationContainer.setVisibility(View.GONE);
View gradeValueTableRow = activity.findViewById(R.id.stats_grade_value_table_row);
if (gradeLabelTableRow == null || gradeValueTableRow == null) {
return;
}
gradeLabelTableRow.setVisibility(showGrade ? View.VISIBLE : View.GONE);
gradeValueTableRow.setVisibility(showGrade ? View.VISIBLE : View.GONE);
if (showGrade) {
double minGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMinGrade();
double maxGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMaxGrade();
setGradeValue(activity, R.id.stats_min_grade_value, minGrade);
setGradeValue(activity, R.id.stats_max_grade_value, maxGrade);
}
}
private static void setItemVisibility(
Activity activity, int labelId, int spacerId, int valueId, boolean show) {
View label = activity.findViewById(labelId);
View spacer = activity.findViewById(spacerId);
View value = activity.findViewById(valueId);
if (label != null) {
label.setVisibility(show ? View.VISIBLE : View.GONE);
}
if (spacer != null) {
spacer.setVisibility(show ? View.VISIBLE : View.GONE);
}
if (value != null) {
value.setVisibility(show ? View.VISIBLE : View.GONE);
} }
} }
/** /**
* Sets a speed label. * Sets speed.
* *
* @param activity the activity * @param activity the activity
* @param id the speed label resource id * @param itemId the item id
* @param speedId the speed string id * @param speedLabelId the speed label id
* @param paceId the pace string id * @param paceLabelId the pace label id
* @param reportSpeed true to report speed
*/
private static void setSpeedLabel(
Activity activity, int id, int speedId, int paceId, boolean reportSpeed) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
textView.setText(reportSpeed ? speedId : paceId);
}
/**
* Sets a speed value.
*
* @param activity the activity
* @param id the speed value resource id
* @param speed the speed in meters per second * @param speed the speed in meters per second
* @param metricUnits true to display in metric units * @param metricUnits true if metric units
* @param reportSpeed true to report speed * @param reportSpeed true if report speed
*/ */
private static void setSpeedValue( private static void setSpeed(Activity activity, int itemId, int speedLabelId, int paceLabelId,
Activity activity, int id, double speed, boolean metricUnits, boolean reportSpeed) { double speed, boolean metricUnits, boolean reportSpeed) {
TextView textView = (TextView) activity.findViewById(id); String parts[] = StringUtils.getSpeedParts(activity, speed, metricUnits, reportSpeed);
if (textView == null) { setItem(activity, itemId, reportSpeed ? speedLabelId : paceLabelId, parts[0], parts[1]);
return;
}
textView.setText(StringUtils.formatSpeed(activity, speed, metricUnits, reportSpeed));
} }
/** /**
* Sets a distance value. * Sets distance value.
* *
* @param activity the activity * @param activity the activity
* @param id the distance value resource id
* @param distance the distance in meters * @param distance the distance in meters
* @param metricUnits true to display in metric units * @param metricUnits true if metric units
*/ */
private static void setDistanceValue( private static void setDistanceValue(Activity activity, double distance, boolean metricUnits) {
Activity activity, int id, double distance, boolean metricUnits) { String parts[] = StringUtils.getDistanceParts(activity, distance, metricUnits);
TextView textView = (TextView) activity.findViewById(id); setItem(activity, R.id.stats_distance, R.string.stats_distance, parts[0], parts[1]);
if (textView == null) {
return;
}
textView.setText(StringUtils.formatDistance(activity, distance, metricUnits));
} }
/** /**
* Sets a time value. * Sets a time value.
* *
* @param activity the activity * @param activity the activity
* @param id the time value resource id * @param itemId the item id
* @param labelId the label id
* @param time the time * @param time the time
*/ */
private static void setTimeValue(Activity activity, int id, long time) { private static void setTimeValue(Activity activity, int itemId, int labelId, long time) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
String value = time == -1L ? activity.getString(R.string.value_unknown) String value = time == -1L ? activity.getString(R.string.value_unknown)
: StringUtils.formatElapsedTime(time); : StringUtils.formatElapsedTime(time);
textView.setText(value); setItem(activity, itemId, labelId, value, null);
} }
/** /**
* Sets an elevation value. * Sets an elevation value.
* *
* @param activity the activity * @param activity the activity
* @param id the elevation value resource id * @param itemId the item id
* @param labelId the label id
* @param elevation the elevation in meters * @param elevation the elevation in meters
* @param metricUnits true to display in metric units * @param metricUnits true if metric units
*/ */
private static void setElevationValue( private static void setElevationValue(
Activity activity, int id, double elevation, boolean metricUnits) { Activity activity, int itemId, int labelId, double elevation, boolean metricUnits) {
TextView textView = (TextView) activity.findViewById(id);
if (textView == null) {
return;
}
String value; String value;
String unit;
if (Double.isNaN(elevation) || Double.isInfinite(elevation)) { if (Double.isNaN(elevation) || Double.isInfinite(elevation)) {
value = activity.getString(R.string.value_unknown); value = null;
unit = null;
} else { } else {
if (metricUnits) { if (metricUnits) {
value = activity.getString(R.string.value_float_meter, elevation); value = String.format(Locale.getDefault(), ELEVATION_FORMAT, elevation);
unit = activity.getString(R.string.unit_meter);
} else { } else {
elevation *= UnitConversions.M_TO_FT; elevation *= UnitConversions.M_TO_FT;
value = activity.getString(R.string.value_float_feet, elevation); value = String.format(Locale.getDefault(), ELEVATION_FORMAT, elevation);
unit = activity.getString(R.string.unit_feet);
} }
} }
textView.setText(value); setItem(activity, itemId, labelId, value, unit);
} }
/** /**
* Sets a grade value. * Sets a grade value.
* *
* @param activity the activity * @param activity the activity
* @param id the grade value resource id * @param itemId the item id
* @param labelId the label id
* @param grade the grade in fraction between 0 and 1 * @param grade the grade in fraction between 0 and 1
*/ */
private static void setGradeValue(Activity activity, int id, double grade) { private static void setGradeValue(Activity activity, int itemId, int labelId, double grade) {
TextView textView = (TextView) activity.findViewById(id); String value = Double.isNaN(grade) || Double.isInfinite(grade) ? null
if (textView == null) { : String.format(Locale.getDefault(), GRADE_FORMAT, Math.round(grade * 100));
return; setItem(activity, itemId, labelId, value, GRADE_PERCENTAGE);
}
String value;
if (Double.isNaN(grade) || Double.isInfinite(grade)) {
value = activity.getString(R.string.value_unknown);
} else {
value = activity.getString(R.string.value_integer_percent, Math.round(grade * 100));
}
textView.setText(value);
} }
/** /**
* Sets a coordinate value. * Sets a coordinate value.
* *
* @param activity the activity * @param activity the activity
* @param id the coordinate value resource id * @param itemId the item id
* @param labelId the label id
* @param coordinate the coordinate in degrees * @param coordinate the coordinate in degrees
*/ */
private static void setCoordinateValue(Activity activity, int id, double coordinate) { private static void setCoordinateValue(
TextView textView = (TextView) activity.findViewById(id); Activity activity, int itemId, int labelId, double coordinate) {
if (textView == null) { String value = Double.isNaN(coordinate) || Double.isInfinite(coordinate) ? null
: Location.convert(coordinate, Location.FORMAT_DEGREES);
setItem(activity, itemId, labelId, value, COORDINATE_DEGREE);
}
/**
* Sets an item.
*
* @param activity the activity
* @param itemId the item id
* @param labelId the label id. -1 to hide the label
* @param value the value, can be null
* @param unit the unit. Null to hide the unit
*/
private static void setItem(
Activity activity, int itemId, int labelId, String value, String unit) {
View view = activity.findViewById(itemId);
TextView labelTextView = (TextView) view.findViewById(R.id.stats_label);
TextView valueTextView = (TextView) view.findViewById(R.id.stats_value);
TextView unitTextView = (TextView) view.findViewById(R.id.stats_unit);
if (labelTextView == null || valueTextView == null || unitTextView == null) {
return; return;
} }
String value; if (labelId == -1) {
if (Double.isNaN(coordinate) || Double.isInfinite(coordinate)) { labelTextView.setVisibility(View.GONE);
value = activity.getString(R.string.value_unknown);
} else { } else {
value = activity.getString( labelTextView.setVisibility(View.VISIBLE);
R.string.value_coordinate_degree, Location.convert(coordinate, Location.FORMAT_DEGREES)); labelTextView.setText(labelId);
} }
textView.setText(value);
if (value == null) {
value = activity.getString(R.string.value_unknown);
unitTextView.setVisibility(View.GONE);
} else {
if (unit == null) {
unitTextView.setVisibility(View.GONE);
} else {
unitTextView.setVisibility(View.VISIBLE);
unitTextView.setText(unit);
}
}
valueTextView.setText(value);
} }
} }
@@ -188,40 +188,6 @@ public class StringUtils {
return result; return result;
} }
/**
* Formats the speed.
*
* @param context the context
* @param speed the speed in meters per second
* @param metricUnits true to use metric units. False to use imperial units
* @param reportSpeed true to report as speed. False to report as pace
*/
public static String formatSpeed(
Context context, double speed, boolean metricUnits, boolean reportSpeed) {
if (Double.isNaN(speed) || Double.isInfinite(speed)) {
return context.getString(R.string.value_unknown);
}
speed *= UnitConversions.MS_TO_KMH;
if (metricUnits) {
if (reportSpeed) {
return context.getString(R.string.value_float_kilometer_hour, speed);
} else {
// convert from hours to minutes
double pace = speed == 0 ? 0.0 : 60.0 / speed;
return context.getString(R.string.value_float_minute_kilometer, pace);
}
} else {
speed *= UnitConversions.KM_TO_MI;
if (reportSpeed) {
return context.getString(R.string.value_float_mile_hour, speed);
} else {
// convert from hours to minutes
double pace = speed == 0 ? 0.0 : 60.0 / speed;
return context.getString(R.string.value_float_minute_mile, pace);
}
}
}
/** /**
* Gets the speed in an array of two strings. The first string is the speed. * Gets the speed in an array of two strings. The first string is the speed.
* The second string is the unit. The first string is null if speed is * The second string is the unit. The first string is null if speed is
@@ -90,28 +90,6 @@ public class StringUtilsTest extends AndroidTestCase {
assertEquals("328.08 ft", StringUtils.formatDistance(getContext(), 100, false)); assertEquals("328.08 ft", StringUtils.formatDistance(getContext(), 100, false));
} }
/**
* Tests {@link StringUtils#formatSpeed(android.content.Context, double,
* boolean, boolean)}.
*/
public void testFormatSpeed() {
// Speed in metric
assertEquals("36.00 km/h", StringUtils.formatSpeed(getContext(), 10, true, true));
// Speed in imperial
assertEquals("22.37 mi/h", StringUtils.formatSpeed(getContext(), 10, false, true));
// Pace in metric
assertEquals("1.67 min/km", StringUtils.formatSpeed(getContext(), 10, true, false));
// Pace in imperial
assertEquals("2.68 min/mi", StringUtils.formatSpeed(getContext(), 10, false, false));
// zero pace
assertEquals("0.00 min/km", StringUtils.formatSpeed(getContext(), 0, true, false));
assertEquals("0.00 min/mi", StringUtils.formatSpeed(getContext(), 0, false, false));
// speed is NaN
assertEquals("-", StringUtils.formatSpeed(getContext(), Double.NaN, true, true));
// speed is infinite
assertEquals("-", StringUtils.formatSpeed(getContext(), Double.NEGATIVE_INFINITY, true, true));
}
/** /**
* Tests {@link StringUtils#formatCData(String)}. * Tests {@link StringUtils#formatCData(String)}.
*/ */
@@ -211,7 +211,8 @@ public class SettingTest extends ActivityInstrumentationTestCase2<TrackListActiv
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.stats_elevation)); EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.stats_elevation));
} }
if (changeGrade) { if (changeGrade) {
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_stats_grade)); EndToEndTestUtils.SOLO.clickOnText(
activityMyTracks.getString(R.string.settings_stats_grade_elevation));
} }
if (changeLatLong) { if (changeLatLong) {
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks EndToEndTestUtils.SOLO.clickOnText(activityMyTracks