From 9a6068977f8deeb679399bcd63ec7820e01c8d02 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Mon, 26 Mar 2018 17:19:01 -0400 Subject: [PATCH 01/36] First commit for abbreviations using MAS snapshot --- build.gradle | 2 ++ gradle/dependencies.gradle | 2 +- libandroid-navigation-ui/build.gradle | 5 +++++ .../ui/v5/instruction/InstructionLoader.java | 10 ++++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e66e3e3c9a1..31ed67a53b3 100644 --- a/build.gradle +++ b/build.gradle @@ -24,6 +24,8 @@ task testReport(type: TestReport, group: 'Build') { allprojects { repositories { + mavenCentral() + maven { url "http://oss.sonatype.org/content/repositories/snapshots/" } maven { url 'https://plugins.gradle.org/m2' } google() jcenter() diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 1f15e7042c9..c7a3d83e5f1 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -10,7 +10,7 @@ ext { version = [ mapboxMapSdk : '5.5.0', mapboxServices : '2.2.10', - mapboxSdkServices : '3.0.0-beta.4', + mapboxSdkServices : '3.0.0-SNAPSHOT', locationLayerPlugin: '0.4.0', autoValue : '1.5', autoValueParcel : '0.2.5', diff --git a/libandroid-navigation-ui/build.gradle b/libandroid-navigation-ui/build.gradle index 39d65b70082..01fb1fc4195 100644 --- a/libandroid-navigation-ui/build.gradle +++ b/libandroid-navigation-ui/build.gradle @@ -30,6 +30,11 @@ android { } } +repositories { + mavenCentral() + maven { url "http://oss.sonatype.org/content/repositories/snapshots/" } +} + dependencies { // Navigation SDK api project(':libandroid-navigation') diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 5f1ab70d264..829658cffb0 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -14,6 +14,8 @@ import com.squareup.picasso.Picasso; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; /** @@ -122,6 +124,14 @@ public void loadInstruction(TextView textView, BannerText bannerText) { StringBuilder instructionStringBuilder = new StringBuilder(); List shieldUrls = new ArrayList<>(); + List bannerComponents = bannerText.components(); + Collections.sort(bannerComponents, new Comparator() { + @Override + public int compare(BannerComponents bannerComponents, BannerComponents t1) { + return bannerComponents.abbreviationPriority().compareTo(t1.abbreviationPriority()); + } + }); + for (BannerComponents components : bannerText.components()) { if (hasBaseUrl(components)) { addShieldInfo(textView, instructionStringBuilder, shieldUrls, components); From a6a86f4b164f55cb63bf882258ae4ffc0dce71cf Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Fri, 13 Apr 2018 17:05:14 -0400 Subject: [PATCH 02/36] Added InstructionBuilder without implementation --- .../ui/v5/instruction/InstructionBuilder.java | 44 ++++++++++++++++ .../ui/v5/instruction/InstructionLoader.java | 52 ++++++++++--------- .../ui/v5/instruction/InstructionTarget.java | 2 +- 3 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java new file mode 100644 index 00000000000..9f1bd467e1e --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java @@ -0,0 +1,44 @@ +package com.mapbox.services.android.navigation.ui.v5.instruction; + +import android.widget.TextView; + +import com.mapbox.api.directions.v5.models.BannerComponents; + +import java.util.ArrayList; +import java.util.List; + +public class InstructionBuilder extends ArrayList { + + public InstructionBuilder(List bannerComponents) { + + } + + public void buildInstruction(TextView textView) { + + } + + class Node { + int index; + String text; + } + + class ShieldNode extends Node { + String getUrl() { + return ""; + } + + String getText() { + return ""; + } + } + + class AbbreviationNode extends Node { + String getAbbreviation() { + return ""; + } + + int getAbbreviationPriority() { + return -1; + } + } +} diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 5f6af9258dd..5c7f8e27093 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -15,7 +15,6 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.List; /** @@ -120,32 +119,35 @@ public void loadInstruction(TextView textView, BannerText bannerText) { checkIsInitialized(); - if (hasComponents(bannerText)) { - StringBuilder instructionStringBuilder = new StringBuilder(); - List shieldUrls = new ArrayList<>(); - - List bannerComponents = bannerText.components(); - Collections.sort(bannerComponents); - - for (BannerComponents components : bannerText.components()) { - if (hasBaseUrl(components)) { - addShieldInfo(textView, instructionStringBuilder, shieldUrls, components); - } else { - String text = components.text(); - boolean emptyText = TextUtils.isEmpty(instructionStringBuilder.toString()); - String instructionText = emptyText ? text : SINGLE_SPACE.concat(text); - instructionStringBuilder.append(instructionText); - } - } + if (!hasComponents(bannerText)) { + return; + } + + StringBuilder instructionStringBuilder = new StringBuilder(); + List shieldUrls = new ArrayList<>(); + + List bannerComponents = bannerText.components(); + Collections.sort(bannerComponents); + + for (BannerComponents components : bannerText.components()) { + if (hasImageUrl(components)) { + addShieldInfo(textView, instructionStringBuilder, shieldUrls, components); - // If there are shield Urls, fetch the corresponding images - if (!shieldUrls.isEmpty()) { - createTargets(textView, instructionStringBuilder, shieldUrls); - loadTargets(); } else { - textView.setText(instructionStringBuilder); + String text = components.text(); + boolean emptyText = TextUtils.isEmpty(instructionStringBuilder.toString()); + String instructionText = emptyText ? text : SINGLE_SPACE.concat(text); + instructionStringBuilder.append(instructionText); } } + + // If there are shield Urls, fetch the corresponding images + if (!shieldUrls.isEmpty()) { + createTargets(textView, instructionStringBuilder, shieldUrls); + loadTargets(); + } else { + textView.setText(instructionStringBuilder); + } } private static boolean hasComponents(BannerText bannerText) { @@ -160,13 +162,13 @@ private static boolean hasComponents(BannerText bannerText) { */ private void fetchImageBaseUrls(BannerText bannerText) { for (BannerComponents components : bannerText.components()) { - if (hasBaseUrl(components)) { + if (hasImageUrl(components)) { picassoImageLoader.load(urlDensityMap.get(components.imageBaseUrl())).fetch(); } } } - private static boolean hasBaseUrl(BannerComponents components) { + private static boolean hasImageUrl(BannerComponents components) { return !TextUtils.isEmpty(components.imageBaseUrl()); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java index f27d80bbd89..38ae6c26f4a 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java @@ -24,7 +24,7 @@ public class InstructionTarget implements Target { private BannerShieldInfo shield; private InstructionLoadedCallback instructionLoadedCallback; - InstructionTarget(TextView textView, Spannable instructionSpannable, + InstructionTarget(TextView textView, Spannable instructionSpannable, List shields, BannerShieldInfo shield, InstructionLoadedCallback instructionLoadedCallback) { this.textView = textView; From da17d64884a1ec23ca0bcd51354ff6992ed9e412 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Mon, 16 Apr 2018 17:19:44 -0400 Subject: [PATCH 03/36] Added text as filler for banner shields and continued work on combining shield and abbreviation logic --- .../ui/v5/instruction/BannerShieldInfo.java | 2 +- .../ui/v5/instruction/InstructionBuilder.java | 32 +++++++++++++++++++ .../ui/v5/instruction/InstructionLoader.java | 6 ++-- .../ui/v5/instruction/InstructionTarget.java | 8 +++++ 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java index dc33dbb220d..4ed248ad7aa 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java @@ -26,6 +26,6 @@ int getStartIndex() { } int getEndIndex() { - return startIndex + 1; + return startIndex + text.length() - 1; } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java index 9f1bd467e1e..d56ae03b68e 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java @@ -1,5 +1,6 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; +import android.text.TextUtils; import android.widget.TextView; import com.mapbox.api.directions.v5.models.BannerComponents; @@ -8,9 +9,40 @@ import java.util.List; public class InstructionBuilder extends ArrayList { + int length = 0; public InstructionBuilder(List bannerComponents) { + super(); + StringBuilder instructionStringBuilder = new StringBuilder(); + List shieldUrls = new ArrayList<>(); + + for (BannerComponents components : bannerComponents) { + // todo: create StringBuilder and add nodes to list + if (hasImageUrl(components)) { + addShieldInfo(textView, instructionStringBuilder, shieldUrls, components); + + } else { +// String text = components.text(); +// boolean textViewIsEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); +// String instructionText = textViewIsEmpty ? text : SINGLE_SPACE.concat(text); + instructionStringBuilder.append(components.text()); + } + } + } + + private static boolean hasImageUrl(BannerComponents components) { + return !TextUtils.isEmpty(components.imageBaseUrl()); + } + + private static void addShieldInfo(TextView textView, StringBuilder instructionStringBuilder, + List shieldUrls, BannerComponents components) { + boolean instructionBuilderEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); + int instructionLength = instructionStringBuilder.length(); + int startIndex = instructionBuilderEmpty ? instructionLength : instructionLength + 1; + shieldUrls.add(new BannerShieldInfo(textView.getContext(), components.imageBaseUrl(), + startIndex, components.text())); + instructionStringBuilder.append(components.text()); } public void buildInstruction(TextView textView) { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 5c7f8e27093..c338456cb2e 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -135,8 +135,8 @@ public void loadInstruction(TextView textView, BannerText bannerText) { } else { String text = components.text(); - boolean emptyText = TextUtils.isEmpty(instructionStringBuilder.toString()); - String instructionText = emptyText ? text : SINGLE_SPACE.concat(text); + boolean textViewIsEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); + String instructionText = textViewIsEmpty ? text : SINGLE_SPACE.concat(text); instructionStringBuilder.append(instructionText); } } @@ -179,7 +179,7 @@ private static void addShieldInfo(TextView textView, StringBuilder instructionSt int startIndex = instructionBuilderEmpty ? instructionLength : instructionLength + 1; shieldUrls.add(new BannerShieldInfo(textView.getContext(), components.imageBaseUrl(), startIndex, components.text())); - instructionStringBuilder.append(IMAGE_SPACE_PLACEHOLDER); + instructionStringBuilder.append(components.text()); } private void createTargets(TextView textView, StringBuilder instructionStringBuilder, diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java index 38ae6c26f4a..fce7e9d0ca8 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java @@ -7,6 +7,7 @@ import android.text.Spanned; import android.text.TextUtils; import android.text.style.ImageSpan; +import android.util.Log; import android.widget.TextView; import com.squareup.picasso.Picasso; @@ -48,6 +49,13 @@ public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { int right = bottom * bitmap.getWidth() / bitmap.getHeight(); drawable.setBounds(0, 0, right, bottom); + String tag = "InstructionTarget"; + Log.d(tag, "\ninstruction spannable: " + instructionSpannable); + Log.d(tag, "instruction spannable length: " + instructionSpannable.length()); + Log.d(tag, "shield text: " + shield.getText()); + Log.d(tag, "shield start/end: " + shield.getStartIndex() + ", " + shield.getEndIndex()); + Log.d(tag, "~~~~~~~~~~~~~~"); + // Create and set a new ImageSpan at the given index with the Drawable instructionSpannable.setSpan(new ImageSpan(drawable), shield.getStartIndex(), shield.getEndIndex(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); From 59f655675c1668e797234326e82a211fef4f7621 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 18 Apr 2018 15:31:50 -0400 Subject: [PATCH 04/36] Continued abbreviation work --- .../ui/v5/instruction/InstructionBuilder.java | 62 +++++++++++++++---- .../ui/v5/instruction/InstructionLoader.java | 2 + 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java index d56ae03b68e..b8897132c1d 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java @@ -1,5 +1,6 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; +import android.graphics.Paint; import android.text.TextUtils; import android.widget.TextView; @@ -10,27 +11,36 @@ public class InstructionBuilder extends ArrayList { int length = 0; + List abbreviations; - public InstructionBuilder(List bannerComponents) { + public InstructionBuilder(List bannerComponents, TextView textView) { super(); StringBuilder instructionStringBuilder = new StringBuilder(); List shieldUrls = new ArrayList<>(); + abbreviations = new ArrayList<>(); for (BannerComponents components : bannerComponents) { - // todo: create StringBuilder and add nodes to list if (hasImageUrl(components)) { addShieldInfo(textView, instructionStringBuilder, shieldUrls, components); - + add(new ShieldNode(components)); + } else if (hasAbbreviation(components)) { + instructionStringBuilder.append(components.text()); + abbreviations.add(components); + add(new AbbreviationNode(components)); } else { -// String text = components.text(); -// boolean textViewIsEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); -// String instructionText = textViewIsEmpty ? text : SINGLE_SPACE.concat(text); instructionStringBuilder.append(components.text()); + add(new Node(components)); } + + instructionStringBuilder.append(" "); } } + private static boolean hasAbbreviation(BannerComponents components) { + return !TextUtils.isEmpty(components.abbreviation()); + } + private static boolean hasImageUrl(BannerComponents components) { return !TextUtils.isEmpty(components.imageBaseUrl()); } @@ -46,31 +56,57 @@ private static void addShieldInfo(TextView textView, StringBuilder instructionSt } public void buildInstruction(TextView textView) { + } + private boolean textFits(TextView textView, String text) { + Paint paint = new Paint(textView.getPaint()); + float width = paint.measureText(text); + return width < textView.getWidth(); } class Node { - int index; String text; + + public Node(BannerComponents bannerComponents) { + this.text = bannerComponents.text(); + } + + public String getText() { + return text; + } } class ShieldNode extends Node { - String getUrl() { - return ""; + String url; + + public ShieldNode(BannerComponents bannerComponents) { + super(bannerComponents); + + this.url = bannerComponents.imageBaseUrl(); } - String getText() { - return ""; + String getUrl() { + return url; } } class AbbreviationNode extends Node { + String abbreviation; + int abbreviationPriority; + + public AbbreviationNode(BannerComponents bannerComponents) { + super(bannerComponents); + + this.abbreviation = bannerComponents.abbreviation(); + this.abbreviationPriority = bannerComponents.abbreviationPriority(); + } + String getAbbreviation() { - return ""; + return abbreviation; } int getAbbreviationPriority() { - return -1; + return abbreviationPriority; } } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index c338456cb2e..8937b9d766a 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -126,6 +126,8 @@ public void loadInstruction(TextView textView, BannerText bannerText) { StringBuilder instructionStringBuilder = new StringBuilder(); List shieldUrls = new ArrayList<>(); + InstructionBuilder instructionBuilder = new InstructionBuilder(bannerText.components(), textView); + List bannerComponents = bannerText.components(); Collections.sort(bannerComponents); From ffc8d81602425c9167bb598e7ba00a98d22ad644 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 18 Apr 2018 18:07:15 -0400 Subject: [PATCH 05/36] Continued working on abbreviations but having issues sorting list of abbreviations by abbreviationPriority while also keeping track of index --- .../ui/v5/instruction/InstructionBuilder.java | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java index b8897132c1d..9c9b7cb0830 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java @@ -1,21 +1,25 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; import android.graphics.Paint; +import android.support.annotation.NonNull; import android.text.TextUtils; +import android.util.Pair; import android.widget.TextView; import com.mapbox.api.directions.v5.models.BannerComponents; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class InstructionBuilder extends ArrayList { int length = 0; - List abbreviations; + List abbreviations; + StringBuilder instructionStringBuilder; public InstructionBuilder(List bannerComponents, TextView textView) { super(); - StringBuilder instructionStringBuilder = new StringBuilder(); + instructionStringBuilder = new StringBuilder(); List shieldUrls = new ArrayList<>(); abbreviations = new ArrayList<>(); @@ -26,8 +30,9 @@ public InstructionBuilder(List bannerComponents, TextView text add(new ShieldNode(components)); } else if (hasAbbreviation(components)) { instructionStringBuilder.append(components.text()); - abbreviations.add(components); - add(new AbbreviationNode(components)); + AbbreviationNode abbreviationNode = new AbbreviationNode(components); + add(abbreviationNode); + abbreviations.add(abbreviationNode); } else { instructionStringBuilder.append(components.text()); add(new Node(components)); @@ -35,6 +40,8 @@ public InstructionBuilder(List bannerComponents, TextView text instructionStringBuilder.append(" "); } + + Collections.sort(abbreviations); } private static boolean hasAbbreviation(BannerComponents components) { @@ -56,6 +63,22 @@ private static void addShieldInfo(TextView textView, StringBuilder instructionSt } public void buildInstruction(TextView textView) { + int currAbbreviationPriority; + while (!textFits(textView, instructionStringBuilder.toString())) { + currAbbreviationPriority = abbreviations.get(0).abbreviationPriority(); + instructionStringBuilder = new StringBuilder(); + + + + } + + } + + private void abbreviate(int abbreviationPriority) { + int currentIndex = 0; + while (abbreviations.get(currentIndex).abbreviationPriority() == abbreviationPriority) { + get(abbreviations.remove(currentIndex).) + } } private boolean textFits(TextView textView, String text) { @@ -90,9 +113,10 @@ String getUrl() { } } - class AbbreviationNode extends Node { + class AbbreviationNode extends Node implements Comparable { String abbreviation; int abbreviationPriority; + boolean abbreviate; public AbbreviationNode(BannerComponents bannerComponents) { super(bannerComponents); @@ -108,5 +132,9 @@ String getAbbreviation() { int getAbbreviationPriority() { return abbreviationPriority; } + + void setAbbreviate(boolean abbreviate) { + this.abbreviate = abbreviate; + } } } From c1890f59745378f47341df4cfd70563c3d1fe687 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 25 Apr 2018 13:10:49 -0400 Subject: [PATCH 06/36] First commit with InstructionBuilder fixed up --- .../ui/v5/instruction/BannerShieldInfo.java | 25 ++- .../ui/v5/instruction/InstructionBuilder.java | 177 +++++++++++------- .../instruction/InstructionImageLoader.java | 4 + .../ui/v5/instruction/InstructionLoader.java | 69 +++---- 4 files changed, 170 insertions(+), 105 deletions(-) create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java index 4ed248ad7aa..95294df0131 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java @@ -2,15 +2,18 @@ import android.content.Context; +import com.mapbox.api.directions.v5.models.BannerComponents; + class BannerShieldInfo { private String url; private String text; - private int startIndex; + private int nodeIndex; + private int startIndex = -1; - BannerShieldInfo(Context context, String url, int startIndex, String text) { - this.url = new UrlDensityMap(context).get(url); - this.startIndex = startIndex; - this.text = text; + BannerShieldInfo(Context context, BannerComponents bannerComponents, int nodeIndex) { + this.url = new UrlDensityMap(context).get(bannerComponents.imageBaseUrl()); + this.nodeIndex = nodeIndex; + this.text = bannerComponents.text(); } String getUrl() { @@ -21,11 +24,19 @@ public String getText() { return text; } - int getStartIndex() { + public int getNodeIndex() { + return nodeIndex; + } + + public void setStartIndex(int startIndex) { + this.startIndex = startIndex; + } + + public int getStartIndex() { return startIndex; } int getEndIndex() { - return startIndex + text.length() - 1; + return startIndex + text.length(); } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java index 9c9b7cb0830..dece5245d1d 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java @@ -1,84 +1,111 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; import android.graphics.Paint; -import android.support.annotation.NonNull; import android.text.TextUtils; -import android.util.Pair; import android.widget.TextView; import com.mapbox.api.directions.v5.models.BannerComponents; import java.util.ArrayList; -import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; -public class InstructionBuilder extends ArrayList { +public class InstructionBuilder { int length = 0; - List abbreviations; - StringBuilder instructionStringBuilder; + Map> abbreviations; + List shieldUrls; + List nodes; + TextView textView; public InstructionBuilder(List bannerComponents, TextView textView) { super(); - instructionStringBuilder = new StringBuilder(); - List shieldUrls = new ArrayList<>(); - abbreviations = new ArrayList<>(); - + this.textView = textView; + nodes = new ArrayList<>(); + shieldUrls = new ArrayList<>(); + abbreviations = new HashMap<>(); for (BannerComponents components : bannerComponents) { if (hasImageUrl(components)) { - addShieldInfo(textView, instructionStringBuilder, shieldUrls, components); - add(new ShieldNode(components)); + addShieldInfo(textView, components); + nodes.add(new ShieldNode(components, length - 1)); + length += components.text().length(); } else if (hasAbbreviation(components)) { - instructionStringBuilder.append(components.text()); - AbbreviationNode abbreviationNode = new AbbreviationNode(components); - add(abbreviationNode); - abbreviations.add(abbreviationNode); + addPriorityInfo(components); + nodes.add(new AbbreviationNode(components)); } else { - instructionStringBuilder.append(components.text()); - add(new Node(components)); + nodes.add(new Node(components)); } + length += components.text().length() + 1; + } + } - instructionStringBuilder.append(" "); + public String getBannerText() { + String bannerText; + int currAbbreviationPriority = 0; + while (!textFits(textView, bannerText = join(nodes))) { + List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); + + for (Integer index : indices) { + abbreviate(index); + } } - Collections.sort(abbreviations); + return bannerText; } - private static boolean hasAbbreviation(BannerComponents components) { - return !TextUtils.isEmpty(components.abbreviation()); + public List getShieldUrls() { + for (BannerShieldInfo bannerShieldInfo : shieldUrls) { + bannerShieldInfo.setStartIndex(nodes.get(bannerShieldInfo.getNodeIndex()).startIndex); + } + return shieldUrls; } - private static boolean hasImageUrl(BannerComponents components) { - return !TextUtils.isEmpty(components.imageBaseUrl()); + private void abbreviate(int index) { + ((AbbreviationNode) nodes.get(index)).setAbbreviate(true); } - private static void addShieldInfo(TextView textView, StringBuilder instructionStringBuilder, - List shieldUrls, BannerComponents components) { - boolean instructionBuilderEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); - int instructionLength = instructionStringBuilder.length(); - int startIndex = instructionBuilderEmpty ? instructionLength : instructionLength + 1; - shieldUrls.add(new BannerShieldInfo(textView.getContext(), components.imageBaseUrl(), - startIndex, components.text())); - instructionStringBuilder.append(components.text()); + private boolean hasAbbreviation(BannerComponents components) { + return !TextUtils.isEmpty(components.abbreviation()); } - public void buildInstruction(TextView textView) { - int currAbbreviationPriority; - while (!textFits(textView, instructionStringBuilder.toString())) { - currAbbreviationPriority = abbreviations.get(0).abbreviationPriority(); - instructionStringBuilder = new StringBuilder(); - - + private boolean hasImageUrl(BannerComponents components) { + return !TextUtils.isEmpty(components.imageBaseUrl()); + } + private void addPriorityInfo(BannerComponents components) { + int abbreviationPriority = components.abbreviationPriority(); + if (abbreviations.get(Integer.valueOf(abbreviationPriority)) == null) { + abbreviations.put(abbreviationPriority, new ArrayList()); } + abbreviations.get(abbreviationPriority).add(Integer.valueOf(nodes.size())); + } + private void addShieldInfo(TextView textView, BannerComponents components) { + shieldUrls.add(new BannerShieldInfo(textView.getContext(), components, + nodes.size())); } - private void abbreviate(int abbreviationPriority) { - int currentIndex = 0; - while (abbreviations.get(currentIndex).abbreviationPriority() == abbreviationPriority) { - get(abbreviations.remove(currentIndex).) + private String join(List tokens) { + StringBuilder stringBuilder = new StringBuilder(); + Iterator iterator = tokens.iterator(); + Node node; + + if (iterator.hasNext()) { + node = iterator.next(); + node.setStartIndex(stringBuilder.length()); + stringBuilder.append(node); + + while (iterator.hasNext()) { + stringBuilder.append(" "); + node = iterator.next(); + node.setStartIndex(stringBuilder.length()); + stringBuilder.append(node); + } } + + return stringBuilder.toString(); } private boolean textFits(TextView textView, String text) { @@ -88,53 +115,75 @@ private boolean textFits(TextView textView, String text) { } class Node { - String text; + BannerComponents bannerComponents; + int startIndex = -1; public Node(BannerComponents bannerComponents) { - this.text = bannerComponents.text(); + this.bannerComponents = bannerComponents; + } + + @Override + public String toString() { + return bannerComponents.text(); } - public String getText() { - return text; + public void setStartIndex(int startIndex) { + this.startIndex = startIndex; } + +// public String getText() { +// return text; +// } } class ShieldNode extends Node { - String url; + int stringIndex; - public ShieldNode(BannerComponents bannerComponents) { - super(bannerComponents); +// String url; - this.url = bannerComponents.imageBaseUrl(); + public ShieldNode(BannerComponents bannerComponents, int stringIndex) { + super(bannerComponents); + this.stringIndex = stringIndex; +// this.url = bannerComponents.imageBaseUrl(); } - String getUrl() { - return url; - } +// +// String getUrl() { +// return url; +// } } - class AbbreviationNode extends Node implements Comparable { - String abbreviation; - int abbreviationPriority; + class AbbreviationNode extends Node { boolean abbreviate; public AbbreviationNode(BannerComponents bannerComponents) { super(bannerComponents); - this.abbreviation = bannerComponents.abbreviation(); - this.abbreviationPriority = bannerComponents.abbreviationPriority(); +// this.abbreviation = bannerComponents.abbreviation(); +// this.abbreviationPriority = bannerComponents.abbreviationPriority(); } - String getAbbreviation() { - return abbreviation; + @Override + public String toString() { + return abbreviate ? bannerComponents.abbreviation() : bannerComponents.text(); } - int getAbbreviationPriority() { - return abbreviationPriority; - } +// String getAbbreviation() { +// return abbreviation; +// } +// +// int getAbbreviationPriority() { +// return abbreviationPriority; +// } void setAbbreviate(boolean abbreviate) { this.abbreviate = abbreviate; } + +// @Override +// public int compareTo(@NonNull AbbreviationNode abbreviationNode) { +// return this.bannerComponents.compareTo(abbreviationNode.bannerComponents); +// +// } } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java new file mode 100644 index 00000000000..4955f0c82ab --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -0,0 +1,4 @@ +package com.mapbox.services.android.navigation.ui.v5.instruction; + +public class InstructionImageLoader { +} diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 8937b9d766a..5a325fb7a47 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -34,8 +34,6 @@ public class InstructionLoader { private Picasso picassoImageLoader; private List targets; private UrlDensityMap urlDensityMap; - private static final String IMAGE_SPACE_PLACEHOLDER = " "; - private static final String SINGLE_SPACE = " "; private InstructionLoader() { } @@ -123,32 +121,35 @@ public void loadInstruction(TextView textView, BannerText bannerText) { return; } - StringBuilder instructionStringBuilder = new StringBuilder(); - List shieldUrls = new ArrayList<>(); - InstructionBuilder instructionBuilder = new InstructionBuilder(bannerText.components(), textView); - - List bannerComponents = bannerText.components(); - Collections.sort(bannerComponents); - - for (BannerComponents components : bannerText.components()) { - if (hasImageUrl(components)) { - addShieldInfo(textView, instructionStringBuilder, shieldUrls, components); - - } else { - String text = components.text(); - boolean textViewIsEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); - String instructionText = textViewIsEmpty ? text : SINGLE_SPACE.concat(text); - instructionStringBuilder.append(instructionText); - } - } + String text = instructionBuilder.getBannerText(); + List shieldUrls = instructionBuilder.getShieldUrls(); + +// StringBuilder instructionStringBuilder = new StringBuilder(); +// List shieldUrls = new ArrayList<>(); +// +// InstructionBuilder instructionBuilder = new InstructionBuilder(bannerText.components(), textView); +// +// List bannerComponents = bannerText.components(); +// Collections.sort(bannerComponents); +// +// for (BannerComponents components : bannerText.components()) { +// if (hasImageUrl(components)) { +// addShieldInfo(textView, instructionStringBuilder, shieldUrls, components) +// } else { +// String text = components.text(); +// boolean textViewIsEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); +// String instructionText = textViewIsEmpty ? text : SINGLE_SPACE.concat(text); +// instructionStringBuilder.append(instructionText); +// } +// } // If there are shield Urls, fetch the corresponding images if (!shieldUrls.isEmpty()) { - createTargets(textView, instructionStringBuilder, shieldUrls); + createTargets(textView, text, shieldUrls); loadTargets(); } else { - textView.setText(instructionStringBuilder); + textView.setText(text); } } @@ -174,19 +175,19 @@ private static boolean hasImageUrl(BannerComponents components) { return !TextUtils.isEmpty(components.imageBaseUrl()); } - private static void addShieldInfo(TextView textView, StringBuilder instructionStringBuilder, - List shieldUrls, BannerComponents components) { - boolean instructionBuilderEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); - int instructionLength = instructionStringBuilder.length(); - int startIndex = instructionBuilderEmpty ? instructionLength : instructionLength + 1; - shieldUrls.add(new BannerShieldInfo(textView.getContext(), components.imageBaseUrl(), - startIndex, components.text())); - instructionStringBuilder.append(components.text()); - } - - private void createTargets(TextView textView, StringBuilder instructionStringBuilder, +// private static void addShieldInfo(TextView textView, StringBuilder instructionStringBuilder, +// List shieldUrls, BannerComponents components) { +// boolean instructionBuilderEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); +// int instructionLength = instructionStringBuilder.length(); +// int startIndex = instructionBuilderEmpty ? instructionLength : instructionLength + 1; +// shieldUrls.add(new BannerShieldInfo(textView.getContext(), components.imageBaseUrl(), +// startIndex, components.text())); +// instructionStringBuilder.append(components.text()); +// } + + private void createTargets(TextView textView, String text, List shields) { - Spannable instructionSpannable = new SpannableString(instructionStringBuilder); + Spannable instructionSpannable = new SpannableString(text); for (final BannerShieldInfo shield : shields) { targets.add(new InstructionTarget(textView, instructionSpannable, shields, shield, new InstructionTarget.InstructionLoadedCallback() { From 91bafc72b6930660560dd1603bc5fe876c3625b2 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 25 Apr 2018 15:58:21 -0400 Subject: [PATCH 07/36] Cleanup --- .../ui/v5/instruction/InstructionBuilder.java | 28 ------------------ .../ui/v5/instruction/InstructionLoader.java | 29 ------------------- 2 files changed, 57 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java index dece5245d1d..6549d8eab4b 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java @@ -130,27 +130,16 @@ public String toString() { public void setStartIndex(int startIndex) { this.startIndex = startIndex; } - -// public String getText() { -// return text; -// } } class ShieldNode extends Node { int stringIndex; -// String url; public ShieldNode(BannerComponents bannerComponents, int stringIndex) { super(bannerComponents); this.stringIndex = stringIndex; -// this.url = bannerComponents.imageBaseUrl(); } - -// -// String getUrl() { -// return url; -// } } class AbbreviationNode extends Node { @@ -158,9 +147,6 @@ class AbbreviationNode extends Node { public AbbreviationNode(BannerComponents bannerComponents) { super(bannerComponents); - -// this.abbreviation = bannerComponents.abbreviation(); -// this.abbreviationPriority = bannerComponents.abbreviationPriority(); } @Override @@ -168,22 +154,8 @@ public String toString() { return abbreviate ? bannerComponents.abbreviation() : bannerComponents.text(); } -// String getAbbreviation() { -// return abbreviation; -// } -// -// int getAbbreviationPriority() { -// return abbreviationPriority; -// } - void setAbbreviate(boolean abbreviate) { this.abbreviate = abbreviate; } - -// @Override -// public int compareTo(@NonNull AbbreviationNode abbreviationNode) { -// return this.bannerComponents.compareTo(abbreviationNode.bannerComponents); -// -// } } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 5a325fb7a47..ece8b9868cb 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -125,25 +125,6 @@ public void loadInstruction(TextView textView, BannerText bannerText) { String text = instructionBuilder.getBannerText(); List shieldUrls = instructionBuilder.getShieldUrls(); -// StringBuilder instructionStringBuilder = new StringBuilder(); -// List shieldUrls = new ArrayList<>(); -// -// InstructionBuilder instructionBuilder = new InstructionBuilder(bannerText.components(), textView); -// -// List bannerComponents = bannerText.components(); -// Collections.sort(bannerComponents); -// -// for (BannerComponents components : bannerText.components()) { -// if (hasImageUrl(components)) { -// addShieldInfo(textView, instructionStringBuilder, shieldUrls, components) -// } else { -// String text = components.text(); -// boolean textViewIsEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); -// String instructionText = textViewIsEmpty ? text : SINGLE_SPACE.concat(text); -// instructionStringBuilder.append(instructionText); -// } -// } - // If there are shield Urls, fetch the corresponding images if (!shieldUrls.isEmpty()) { createTargets(textView, text, shieldUrls); @@ -175,16 +156,6 @@ private static boolean hasImageUrl(BannerComponents components) { return !TextUtils.isEmpty(components.imageBaseUrl()); } -// private static void addShieldInfo(TextView textView, StringBuilder instructionStringBuilder, -// List shieldUrls, BannerComponents components) { -// boolean instructionBuilderEmpty = TextUtils.isEmpty(instructionStringBuilder.toString()); -// int instructionLength = instructionStringBuilder.length(); -// int startIndex = instructionBuilderEmpty ? instructionLength : instructionLength + 1; -// shieldUrls.add(new BannerShieldInfo(textView.getContext(), components.imageBaseUrl(), -// startIndex, components.text())); -// instructionStringBuilder.append(components.text()); -// } - private void createTargets(TextView textView, String text, List shields) { Spannable instructionSpannable = new SpannableString(text); From 9cf38b37c6876c4fc302e5876e2924383cdc1822 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 25 Apr 2018 17:07:31 -0400 Subject: [PATCH 08/36] Refactored to separate concerns --- .../instruction/AbbreviationCoordinator.java | 67 +++++++ .../ui/v5/instruction/InstructionBuilder.java | 161 --------------- .../instruction/InstructionImageLoader.java | 163 ++++++++++++++++ .../ui/v5/instruction/InstructionLoader.java | 184 +++++++++++------- .../ui/v5/instruction/InstructionTarget.java | 2 +- 5 files changed, 348 insertions(+), 229 deletions(-) create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java delete mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java new file mode 100644 index 00000000000..f8ede9dbdac --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -0,0 +1,67 @@ +package com.mapbox.services.android.navigation.ui.v5.instruction; + +import android.graphics.Paint; +import android.widget.TextView; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class AbbreviationCoordinator { + Map> abbreviations; + TextView textView; + + public AbbreviationCoordinator(TextView textView, Map> abbreviations) { + this.textView = textView; + this.abbreviations = abbreviations; + } + + public String abbreviateBannerText(List nodes) { + String bannerText; + int currAbbreviationPriority = 0; + while (!textFits(textView, bannerText = join(nodes))) { + List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); + + if (indices == null) { + continue; + } + + for (Integer index : indices) { + abbreviate(nodes.get(index)); + } + } + + return bannerText; + } + + private void abbreviate(InstructionLoader.Node node) { + ((InstructionLoader.AbbreviationNode) node).setAbbreviate(true); + } + + private String join(List tokens) { + StringBuilder stringBuilder = new StringBuilder(); + Iterator iterator = tokens.iterator(); + InstructionLoader.Node node; + + if (iterator.hasNext()) { + node = iterator.next(); + node.setStartIndex(stringBuilder.length()); + stringBuilder.append(node); + + while (iterator.hasNext()) { + stringBuilder.append(" "); + node = iterator.next(); + node.setStartIndex(stringBuilder.length()); + stringBuilder.append(node); + } + } + + return stringBuilder.toString(); + } + + private boolean textFits(TextView textView, String text) { + Paint paint = new Paint(textView.getPaint()); + float width = paint.measureText(text); + return width < textView.getWidth(); + } +} diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java deleted file mode 100644 index 6549d8eab4b..00000000000 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionBuilder.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.mapbox.services.android.navigation.ui.v5.instruction; - -import android.graphics.Paint; -import android.text.TextUtils; -import android.widget.TextView; - -import com.mapbox.api.directions.v5.models.BannerComponents; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class InstructionBuilder { - int length = 0; - Map> abbreviations; - List shieldUrls; - List nodes; - TextView textView; - - public InstructionBuilder(List bannerComponents, TextView textView) { - super(); - this.textView = textView; - nodes = new ArrayList<>(); - shieldUrls = new ArrayList<>(); - abbreviations = new HashMap<>(); - - for (BannerComponents components : bannerComponents) { - if (hasImageUrl(components)) { - addShieldInfo(textView, components); - nodes.add(new ShieldNode(components, length - 1)); - length += components.text().length(); - } else if (hasAbbreviation(components)) { - addPriorityInfo(components); - nodes.add(new AbbreviationNode(components)); - } else { - nodes.add(new Node(components)); - } - length += components.text().length() + 1; - } - } - - public String getBannerText() { - String bannerText; - int currAbbreviationPriority = 0; - while (!textFits(textView, bannerText = join(nodes))) { - List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); - - for (Integer index : indices) { - abbreviate(index); - } - } - - return bannerText; - } - - public List getShieldUrls() { - for (BannerShieldInfo bannerShieldInfo : shieldUrls) { - bannerShieldInfo.setStartIndex(nodes.get(bannerShieldInfo.getNodeIndex()).startIndex); - } - return shieldUrls; - } - - private void abbreviate(int index) { - ((AbbreviationNode) nodes.get(index)).setAbbreviate(true); - } - - private boolean hasAbbreviation(BannerComponents components) { - return !TextUtils.isEmpty(components.abbreviation()); - } - - private boolean hasImageUrl(BannerComponents components) { - return !TextUtils.isEmpty(components.imageBaseUrl()); - } - - private void addPriorityInfo(BannerComponents components) { - int abbreviationPriority = components.abbreviationPriority(); - if (abbreviations.get(Integer.valueOf(abbreviationPriority)) == null) { - abbreviations.put(abbreviationPriority, new ArrayList()); - } - abbreviations.get(abbreviationPriority).add(Integer.valueOf(nodes.size())); - } - - private void addShieldInfo(TextView textView, BannerComponents components) { - shieldUrls.add(new BannerShieldInfo(textView.getContext(), components, - nodes.size())); - } - - private String join(List tokens) { - StringBuilder stringBuilder = new StringBuilder(); - Iterator iterator = tokens.iterator(); - Node node; - - if (iterator.hasNext()) { - node = iterator.next(); - node.setStartIndex(stringBuilder.length()); - stringBuilder.append(node); - - while (iterator.hasNext()) { - stringBuilder.append(" "); - node = iterator.next(); - node.setStartIndex(stringBuilder.length()); - stringBuilder.append(node); - } - } - - return stringBuilder.toString(); - } - - private boolean textFits(TextView textView, String text) { - Paint paint = new Paint(textView.getPaint()); - float width = paint.measureText(text); - return width < textView.getWidth(); - } - - class Node { - BannerComponents bannerComponents; - int startIndex = -1; - - public Node(BannerComponents bannerComponents) { - this.bannerComponents = bannerComponents; - } - - @Override - public String toString() { - return bannerComponents.text(); - } - - public void setStartIndex(int startIndex) { - this.startIndex = startIndex; - } - } - - class ShieldNode extends Node { - int stringIndex; - - - public ShieldNode(BannerComponents bannerComponents, int stringIndex) { - super(bannerComponents); - this.stringIndex = stringIndex; - } - } - - class AbbreviationNode extends Node { - boolean abbreviate; - - public AbbreviationNode(BannerComponents bannerComponents) { - super(bannerComponents); - } - - @Override - public String toString() { - return abbreviate ? bannerComponents.abbreviation() : bannerComponents.text(); - } - - void setAbbreviate(boolean abbreviate) { - this.abbreviate = abbreviate; - } - } -} diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index 4955f0c82ab..fa27ef4a1ab 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -1,4 +1,167 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; +import android.content.Context; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextUtils; +import android.text.style.ImageSpan; +import android.widget.TextView; + +import com.mapbox.api.directions.v5.models.BannerComponents; +import com.mapbox.api.directions.v5.models.BannerInstructions; +import com.mapbox.api.directions.v5.models.BannerText; +import com.mapbox.api.directions.v5.models.LegStep; +import com.squareup.picasso.Picasso; + +import java.util.ArrayList; +import java.util.List; + +/** + * Utility class that can be used to load a given {@link BannerText} into the provided + * {@link TextView}. + *

+ * For each {@link BannerComponents}, either the text or given shield URL will be used (the shield + * URL taking priority). + *

+ * If a shield URL is found, {@link Picasso} is used to load the image. Then, once the image is loaded, + * a new {@link ImageSpan} is created and set to the appropriate position of the {@link Spannable}/ + */ public class InstructionImageLoader { + + private static InstructionImageLoader instance; + private boolean isInitialized; + private Picasso picassoImageLoader; + private List targets; + private UrlDensityMap urlDensityMap; + + private InstructionImageLoader() { + } + + /** + * Primary access method (using singleton pattern) + * + * @return InstructionLoader + */ + public static synchronized InstructionImageLoader getInstance() { + if (instance == null) { + instance = new InstructionImageLoader(); + } + + return instance; + } + + /** + * Must be called before loading images. + *

+ * Initializes a new {@link Picasso} instance as well as the + * {@link ArrayList} of {@link InstructionTarget}. + * + * @param context to init Picasso + */ + public void initialize(Context context) { + if (!isInitialized) { + Picasso.Builder builder = new Picasso.Builder(context) + .loggingEnabled(true); + picassoImageLoader = builder.build(); + + this.urlDensityMap = new UrlDensityMap(context); + targets = new ArrayList<>(); + + isInitialized = true; + } + } + + /** + * Will pre-fetch images for a given {@link LegStep}. + *

+ * If loaded successfully, this will allow the images to be displayed + * without delay in the {@link InstructionView}. + * + * @param step providing the image Urls + */ + public void prefetchImageCache(LegStep step) { + + if (step == null || step.bannerInstructions() == null + || step.bannerInstructions().isEmpty()) { + return; + } + + checkIsInitialized(); + + List bannerInstructionList = new ArrayList<>(step.bannerInstructions()); + for (BannerInstructions instructions : bannerInstructionList) { + if (hasComponents(instructions.primary())) { + fetchImageBaseUrls(instructions.primary()); + } + if (hasComponents(instructions.secondary())) { + fetchImageBaseUrls(instructions.secondary()); + } + } + } + + public void shutdown() { + targets.clear(); + } + + /** + * Takes the given components from the {@link BannerText} and creates + * a new {@link Spannable} with text / {@link ImageSpan}s which is loaded + * into the given {@link TextView}. + * + * @param textView target for the banner text + * @param bannerText with components to be extracted + * @since 0.9.0 + */ + public void loadImages(TextView textView, List shieldUrls) { + createTargets(textView, shieldUrls); + loadTargets(); + } + + private static boolean hasComponents(BannerText bannerText) { + return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); + } + + /** + * Takes a given {@link BannerText} and fetches a valid + * imageBaseUrl if one is found. + * + * @param bannerText to provide the base URL + */ + private void fetchImageBaseUrls(BannerText bannerText) { + for (BannerComponents components : bannerText.components()) { + if (hasImageUrl(components)) { + picassoImageLoader.load(urlDensityMap.get(components.imageBaseUrl())).fetch(); + } + } + } + + private static boolean hasImageUrl(BannerComponents components) { + return !TextUtils.isEmpty(components.imageBaseUrl()); + } + + private void createTargets(TextView textView, List shields) { + Spannable instructionSpannable = new SpannableString(textView.getText()); + for (final BannerShieldInfo shield : shields) { + targets.add(new InstructionTarget(textView, instructionSpannable, shields, shield, + new InstructionTarget.InstructionLoadedCallback() { + @Override + public void onInstructionLoaded(InstructionTarget target) { + targets.remove(target); + } + })); + } + } + + private void loadTargets() { + for (InstructionTarget target : new ArrayList<>(targets)) { + picassoImageLoader.load(target.getShield().getUrl()) + .into(target); + } + } + + private void checkIsInitialized() { + if (!isInitialized) { + throw new RuntimeException("InstructionLoader must be initialized prior to loading image URLs"); + } + } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index ece8b9868cb..0f0f0ff2bd2 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -2,20 +2,19 @@ import android.content.Context; import android.text.Spannable; -import android.text.SpannableString; import android.text.TextUtils; import android.text.style.ImageSpan; import android.widget.TextView; import com.mapbox.api.directions.v5.models.BannerComponents; -import com.mapbox.api.directions.v5.models.BannerInstructions; import com.mapbox.api.directions.v5.models.BannerText; import com.mapbox.api.directions.v5.models.LegStep; import com.squareup.picasso.Picasso; import java.util.ArrayList; -import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Utility class that can be used to load a given {@link BannerText} into the provided @@ -30,10 +29,13 @@ public class InstructionLoader { private static InstructionLoader instance; + private static InstructionImageLoader instructionImageLoader; + List shieldUrls; + List nodes; + Map> abbreviations; + int length = 0; + private boolean isInitialized; - private Picasso picassoImageLoader; - private List targets; - private UrlDensityMap urlDensityMap; private InstructionLoader() { } @@ -61,12 +63,8 @@ public static synchronized InstructionLoader getInstance() { */ public void initialize(Context context) { if (!isInitialized) { - Picasso.Builder builder = new Picasso.Builder(context) - .loggingEnabled(true); - picassoImageLoader = builder.build(); - - this.urlDensityMap = new UrlDensityMap(context); - targets = new ArrayList<>(); + instructionImageLoader = InstructionImageLoader.getInstance(); + instructionImageLoader.initialize(context); isInitialized = true; } @@ -81,27 +79,11 @@ public void initialize(Context context) { * @param step providing the image Urls */ public void prefetchImageCache(LegStep step) { - - if (step == null || step.bannerInstructions() == null - || step.bannerInstructions().isEmpty()) { - return; - } - - checkIsInitialized(); - - List bannerInstructionList = new ArrayList<>(step.bannerInstructions()); - for (BannerInstructions instructions : bannerInstructionList) { - if (hasComponents(instructions.primary())) { - fetchImageBaseUrls(instructions.primary()); - } - if (hasComponents(instructions.secondary())) { - fetchImageBaseUrls(instructions.secondary()); - } - } + instructionImageLoader.prefetchImageCache(step); } public void shutdown() { - targets.clear(); + instructionImageLoader.shutdown(); } /** @@ -114,67 +96,90 @@ public void shutdown() { * @since 0.9.0 */ public void loadInstruction(TextView textView, BannerText bannerText) { - checkIsInitialized(); if (!hasComponents(bannerText)) { return; } - InstructionBuilder instructionBuilder = new InstructionBuilder(bannerText.components(), textView); - String text = instructionBuilder.getBannerText(); - List shieldUrls = instructionBuilder.getShieldUrls(); + parseBannerComponents(textView, bannerText.components()); + setText(textView); + loadImages(textView); + } + + private void loadImages(TextView textView) { + List shieldUrls = getShieldUrls(); - // If there are shield Urls, fetch the corresponding images - if (!shieldUrls.isEmpty()) { - createTargets(textView, text, shieldUrls); - loadTargets(); - } else { - textView.setText(text); + if (hasImages(shieldUrls)) { + instructionImageLoader.loadImages(textView, shieldUrls); } } - private static boolean hasComponents(BannerText bannerText) { - return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); + private void setText(TextView textView) { + String text = getAbbreviatedBannerText(textView); + textView.setText(text); } - /** - * Takes a given {@link BannerText} and fetches a valid - * imageBaseUrl if one is found. - * - * @param bannerText to provide the base URL - */ - private void fetchImageBaseUrls(BannerText bannerText) { - for (BannerComponents components : bannerText.components()) { + private String getAbbreviatedBannerText(TextView textView) { + AbbreviationCoordinator abbreviationCoordinator = new AbbreviationCoordinator(textView, abbreviations); + return abbreviationCoordinator.abbreviateBannerText(nodes); + } + + private void parseBannerComponents(TextView textView, List bannerComponents) { + nodes = new ArrayList<>(); + shieldUrls = new ArrayList<>(); + abbreviations = new HashMap<>(); + + for (BannerComponents components : bannerComponents) { if (hasImageUrl(components)) { - picassoImageLoader.load(urlDensityMap.get(components.imageBaseUrl())).fetch(); + addShieldInfo(textView, components); + nodes.add(new ShieldNode(components, length - 1)); + length += components.text().length(); + } else if (hasAbbreviation(components)) { + addPriorityInfo(components); + nodes.add(new AbbreviationNode(components)); + } else { + nodes.add(new Node(components)); } + length += components.text().length() + 1; } } - private static boolean hasImageUrl(BannerComponents components) { + private boolean hasAbbreviation(BannerComponents components) { + return !TextUtils.isEmpty(components.abbreviation()); + } + + private boolean hasImageUrl(BannerComponents components) { return !TextUtils.isEmpty(components.imageBaseUrl()); } - private void createTargets(TextView textView, String text, - List shields) { - Spannable instructionSpannable = new SpannableString(text); - for (final BannerShieldInfo shield : shields) { - targets.add(new InstructionTarget(textView, instructionSpannable, shields, shield, - new InstructionTarget.InstructionLoadedCallback() { - @Override - public void onInstructionLoaded(InstructionTarget target) { - targets.remove(target); - } - })); + private void addPriorityInfo(BannerComponents components) { + int abbreviationPriority = components.abbreviationPriority(); + if (abbreviations.get(Integer.valueOf(abbreviationPriority)) == null) { + abbreviations.put(abbreviationPriority, new ArrayList()); } + abbreviations.get(abbreviationPriority).add(Integer.valueOf(nodes.size())); } - private void loadTargets() { - for (InstructionTarget target : new ArrayList<>(targets)) { - picassoImageLoader.load(target.getShield().getUrl()) - .into(target); + + public List getShieldUrls() { + for (BannerShieldInfo bannerShieldInfo : shieldUrls) { + bannerShieldInfo.setStartIndex(nodes.get(bannerShieldInfo.getNodeIndex()).startIndex); } + return shieldUrls; + } + + private void addShieldInfo(TextView textView, BannerComponents components) { + shieldUrls.add(new BannerShieldInfo(textView.getContext(), components, + nodes.size())); + } + + private static boolean hasComponents(BannerText bannerText) { + return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); + } + + private static boolean hasImages(List shieldUrls) { + return !shieldUrls.isEmpty(); } private void checkIsInitialized() { @@ -182,4 +187,49 @@ private void checkIsInitialized() { throw new RuntimeException("InstructionLoader must be initialized prior to loading image URLs"); } } + + static class Node { + BannerComponents bannerComponents; + int startIndex = -1; + + Node(BannerComponents bannerComponents) { + this.bannerComponents = bannerComponents; + } + + @Override + public String toString() { + return bannerComponents.text(); + } + + public void setStartIndex(int startIndex) { + this.startIndex = startIndex; + } + } + + static class ShieldNode extends Node { + int stringIndex; + + + ShieldNode(BannerComponents bannerComponents, int stringIndex) { + super(bannerComponents); + this.stringIndex = stringIndex; + } + } + + static class AbbreviationNode extends Node { + boolean abbreviate; + + AbbreviationNode(BannerComponents bannerComponents) { + super(bannerComponents); + } + + @Override + public String toString() { + return abbreviate ? bannerComponents.abbreviation() : bannerComponents.text(); + } + + void setAbbreviate(boolean abbreviate) { + this.abbreviate = abbreviate; + } + } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java index fce7e9d0ca8..f5649aefb37 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java @@ -25,7 +25,7 @@ public class InstructionTarget implements Target { private BannerShieldInfo shield; private InstructionLoadedCallback instructionLoadedCallback; - InstructionTarget(TextView textView, Spannable instructionSpannable, + InstructionTarget(TextView textView, Spannable instructionSpannable, List shields, BannerShieldInfo shield, InstructionLoadedCallback instructionLoadedCallback) { this.textView = textView; From 21a57b511ec0686e8585232e3ecaba87682ca400 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 25 Apr 2018 17:25:47 -0400 Subject: [PATCH 09/36] Added startIndex to Node constructor for consistency --- .../ui/v5/instruction/InstructionLoader.java | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 0f0f0ff2bd2..20d042f28f3 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -134,12 +134,11 @@ private void parseBannerComponents(TextView textView, List ban if (hasImageUrl(components)) { addShieldInfo(textView, components); nodes.add(new ShieldNode(components, length - 1)); - length += components.text().length(); } else if (hasAbbreviation(components)) { addPriorityInfo(components); - nodes.add(new AbbreviationNode(components)); + nodes.add(new AbbreviationNode(components, length - 1)); } else { - nodes.add(new Node(components)); + nodes.add(new Node(components, length - 1)); } length += components.text().length() + 1; } @@ -161,7 +160,6 @@ private void addPriorityInfo(BannerComponents components) { abbreviations.get(abbreviationPriority).add(Integer.valueOf(nodes.size())); } - public List getShieldUrls() { for (BannerShieldInfo bannerShieldInfo : shieldUrls) { bannerShieldInfo.setStartIndex(nodes.get(bannerShieldInfo.getNodeIndex()).startIndex); @@ -170,8 +168,7 @@ public List getShieldUrls() { } private void addShieldInfo(TextView textView, BannerComponents components) { - shieldUrls.add(new BannerShieldInfo(textView.getContext(), components, - nodes.size())); + shieldUrls.add(new BannerShieldInfo(textView.getContext(), components, nodes.size())); } private static boolean hasComponents(BannerText bannerText) { @@ -190,10 +187,11 @@ private void checkIsInitialized() { static class Node { BannerComponents bannerComponents; - int startIndex = -1; + int startIndex; - Node(BannerComponents bannerComponents) { + Node(BannerComponents bannerComponents, int startIndex) { this.bannerComponents = bannerComponents; + this.startIndex = startIndex; } @Override @@ -207,20 +205,16 @@ public void setStartIndex(int startIndex) { } static class ShieldNode extends Node { - int stringIndex; - - - ShieldNode(BannerComponents bannerComponents, int stringIndex) { - super(bannerComponents); - this.stringIndex = stringIndex; + ShieldNode(BannerComponents bannerComponents, int startIndex) { + super(bannerComponents, startIndex); } } static class AbbreviationNode extends Node { boolean abbreviate; - AbbreviationNode(BannerComponents bannerComponents) { - super(bannerComponents); + AbbreviationNode(BannerComponents bannerComponents, int startIndex) { + super(bannerComponents, startIndex); } @Override From 2c23887dcbc5cbf175e9473740f52b69da764fb1 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 25 Apr 2018 17:33:07 -0400 Subject: [PATCH 10/36] Cleanup --- .../navigation/ui/v5/instruction/AbbreviationCoordinator.java | 3 ++- .../navigation/ui/v5/instruction/InstructionImageLoader.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index f8ede9dbdac..f89fd174fcf 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -8,6 +8,7 @@ import java.util.Map; public class AbbreviationCoordinator { + private static final String SINGLE_SPACE = " "; Map> abbreviations; TextView textView; @@ -49,7 +50,7 @@ private String join(List tokens) { stringBuilder.append(node); while (iterator.hasNext()) { - stringBuilder.append(" "); + stringBuilder.append(SINGLE_SPACE); node = iterator.next(); node.setStartIndex(stringBuilder.length()); stringBuilder.append(node); diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index fa27ef4a1ab..82a5d6391f5 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -109,7 +109,6 @@ public void shutdown() { * into the given {@link TextView}. * * @param textView target for the banner text - * @param bannerText with components to be extracted * @since 0.9.0 */ public void loadImages(TextView textView, List shieldUrls) { From 183c2d91479d0d14c84dc555b6c58d4a8f616fd8 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 25 Apr 2018 17:35:16 -0400 Subject: [PATCH 11/36] Removed snapshots --- build.gradle | 2 -- libandroid-navigation-ui/build.gradle | 5 ----- 2 files changed, 7 deletions(-) diff --git a/build.gradle b/build.gradle index 31ed67a53b3..e66e3e3c9a1 100644 --- a/build.gradle +++ b/build.gradle @@ -24,8 +24,6 @@ task testReport(type: TestReport, group: 'Build') { allprojects { repositories { - mavenCentral() - maven { url "http://oss.sonatype.org/content/repositories/snapshots/" } maven { url 'https://plugins.gradle.org/m2' } google() jcenter() diff --git a/libandroid-navigation-ui/build.gradle b/libandroid-navigation-ui/build.gradle index 05226d70dc1..c8afda54816 100644 --- a/libandroid-navigation-ui/build.gradle +++ b/libandroid-navigation-ui/build.gradle @@ -31,11 +31,6 @@ android { } } -repositories { - mavenCentral() - maven { url "http://oss.sonatype.org/content/repositories/snapshots/" } -} - dependencies { // Navigation SDK api project(':libandroid-navigation') From 01707cd67939d12cdf18464ebcc236ef9f0da1e5 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 25 Apr 2018 17:37:54 -0400 Subject: [PATCH 12/36] Added private modifiers --- .../ui/v5/instruction/AbbreviationCoordinator.java | 4 ++-- .../ui/v5/instruction/InstructionLoader.java | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index f89fd174fcf..27cf7832361 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -9,8 +9,8 @@ public class AbbreviationCoordinator { private static final String SINGLE_SPACE = " "; - Map> abbreviations; - TextView textView; + private Map> abbreviations; + private TextView textView; public AbbreviationCoordinator(TextView textView, Map> abbreviations) { this.textView = textView; diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 20d042f28f3..85a2a2c1bbf 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -30,9 +30,9 @@ public class InstructionLoader { private static InstructionLoader instance; private static InstructionImageLoader instructionImageLoader; - List shieldUrls; - List nodes; - Map> abbreviations; + private List shieldUrls; + private List nodes; + private Map> abbreviations; int length = 0; private boolean isInitialized; @@ -186,8 +186,8 @@ private void checkIsInitialized() { } static class Node { - BannerComponents bannerComponents; - int startIndex; + protected BannerComponents bannerComponents; + protected int startIndex; Node(BannerComponents bannerComponents, int startIndex) { this.bannerComponents = bannerComponents; @@ -211,7 +211,7 @@ static class ShieldNode extends Node { } static class AbbreviationNode extends Node { - boolean abbreviate; + protected boolean abbreviate; AbbreviationNode(BannerComponents bannerComponents, int startIndex) { super(bannerComponents, startIndex); @@ -222,7 +222,7 @@ public String toString() { return abbreviate ? bannerComponents.abbreviation() : bannerComponents.text(); } - void setAbbreviate(boolean abbreviate) { + public void setAbbreviate(boolean abbreviate) { this.abbreviate = abbreviate; } } From ef73dd9e47a52eb72ea158cd953a9ce01462110c Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 25 Apr 2018 17:43:08 -0400 Subject: [PATCH 13/36] Removed logging --- .../navigation/ui/v5/instruction/InstructionTarget.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java index f5649aefb37..f27d80bbd89 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java @@ -7,7 +7,6 @@ import android.text.Spanned; import android.text.TextUtils; import android.text.style.ImageSpan; -import android.util.Log; import android.widget.TextView; import com.squareup.picasso.Picasso; @@ -49,13 +48,6 @@ public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { int right = bottom * bitmap.getWidth() / bitmap.getHeight(); drawable.setBounds(0, 0, right, bottom); - String tag = "InstructionTarget"; - Log.d(tag, "\ninstruction spannable: " + instructionSpannable); - Log.d(tag, "instruction spannable length: " + instructionSpannable.length()); - Log.d(tag, "shield text: " + shield.getText()); - Log.d(tag, "shield start/end: " + shield.getStartIndex() + ", " + shield.getEndIndex()); - Log.d(tag, "~~~~~~~~~~~~~~"); - // Create and set a new ImageSpan at the given index with the Drawable instructionSpannable.setSpan(new ImageSpan(drawable), shield.getStartIndex(), shield.getEndIndex(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); From 8de18f2aec78f53a0c173b27010b92593735cb9a Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Thu, 26 Apr 2018 09:49:51 -0400 Subject: [PATCH 14/36] Fixed checkstyle issue --- .../ui/v5/instruction/AbbreviationCoordinator.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index 27cf7832361..37b9a68d298 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -18,9 +18,9 @@ public AbbreviationCoordinator(TextView textView, Map> ab } public String abbreviateBannerText(List nodes) { - String bannerText; + String bannerText = join(nodes); int currAbbreviationPriority = 0; - while (!textFits(textView, bannerText = join(nodes))) { + while (!textFits(textView, bannerText)) { List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); if (indices == null) { @@ -30,6 +30,8 @@ public String abbreviateBannerText(List nodes) { for (Integer index : indices) { abbreviate(nodes.get(index)); } + + bannerText = join(nodes); } return bannerText; From 95a724b08a6f6a4cc351096f2a4ecf35c87cde7c Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Mon, 30 Apr 2018 15:41:51 -0400 Subject: [PATCH 15/36] Refactored to separate concerns even further --- .../instruction/AbbreviationCoordinator.java | 90 +++++++++++---- .../instruction/InstructionImageLoader.java | 41 ++++++- .../ui/v5/instruction/InstructionLoader.java | 103 +++++------------- 3 files changed, 140 insertions(+), 94 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index 37b9a68d298..05943262bf3 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -3,22 +3,54 @@ import android.graphics.Paint; import android.widget.TextView; +import com.mapbox.api.directions.v5.models.BannerComponents; +import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.BannerComponentNode; + +import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +/** + * This class allows text to be constructed to fit a given TextView, given specified + * BannerComponents containing abbreviation information and given a list of BannerComponentNodes, + * constructed by InstructionLoader. + */ public class AbbreviationCoordinator { private static final String SINGLE_SPACE = " "; private Map> abbreviations; - private TextView textView; - public AbbreviationCoordinator(TextView textView, Map> abbreviations) { - this.textView = textView; - this.abbreviations = abbreviations; + public AbbreviationCoordinator() { + abbreviations = new HashMap<>(); + } + + /** + * Adds the given BannerComponents object to the list of abbreviations so that when the list of + * BannerComponentNodes is completed, text can be abbreviated properly to fit the specified + * TextView. + * + * @param bannerComponents object holding the abbreviation information + * @param index in the list of BannerComponentNodes + */ + public void addPriorityInfo(BannerComponents bannerComponents, int index) { + int abbreviationPriority = bannerComponents.abbreviationPriority(); + if (abbreviations.get(Integer.valueOf(abbreviationPriority)) == null) { + abbreviations.put(abbreviationPriority, new ArrayList()); + } + abbreviations.get(abbreviationPriority).add(index); } - public String abbreviateBannerText(List nodes) { - String bannerText = join(nodes); + /** + * Using the abbreviations HashMap which should already be populated, abbreviates the text in the + * bannerConmponentNodes until the text fits the given TextView. + * + * @param bannerComponentNodes containing the text to construct + * @param textView to check the text fits + * @return the properly abbreviated string that will fit in the TextView + */ + public String abbreviateBannerText(List bannerComponentNodes, TextView textView) { + String bannerText = join(bannerComponentNodes); int currAbbreviationPriority = 0; while (!textFits(textView, bannerText)) { List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); @@ -28,34 +60,34 @@ public String abbreviateBannerText(List nodes) { } for (Integer index : indices) { - abbreviate(nodes.get(index)); + abbreviate(bannerComponentNodes.get(index)); } - bannerText = join(nodes); + bannerText = join(bannerComponentNodes); } return bannerText; } - private void abbreviate(InstructionLoader.Node node) { - ((InstructionLoader.AbbreviationNode) node).setAbbreviate(true); + private void abbreviate(BannerComponentNode bannerComponentNode) { + ((AbbreviationBannerComponentNode) bannerComponentNode).setAbbreviate(true); } - private String join(List tokens) { + private String join(List tokens) { StringBuilder stringBuilder = new StringBuilder(); - Iterator iterator = tokens.iterator(); - InstructionLoader.Node node; + Iterator iterator = tokens.iterator(); + BannerComponentNode bannerComponentNode; if (iterator.hasNext()) { - node = iterator.next(); - node.setStartIndex(stringBuilder.length()); - stringBuilder.append(node); + bannerComponentNode = iterator.next(); + bannerComponentNode.setStartIndex(stringBuilder.length()); + stringBuilder.append(bannerComponentNode); while (iterator.hasNext()) { stringBuilder.append(SINGLE_SPACE); - node = iterator.next(); - node.setStartIndex(stringBuilder.length()); - stringBuilder.append(node); + bannerComponentNode = iterator.next(); + bannerComponentNode.setStartIndex(stringBuilder.length()); + stringBuilder.append(bannerComponentNode); } } @@ -67,4 +99,24 @@ private boolean textFits(TextView textView, String text) { float width = paint.measureText(text); return width < textView.getWidth(); } + + /** + * Class used by InstructionLoader to determine that a BannerComponent contains an abbreviation + */ + static class AbbreviationBannerComponentNode extends BannerComponentNode { + protected boolean abbreviate; + + AbbreviationBannerComponentNode(BannerComponents bannerComponents, int startIndex) { + super(bannerComponents, startIndex); + } + + @Override + public String toString() { + return abbreviate ? bannerComponents.abbreviation() : bannerComponents.text(); + } + + public void setAbbreviate(boolean abbreviate) { + this.abbreviate = abbreviate; + } + } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index 82a5d6391f5..a8f57c23f5b 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -11,6 +11,7 @@ import com.mapbox.api.directions.v5.models.BannerInstructions; import com.mapbox.api.directions.v5.models.BannerText; import com.mapbox.api.directions.v5.models.LegStep; +import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.BannerComponentNode; import com.squareup.picasso.Picasso; import java.util.ArrayList; @@ -33,6 +34,7 @@ public class InstructionImageLoader { private Picasso picassoImageLoader; private List targets; private UrlDensityMap urlDensityMap; + private List shieldUrls; private InstructionImageLoader() { } @@ -66,11 +68,24 @@ public void initialize(Context context) { this.urlDensityMap = new UrlDensityMap(context); targets = new ArrayList<>(); + shieldUrls = new ArrayList<>(); isInitialized = true; } } + /** + * Uses the given BannerComponents object to construct a BannerShieldInfo object containing the + * information needed to load the proper image into the TextView where appropriate. + * + * @param textView to insert image into + * @param components containing image info + * @param index of the BannerComponentNode which refers to the given BannerComponents + */ + public void addShieldInfo(TextView textView, BannerComponents components, int index) { + shieldUrls.add(new BannerShieldInfo(textView.getContext(), components, index)); + } + /** * Will pre-fetch images for a given {@link LegStep}. *

@@ -111,15 +126,30 @@ public void shutdown() { * @param textView target for the banner text * @since 0.9.0 */ - public void loadImages(TextView textView, List shieldUrls) { + public void loadImages(TextView textView, List bannerComponentNodes) { + if (!hasImages(shieldUrls)) { + return; + } + + updateShieldUrlIndices(bannerComponentNodes); createTargets(textView, shieldUrls); loadTargets(); } + private void updateShieldUrlIndices(List bannerComponentNodes) { + for (BannerShieldInfo bannerShieldInfo : shieldUrls) { + bannerShieldInfo.setStartIndex(bannerComponentNodes.get(bannerShieldInfo.getNodeIndex()).startIndex); + } + } + private static boolean hasComponents(BannerText bannerText) { return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); } + private static boolean hasImages(List shieldUrls) { + return !shieldUrls.isEmpty(); + } + /** * Takes a given {@link BannerText} and fetches a valid * imageBaseUrl if one is found. @@ -134,7 +164,7 @@ private void fetchImageBaseUrls(BannerText bannerText) { } } - private static boolean hasImageUrl(BannerComponents components) { + public boolean hasImageUrl(BannerComponents components) { return !TextUtils.isEmpty(components.imageBaseUrl()); } @@ -163,4 +193,11 @@ private void checkIsInitialized() { throw new RuntimeException("InstructionLoader must be initialized prior to loading image URLs"); } } + + static class ShieldBannerComponentNode extends BannerComponentNode { + + ShieldBannerComponentNode(BannerComponents bannerComponents, int startIndex) { + super(bannerComponents, startIndex); + } + } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 85a2a2c1bbf..4f470da66e1 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -12,9 +12,7 @@ import com.squareup.picasso.Picasso; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; /** * Utility class that can be used to load a given {@link BannerText} into the provided @@ -27,14 +25,12 @@ * a new {@link ImageSpan} is created and set to the appropriate position of the {@link Spannable}/ */ public class InstructionLoader { - private static InstructionLoader instance; private static InstructionImageLoader instructionImageLoader; - private List shieldUrls; - private List nodes; - private Map> abbreviations; - int length = 0; - + private AbbreviationCoordinator abbreviationCoordinator; + private List bannerComponentNodes; + private List bannerComponents; + private int length = 0; private boolean isInitialized; private InstructionLoader() { @@ -102,17 +98,16 @@ public void loadInstruction(TextView textView, BannerText bannerText) { return; } - parseBannerComponents(textView, bannerText.components()); + abbreviationCoordinator = new AbbreviationCoordinator(); + this.bannerComponents = bannerText.components(); + + parseBannerComponents(textView); setText(textView); loadImages(textView); } private void loadImages(TextView textView) { - List shieldUrls = getShieldUrls(); - - if (hasImages(shieldUrls)) { - instructionImageLoader.loadImages(textView, shieldUrls); - } + instructionImageLoader.loadImages(textView, bannerComponentNodes); } private void setText(TextView textView) { @@ -121,75 +116,60 @@ private void setText(TextView textView) { } private String getAbbreviatedBannerText(TextView textView) { - AbbreviationCoordinator abbreviationCoordinator = new AbbreviationCoordinator(textView, abbreviations); - return abbreviationCoordinator.abbreviateBannerText(nodes); + return abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView); } - private void parseBannerComponents(TextView textView, List bannerComponents) { - nodes = new ArrayList<>(); - shieldUrls = new ArrayList<>(); - abbreviations = new HashMap<>(); + private void parseBannerComponents(TextView textView) { + bannerComponentNodes = new ArrayList<>(); for (BannerComponents components : bannerComponents) { if (hasImageUrl(components)) { - addShieldInfo(textView, components); - nodes.add(new ShieldNode(components, length - 1)); + setupWithImages(components, textView); } else if (hasAbbreviation(components)) { - addPriorityInfo(components); - nodes.add(new AbbreviationNode(components, length - 1)); + setupWithAbbreviations(components); } else { - nodes.add(new Node(components, length - 1)); + bannerComponentNodes.add(new BannerComponentNode(components, length - 1)); } length += components.text().length() + 1; } } - private boolean hasAbbreviation(BannerComponents components) { - return !TextUtils.isEmpty(components.abbreviation()); + private void setupWithImages(BannerComponents components, TextView textView) { + instructionImageLoader.addShieldInfo(textView, components, bannerComponentNodes.size()); + bannerComponentNodes.add(new InstructionImageLoader.ShieldBannerComponentNode(components, length - 1)); } - private boolean hasImageUrl(BannerComponents components) { - return !TextUtils.isEmpty(components.imageBaseUrl()); + private void setupWithAbbreviations(BannerComponents components) { + abbreviationCoordinator.addPriorityInfo(components, bannerComponentNodes.size()); + bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationBannerComponentNode(components, length - 1)); } - private void addPriorityInfo(BannerComponents components) { - int abbreviationPriority = components.abbreviationPriority(); - if (abbreviations.get(Integer.valueOf(abbreviationPriority)) == null) { - abbreviations.put(abbreviationPriority, new ArrayList()); - } - abbreviations.get(abbreviationPriority).add(Integer.valueOf(nodes.size())); - } - - public List getShieldUrls() { - for (BannerShieldInfo bannerShieldInfo : shieldUrls) { - bannerShieldInfo.setStartIndex(nodes.get(bannerShieldInfo.getNodeIndex()).startIndex); - } - return shieldUrls; + private boolean hasAbbreviation(BannerComponents components) { + return !TextUtils.isEmpty(components.abbreviation()); } - private void addShieldInfo(TextView textView, BannerComponents components) { - shieldUrls.add(new BannerShieldInfo(textView.getContext(), components, nodes.size())); + private boolean hasImageUrl(BannerComponents components) { + return !TextUtils.isEmpty(components.imageBaseUrl()); } private static boolean hasComponents(BannerText bannerText) { return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); } - private static boolean hasImages(List shieldUrls) { - return !shieldUrls.isEmpty(); - } - private void checkIsInitialized() { if (!isInitialized) { throw new RuntimeException("InstructionLoader must be initialized prior to loading image URLs"); } } - static class Node { + /** + * Class used to construct a list of BannerComponents to be populated into a TextView + */ + static class BannerComponentNode { protected BannerComponents bannerComponents; protected int startIndex; - Node(BannerComponents bannerComponents, int startIndex) { + protected BannerComponentNode(BannerComponents bannerComponents, int startIndex) { this.bannerComponents = bannerComponents; this.startIndex = startIndex; } @@ -203,27 +183,4 @@ public void setStartIndex(int startIndex) { this.startIndex = startIndex; } } - - static class ShieldNode extends Node { - ShieldNode(BannerComponents bannerComponents, int startIndex) { - super(bannerComponents, startIndex); - } - } - - static class AbbreviationNode extends Node { - protected boolean abbreviate; - - AbbreviationNode(BannerComponents bannerComponents, int startIndex) { - super(bannerComponents, startIndex); - } - - @Override - public String toString() { - return abbreviate ? bannerComponents.abbreviation() : bannerComponents.text(); - } - - public void setAbbreviate(boolean abbreviate) { - this.abbreviate = abbreviate; - } - } } From 73cc170e6d1406224afd025782a58a313a2ed486 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Mon, 30 Apr 2018 16:11:09 -0400 Subject: [PATCH 16/36] Fixed bug where navigation froze when text never fit TextView --- .../ui/v5/instruction/AbbreviationCoordinator.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index 05943262bf3..2642c3dcf75 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -7,6 +7,7 @@ import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.BannerComponentNode; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -51,8 +52,14 @@ public void addPriorityInfo(BannerComponents bannerComponents, int index) { */ public String abbreviateBannerText(List bannerComponentNodes, TextView textView) { String bannerText = join(bannerComponentNodes); + + if (abbreviations.isEmpty()) { + return bannerText; + } + int currAbbreviationPriority = 0; - while (!textFits(textView, bannerText)) { + int maxAbbreviationPriority = Collections.max(abbreviations.keySet()); + while (!textFits(textView, bannerText) && (currAbbreviationPriority > maxAbbreviationPriority)) { List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); if (indices == null) { From dc32393598037991174619fb0a3f0690a31adcf6 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Mon, 30 Apr 2018 16:18:51 -0400 Subject: [PATCH 17/36] Cleared shieldUrls to prevent re-using images in subsequent instructions --- .../navigation/ui/v5/instruction/InstructionImageLoader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index a8f57c23f5b..7882693d1f8 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -179,6 +179,7 @@ public void onInstructionLoaded(InstructionTarget target) { } })); } + shieldUrls.clear(); } private void loadTargets() { From 62560b17ee01f8925ed97a7259ef86eab0217199 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Tue, 1 May 2018 09:24:27 -0400 Subject: [PATCH 18/36] Renamed variables and reduced passing of global variables --- ...annerShieldInfo.java => BannerShield.java} | 4 +-- .../instruction/InstructionImageLoader.java | 32 +++++++++---------- .../ui/v5/instruction/InstructionLoader.java | 3 +- .../ui/v5/instruction/InstructionTarget.java | 8 ++--- 4 files changed, 24 insertions(+), 23 deletions(-) rename libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/{BannerShieldInfo.java => BannerShield.java} (87%) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java similarity index 87% rename from libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java rename to libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java index 95294df0131..588080138dd 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShieldInfo.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java @@ -4,13 +4,13 @@ import com.mapbox.api.directions.v5.models.BannerComponents; -class BannerShieldInfo { +class BannerShield { private String url; private String text; private int nodeIndex; private int startIndex = -1; - BannerShieldInfo(Context context, BannerComponents bannerComponents, int nodeIndex) { + BannerShield(Context context, BannerComponents bannerComponents, int nodeIndex) { this.url = new UrlDensityMap(context).get(bannerComponents.imageBaseUrl()); this.nodeIndex = nodeIndex; this.text = bannerComponents.text(); diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index 7882693d1f8..a05003ce32c 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -34,7 +34,7 @@ public class InstructionImageLoader { private Picasso picassoImageLoader; private List targets; private UrlDensityMap urlDensityMap; - private List shieldUrls; + private List bannerShieldList; private InstructionImageLoader() { } @@ -68,22 +68,22 @@ public void initialize(Context context) { this.urlDensityMap = new UrlDensityMap(context); targets = new ArrayList<>(); - shieldUrls = new ArrayList<>(); + bannerShieldList = new ArrayList<>(); isInitialized = true; } } /** - * Uses the given BannerComponents object to construct a BannerShieldInfo object containing the + * Uses the given BannerComponents object to construct a BannerShield object containing the * information needed to load the proper image into the TextView where appropriate. * * @param textView to insert image into - * @param components containing image info + * @param bannerComponents containing image info * @param index of the BannerComponentNode which refers to the given BannerComponents */ - public void addShieldInfo(TextView textView, BannerComponents components, int index) { - shieldUrls.add(new BannerShieldInfo(textView.getContext(), components, index)); + public void addShieldInfo(TextView textView, BannerComponents bannerComponents, int index) { + bannerShieldList.add(new BannerShield(textView.getContext(), bannerComponents, index)); } /** @@ -127,18 +127,18 @@ public void shutdown() { * @since 0.9.0 */ public void loadImages(TextView textView, List bannerComponentNodes) { - if (!hasImages(shieldUrls)) { + if (!hasImages()) { return; } updateShieldUrlIndices(bannerComponentNodes); - createTargets(textView, shieldUrls); + createTargets(textView); loadTargets(); } private void updateShieldUrlIndices(List bannerComponentNodes) { - for (BannerShieldInfo bannerShieldInfo : shieldUrls) { - bannerShieldInfo.setStartIndex(bannerComponentNodes.get(bannerShieldInfo.getNodeIndex()).startIndex); + for (BannerShield bannerShield : bannerShieldList) { + bannerShield.setStartIndex(bannerComponentNodes.get(bannerShield.getNodeIndex()).startIndex); } } @@ -146,8 +146,8 @@ private static boolean hasComponents(BannerText bannerText) { return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); } - private static boolean hasImages(List shieldUrls) { - return !shieldUrls.isEmpty(); + private boolean hasImages() { + return !bannerShieldList.isEmpty(); } /** @@ -168,10 +168,10 @@ public boolean hasImageUrl(BannerComponents components) { return !TextUtils.isEmpty(components.imageBaseUrl()); } - private void createTargets(TextView textView, List shields) { + private void createTargets(TextView textView) { Spannable instructionSpannable = new SpannableString(textView.getText()); - for (final BannerShieldInfo shield : shields) { - targets.add(new InstructionTarget(textView, instructionSpannable, shields, shield, + for (final BannerShield bannerShield : bannerShieldList) { + targets.add(new InstructionTarget(textView, instructionSpannable, bannerShieldList, bannerShield, new InstructionTarget.InstructionLoadedCallback() { @Override public void onInstructionLoaded(InstructionTarget target) { @@ -179,7 +179,7 @@ public void onInstructionLoaded(InstructionTarget target) { } })); } - shieldUrls.clear(); + bannerShieldList.clear(); } private void loadTargets() { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 4f470da66e1..9d395e539fe 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -30,7 +30,7 @@ public class InstructionLoader { private AbbreviationCoordinator abbreviationCoordinator; private List bannerComponentNodes; private List bannerComponents; - private int length = 0; + private int length; private boolean isInitialized; private InstructionLoader() { @@ -120,6 +120,7 @@ private String getAbbreviatedBannerText(TextView textView) { } private void parseBannerComponents(TextView textView) { + length = 0; bannerComponentNodes = new ArrayList<>(); for (BannerComponents components : bannerComponents) { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java index f27d80bbd89..4cd032ade08 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java @@ -20,12 +20,12 @@ public class InstructionTarget implements Target { private TextView textView; private Spannable instructionSpannable; - private List shields; - private BannerShieldInfo shield; + private List shields; + private BannerShield shield; private InstructionLoadedCallback instructionLoadedCallback; InstructionTarget(TextView textView, Spannable instructionSpannable, - List shields, BannerShieldInfo shield, + List shields, BannerShield shield, InstructionLoadedCallback instructionLoadedCallback) { this.textView = textView; this.instructionSpannable = instructionSpannable; @@ -34,7 +34,7 @@ public class InstructionTarget implements Target { this.instructionLoadedCallback = instructionLoadedCallback; } - BannerShieldInfo getShield() { + BannerShield getShield() { return shield; } From 30a525d9fb32955133af0272246a63a5c05cce66 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Tue, 1 May 2018 10:34:57 -0400 Subject: [PATCH 19/36] Fixed typo in bug fix --- .../navigation/ui/v5/instruction/AbbreviationCoordinator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index 2642c3dcf75..adf39284eb5 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -59,7 +59,7 @@ public String abbreviateBannerText(List bannerComponentNode int currAbbreviationPriority = 0; int maxAbbreviationPriority = Collections.max(abbreviations.keySet()); - while (!textFits(textView, bannerText) && (currAbbreviationPriority > maxAbbreviationPriority)) { + while (!textFits(textView, bannerText) && (currAbbreviationPriority <= maxAbbreviationPriority)) { List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); if (indices == null) { From 321fecf00165dc16dd0bd6ebfd39eceda4d794de Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Tue, 1 May 2018 14:17:06 -0400 Subject: [PATCH 20/36] Limited secondary text to one line --- .../src/main/res/layout/instruction_content_layout.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libandroid-navigation-ui/src/main/res/layout/instruction_content_layout.xml b/libandroid-navigation-ui/src/main/res/layout/instruction_content_layout.xml index 376c5f3644e..db024ded31d 100644 --- a/libandroid-navigation-ui/src/main/res/layout/instruction_content_layout.xml +++ b/libandroid-navigation-ui/src/main/res/layout/instruction_content_layout.xml @@ -84,7 +84,7 @@ android:gravity="center_vertical" android:includeFontPadding="false" android:lineSpacingMultiplier="0.8" - android:maxLines="2" + android:maxLines="1" android:minHeight="31dp" android:textColor="?attr/navigationViewBannerSecondaryText" android:textSize="26sp" From c2564857045c3ead5e4e3a92529607394be1053f Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Mon, 7 May 2018 12:30:28 -0400 Subject: [PATCH 21/36] Added AbbreviationCoordinatorTest along with helper classes/methods --- .../instruction/AbbreviationCoordinator.java | 20 +++--- .../navigation/ui/v5/utils/TextViewUtils.java | 13 ++++ .../AbbreviationCoordinatorTest.java | 64 +++++++++++++++++++ .../v5/instruction/BannerComponentsFaker.java | 11 ++++ 4 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/utils/TextViewUtils.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerComponentsFaker.java diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index adf39284eb5..bc17db4542a 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -1,10 +1,10 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; -import android.graphics.Paint; import android.widget.TextView; import com.mapbox.api.directions.v5.models.BannerComponents; import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.BannerComponentNode; +import com.mapbox.services.android.navigation.ui.v5.utils.TextViewUtils; import java.util.ArrayList; import java.util.Collections; @@ -21,9 +21,17 @@ public class AbbreviationCoordinator { private static final String SINGLE_SPACE = " "; private Map> abbreviations; + private TextViewUtils textViewUtils; + + public AbbreviationCoordinator(TextViewUtils textViewUtils) { + this.abbreviations = new HashMap<>(); + this.textViewUtils = textViewUtils; + } + public AbbreviationCoordinator() { - abbreviations = new HashMap<>(); + this.abbreviations = new HashMap<>(); + this.textViewUtils = new TextViewUtils(); } /** @@ -59,7 +67,7 @@ public String abbreviateBannerText(List bannerComponentNode int currAbbreviationPriority = 0; int maxAbbreviationPriority = Collections.max(abbreviations.keySet()); - while (!textFits(textView, bannerText) && (currAbbreviationPriority <= maxAbbreviationPriority)) { + while (!textViewUtils.textFits(textView, bannerText) && (currAbbreviationPriority <= maxAbbreviationPriority)) { List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); if (indices == null) { @@ -101,12 +109,6 @@ private String join(List tokens) { return stringBuilder.toString(); } - private boolean textFits(TextView textView, String text) { - Paint paint = new Paint(textView.getPaint()); - float width = paint.measureText(text); - return width < textView.getWidth(); - } - /** * Class used by InstructionLoader to determine that a BannerComponent contains an abbreviation */ diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/utils/TextViewUtils.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/utils/TextViewUtils.java new file mode 100644 index 00000000000..14eec43e972 --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/utils/TextViewUtils.java @@ -0,0 +1,13 @@ +package com.mapbox.services.android.navigation.ui.v5.utils; + +import android.graphics.Paint; +import android.widget.TextView; + +public class TextViewUtils { + + public boolean textFits(TextView textView, String text) { + Paint paint = new Paint(textView.getPaint()); + float width = paint.measureText(text); + return width < textView.getWidth(); + } +} diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java new file mode 100644 index 00000000000..a3e5d988458 --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java @@ -0,0 +1,64 @@ +package com.mapbox.services.android.navigation.ui.v5.instruction; + +import android.widget.TextView; + +import com.mapbox.api.directions.v5.models.BannerComponents; +import com.mapbox.services.android.navigation.ui.v5.BaseTest; +import com.mapbox.services.android.navigation.ui.v5.utils.TextViewUtils; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AbbreviationCoordinatorTest extends BaseTest { + @Test + public void textIsAbbreviatedWhenItDoesntFit() { + String abbreviation = "smtxt"; + BannerComponents bannerComponents = + BannerComponentsFaker.bannerComponents() + .abbreviation(abbreviation) + .abbreviationPriority(0) + .build(); + TextViewUtils textViewUtils = mock(TextViewUtils.class); + TextView textView = mock(TextView.class); + when(textViewUtils.textFits(textView, abbreviation)).thenReturn(true); + when(textViewUtils.textFits(textView, bannerComponents.text())).thenReturn(false); + + AbbreviationCoordinator abbreviationCoordinator = new AbbreviationCoordinator(textViewUtils); + abbreviationCoordinator.addPriorityInfo(bannerComponents, 0); + + List bannerComponentNodes = new ArrayList<>(); + bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationBannerComponentNode(bannerComponents, 0)); + + assertEquals(abbreviation, abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView)); + } + + @Test + public void textIsNotAbbreviatedWhenItDoesFit() { + String abbreviation = "smtxt"; + String text = "some text"; + + BannerComponents bannerComponents = + BannerComponentsFaker.bannerComponents() + .abbreviation(abbreviation) + .abbreviationPriority(0) + .text(text) + .build(); + TextViewUtils textViewUtils = mock(TextViewUtils.class); + TextView textView = mock(TextView.class); + when(textViewUtils.textFits(textView, bannerComponents.text())).thenReturn(true); + + AbbreviationCoordinator abbreviationCoordinator = new AbbreviationCoordinator(textViewUtils); + abbreviationCoordinator.addPriorityInfo(bannerComponents, 0); + + List bannerComponentNodes = new ArrayList<>(); + bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationBannerComponentNode(bannerComponents, 0)); + + assertEquals(text, abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView)); + } +} diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerComponentsFaker.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerComponentsFaker.java new file mode 100644 index 00000000000..aa1b95fcd4b --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerComponentsFaker.java @@ -0,0 +1,11 @@ +package com.mapbox.services.android.navigation.ui.v5.instruction; + +import com.mapbox.api.directions.v5.models.BannerComponents; + +public class BannerComponentsFaker { + public static BannerComponents.Builder bannerComponents() { + return BannerComponents.builder() + .type("some type") + .text("some text"); + } +} From 9ea777f123602439aa60f31fc3717e30676293f7 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Tue, 8 May 2018 15:25:19 -0400 Subject: [PATCH 22/36] Added test files --- .../ui/v5/instruction/InstructionImageLoader.java | 1 - .../ui/v5/instruction/InstructionImageLoaderTest.java | 7 +++++++ .../ui/v5/instruction/InstructionLoaderTest.java | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoaderTest.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index a05003ce32c..56f7949c849 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -95,7 +95,6 @@ public void addShieldInfo(TextView textView, BannerComponents bannerComponents, * @param step providing the image Urls */ public void prefetchImageCache(LegStep step) { - if (step == null || step.bannerInstructions() == null || step.bannerInstructions().isEmpty()) { return; diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoaderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoaderTest.java new file mode 100644 index 00000000000..bac61ca5c12 --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoaderTest.java @@ -0,0 +1,7 @@ +package com.mapbox.services.android.navigation.ui.v5.instruction; + +import static org.junit.Assert.*; + +public class InstructionImageLoaderTest { + +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java new file mode 100644 index 00000000000..4c39b9d5b3e --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java @@ -0,0 +1,7 @@ +package com.mapbox.services.android.navigation.ui.v5.instruction; + +import static org.junit.Assert.*; + +public class InstructionLoaderTest { + +} \ No newline at end of file From 7ef6e6981acb08fe15acc59b817f2c2cbb8902de Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Tue, 8 May 2018 16:37:01 -0400 Subject: [PATCH 23/36] Refactoring to reduce use of global variables and increase modularity for testability --- .../instruction/AbbreviationCoordinator.java | 4 +- .../ui/v5/instruction/InstructionLoader.java | 71 ++++++++++--------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index bc17db4542a..c09596ee603 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -30,8 +30,7 @@ public AbbreviationCoordinator(TextViewUtils textViewUtils) { public AbbreviationCoordinator() { - this.abbreviations = new HashMap<>(); - this.textViewUtils = new TextViewUtils(); + this(new TextViewUtils()); } /** @@ -81,6 +80,7 @@ public String abbreviateBannerText(List bannerComponentNode bannerText = join(bannerComponentNodes); } + abbreviations.clear(); return bannerText; } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 9d395e539fe..e5f27a5d473 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -28,9 +28,6 @@ public class InstructionLoader { private static InstructionLoader instance; private static InstructionImageLoader instructionImageLoader; private AbbreviationCoordinator abbreviationCoordinator; - private List bannerComponentNodes; - private List bannerComponents; - private int length; private boolean isInitialized; private InstructionLoader() { @@ -58,9 +55,14 @@ public static synchronized InstructionLoader getInstance() { * @param context to init Picasso */ public void initialize(Context context) { + initialize(context, new AbbreviationCoordinator()); + } + + public void initialize(Context context, AbbreviationCoordinator abbreviationCoordinator) { if (!isInitialized) { instructionImageLoader = InstructionImageLoader.getInstance(); instructionImageLoader.initialize(context); + this.abbreviationCoordinator = abbreviationCoordinator; isInitialized = true; } @@ -98,51 +100,56 @@ public void loadInstruction(TextView textView, BannerText bannerText) { return; } - abbreviationCoordinator = new AbbreviationCoordinator(); - this.bannerComponents = bannerText.components(); - - parseBannerComponents(textView); - setText(textView); - loadImages(textView); - } - - private void loadImages(TextView textView) { - instructionImageLoader.loadImages(textView, bannerComponentNodes); + loadAbbreviationsAndImages(textView, bannerText.components()); } - private void setText(TextView textView) { - String text = getAbbreviatedBannerText(textView); - textView.setText(text); - } - - private String getAbbreviatedBannerText(TextView textView) { - return abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView); + private void loadAbbreviationsAndImages(TextView textView, List bannerComponents) { + List bannerComponentNodes = parseBannerComponents(textView, bannerComponents); + setText(textView, bannerComponentNodes); + loadImages(textView, bannerComponentNodes); } - private void parseBannerComponents(TextView textView) { - length = 0; - bannerComponentNodes = new ArrayList<>(); + private List parseBannerComponents(TextView textView, List bannerComponents) { + int length = 0; + List bannerComponentNodes = new ArrayList<>(); for (BannerComponents components : bannerComponents) { + BannerComponentNode node; if (hasImageUrl(components)) { - setupWithImages(components, textView); + node = setupImageNode(components, textView, bannerComponentNodes.size(), length - 1); } else if (hasAbbreviation(components)) { - setupWithAbbreviations(components); + node = setupAbbreviationNode(components, bannerComponentNodes.size(), length - 1); } else { - bannerComponentNodes.add(new BannerComponentNode(components, length - 1)); + node = new BannerComponentNode(components, length - 1); } + bannerComponentNodes.add(node); length += components.text().length() + 1; } + + return bannerComponentNodes; + } + + private InstructionImageLoader.ShieldBannerComponentNode setupImageNode(BannerComponents components, TextView textView, int index, int startIndex) { + instructionImageLoader.addShieldInfo(textView, components, index); + return new InstructionImageLoader.ShieldBannerComponentNode(components, startIndex); + } + + private AbbreviationCoordinator.AbbreviationBannerComponentNode setupAbbreviationNode(BannerComponents components, int index, int startIndex) { + abbreviationCoordinator.addPriorityInfo(components, index); + return new AbbreviationCoordinator.AbbreviationBannerComponentNode(components, startIndex); } - private void setupWithImages(BannerComponents components, TextView textView) { - instructionImageLoader.addShieldInfo(textView, components, bannerComponentNodes.size()); - bannerComponentNodes.add(new InstructionImageLoader.ShieldBannerComponentNode(components, length - 1)); + private void loadImages(TextView textView, List bannerComponentNodes) { + instructionImageLoader.loadImages(textView, bannerComponentNodes); } - private void setupWithAbbreviations(BannerComponents components) { - abbreviationCoordinator.addPriorityInfo(components, bannerComponentNodes.size()); - bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationBannerComponentNode(components, length - 1)); + private void setText(TextView textView, List bannerComponentNodes) { + String text = getAbbreviatedBannerText(textView, bannerComponentNodes); + textView.setText(text); + } + + private String getAbbreviatedBannerText(TextView textView, List bannerComponentNodes) { + return abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView); } private boolean hasAbbreviation(BannerComponents components) { From cccccf52b2889b7661cb65cb0b6ff92d4ede8d0c Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Tue, 8 May 2018 17:12:38 -0400 Subject: [PATCH 24/36] Changed InstructionLoader to not be a singleton --- .../navigation/ui/v5/NavigationView.java | 6 +- .../instruction/AbbreviationCoordinator.java | 6 +- .../instruction/InstructionImageLoader.java | 4 +- .../ui/v5/instruction/InstructionLoader.java | 98 ++++--------------- .../ui/v5/instruction/InstructionView.java | 6 +- .../AbbreviationCoordinatorTest.java | 4 +- 6 files changed, 31 insertions(+), 93 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationView.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationView.java index 23c265f5ea0..2fca141028b 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationView.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationView.java @@ -32,7 +32,7 @@ import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin; import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.services.android.navigation.ui.v5.camera.NavigationCamera; -import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader; +import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionImageLoader; import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionView; import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute; import com.mapbox.services.android.navigation.ui.v5.summary.SummaryBottomSheet; @@ -179,7 +179,7 @@ public void onRestoreInstanceState(Bundle savedInstanceState) { public void onDestroy() { mapView.onDestroy(); navigationViewModel.onDestroy(isChangingConfigurations()); - InstructionLoader.getInstance().shutdown(); + InstructionImageLoader.getInstance().shutdown(); if (camera != null) { camera.onDestroy(); } @@ -407,7 +407,7 @@ public MapboxMap getMapboxMap() { } private void init() { - InstructionLoader.getInstance().initialize(getContext()); + InstructionImageLoader.getInstance().initialize(getContext()); inflate(getContext(), R.layout.navigation_view_layout, this); bind(); initViewModels(); diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index c09596ee603..f8ad9579553 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -85,7 +85,7 @@ public String abbreviateBannerText(List bannerComponentNode } private void abbreviate(BannerComponentNode bannerComponentNode) { - ((AbbreviationBannerComponentNode) bannerComponentNode).setAbbreviate(true); + ((AbbreviationNode) bannerComponentNode).setAbbreviate(true); } private String join(List tokens) { @@ -112,10 +112,10 @@ private String join(List tokens) { /** * Class used by InstructionLoader to determine that a BannerComponent contains an abbreviation */ - static class AbbreviationBannerComponentNode extends BannerComponentNode { + static class AbbreviationNode extends BannerComponentNode { protected boolean abbreviate; - AbbreviationBannerComponentNode(BannerComponents bannerComponents, int startIndex) { + AbbreviationNode(BannerComponents bannerComponents, int startIndex) { super(bannerComponents, startIndex); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index 56f7949c849..c6686a149db 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -194,9 +194,9 @@ private void checkIsInitialized() { } } - static class ShieldBannerComponentNode extends BannerComponentNode { + static class ShieldNode extends BannerComponentNode { - ShieldBannerComponentNode(BannerComponents bannerComponents, int startIndex) { + ShieldNode(BannerComponents bannerComponents, int startIndex) { super(bannerComponents, startIndex); } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index e5f27a5d473..758b87bc13f 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -1,6 +1,5 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; -import android.content.Context; import android.text.Spannable; import android.text.TextUtils; import android.text.style.ImageSpan; @@ -8,7 +7,8 @@ import com.mapbox.api.directions.v5.models.BannerComponents; import com.mapbox.api.directions.v5.models.BannerText; -import com.mapbox.api.directions.v5.models.LegStep; +import com.mapbox.services.android.navigation.ui.v5.instruction.AbbreviationCoordinator.AbbreviationNode; +import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionImageLoader.ShieldNode; import com.squareup.picasso.Picasso; import java.util.ArrayList; @@ -25,91 +25,35 @@ * a new {@link ImageSpan} is created and set to the appropriate position of the {@link Spannable}/ */ public class InstructionLoader { - private static InstructionLoader instance; private static InstructionImageLoader instructionImageLoader; private AbbreviationCoordinator abbreviationCoordinator; - private boolean isInitialized; + private TextView textView; + private List bannerComponentNodes; - private InstructionLoader() { - } + public InstructionLoader(TextView textView, BannerText bannerText) { + this.abbreviationCoordinator = new AbbreviationCoordinator(); + this.textView = textView; + bannerComponentNodes = new ArrayList<>(); + instructionImageLoader = InstructionImageLoader.getInstance(); - /** - * Primary access method (using singleton pattern) - * - * @return InstructionLoader - */ - public static synchronized InstructionLoader getInstance() { - if (instance == null) { - instance = new InstructionLoader(); + if (!hasComponents(bannerText)) { + return; } - return instance; - } - - /** - * Must be called before loading images. - *

- * Initializes a new {@link Picasso} instance as well as the - * {@link ArrayList} of {@link InstructionTarget}. - * - * @param context to init Picasso - */ - public void initialize(Context context) { - initialize(context, new AbbreviationCoordinator()); - } - - public void initialize(Context context, AbbreviationCoordinator abbreviationCoordinator) { - if (!isInitialized) { - instructionImageLoader = InstructionImageLoader.getInstance(); - instructionImageLoader.initialize(context); - this.abbreviationCoordinator = abbreviationCoordinator; - - isInitialized = true; - } - } - - /** - * Will pre-fetch images for a given {@link LegStep}. - *

- * If loaded successfully, this will allow the images to be displayed - * without delay in the {@link InstructionView}. - * - * @param step providing the image Urls - */ - public void prefetchImageCache(LegStep step) { - instructionImageLoader.prefetchImageCache(step); - } - - public void shutdown() { - instructionImageLoader.shutdown(); + bannerComponentNodes = parseBannerComponents(bannerText.components()); } /** * Takes the given components from the {@link BannerText} and creates * a new {@link Spannable} with text / {@link ImageSpan}s which is loaded * into the given {@link TextView}. - * - * @param textView target for the banner text - * @param bannerText with components to be extracted - * @since 0.9.0 */ - public void loadInstruction(TextView textView, BannerText bannerText) { - checkIsInitialized(); - - if (!hasComponents(bannerText)) { - return; - } - - loadAbbreviationsAndImages(textView, bannerText.components()); - } - - private void loadAbbreviationsAndImages(TextView textView, List bannerComponents) { - List bannerComponentNodes = parseBannerComponents(textView, bannerComponents); + public void loadInstruction() { setText(textView, bannerComponentNodes); loadImages(textView, bannerComponentNodes); } - private List parseBannerComponents(TextView textView, List bannerComponents) { + private List parseBannerComponents(List bannerComponents) { int length = 0; List bannerComponentNodes = new ArrayList<>(); @@ -129,14 +73,14 @@ private List parseBannerComponents(TextView textView, List< return bannerComponentNodes; } - private InstructionImageLoader.ShieldBannerComponentNode setupImageNode(BannerComponents components, TextView textView, int index, int startIndex) { + private ShieldNode setupImageNode(BannerComponents components, TextView textView, int index, int startIndex) { instructionImageLoader.addShieldInfo(textView, components, index); - return new InstructionImageLoader.ShieldBannerComponentNode(components, startIndex); + return new InstructionImageLoader.ShieldNode(components, startIndex); } - private AbbreviationCoordinator.AbbreviationBannerComponentNode setupAbbreviationNode(BannerComponents components, int index, int startIndex) { + private AbbreviationNode setupAbbreviationNode(BannerComponents components, int index, int startIndex) { abbreviationCoordinator.addPriorityInfo(components, index); - return new AbbreviationCoordinator.AbbreviationBannerComponentNode(components, startIndex); + return new AbbreviationCoordinator.AbbreviationNode(components, startIndex); } private void loadImages(TextView textView, List bannerComponentNodes) { @@ -164,12 +108,6 @@ private static boolean hasComponents(BannerText bannerText) { return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); } - private void checkIsInitialized() { - if (!isInitialized) { - throw new RuntimeException("InstructionLoader must be initialized prior to loading image URLs"); - } - } - /** * Class used to construct a list of BannerComponents to be populated into a TextView */ diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java index ffaa1b9a43c..3c69fa351c5 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java @@ -234,7 +234,7 @@ private void updateViews(InstructionModel model) { if (newStep(model.getProgress())) { // Pre-fetch the image URLs for the upcoming step LegStep upComingStep = model.getProgress().currentLegProgress().upComingStep(); - InstructionLoader.getInstance().prefetchImageCache(upComingStep); + InstructionImageLoader.getInstance().prefetchImageCache(upComingStep); } } @@ -683,7 +683,7 @@ private void distanceText(InstructionModel model) { */ private void updateTextInstruction(InstructionModel model) { if (model.getPrimaryBannerText() != null) { - InstructionLoader.getInstance().loadInstruction(upcomingPrimaryText, model.getPrimaryBannerText()); + new InstructionLoader(upcomingPrimaryText, model.getPrimaryBannerText()).loadInstruction(); } if (model.getSecondaryBannerText() != null) { if (upcomingSecondaryText.getVisibility() == GONE) { @@ -691,7 +691,7 @@ private void updateTextInstruction(InstructionModel model) { upcomingPrimaryText.setMaxLines(1); adjustBannerTextVerticalBias(0.65f); } - InstructionLoader.getInstance().loadInstruction(upcomingSecondaryText, model.getSecondaryBannerText()); + new InstructionLoader(upcomingSecondaryText, model.getSecondaryBannerText()).loadInstruction(); } else { upcomingPrimaryText.setMaxLines(2); upcomingSecondaryText.setVisibility(GONE); diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java index a3e5d988458..70c50b1c0d6 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java @@ -33,7 +33,7 @@ public void textIsAbbreviatedWhenItDoesntFit() { abbreviationCoordinator.addPriorityInfo(bannerComponents, 0); List bannerComponentNodes = new ArrayList<>(); - bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationBannerComponentNode(bannerComponents, 0)); + bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationNode(bannerComponents, 0)); assertEquals(abbreviation, abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView)); } @@ -57,7 +57,7 @@ public void textIsNotAbbreviatedWhenItDoesFit() { abbreviationCoordinator.addPriorityInfo(bannerComponents, 0); List bannerComponentNodes = new ArrayList<>(); - bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationBannerComponentNode(bannerComponents, 0)); + bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationNode(bannerComponents, 0)); assertEquals(text, abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView)); } From 2732823ad4c681e2a92b665a1722dc3c42c39ee4 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 9 May 2018 10:09:06 -0400 Subject: [PATCH 25/36] Added tests for InstructionLoader --- .../ui/v5/instruction/InstructionLoader.java | 12 ++- .../v5/instruction/InstructionLoaderTest.java | 94 ++++++++++++++++++- 2 files changed, 101 insertions(+), 5 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index 758b87bc13f..c2307f57ceb 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -1,12 +1,12 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; import android.text.Spannable; -import android.text.TextUtils; import android.text.style.ImageSpan; import android.widget.TextView; import com.mapbox.api.directions.v5.models.BannerComponents; import com.mapbox.api.directions.v5.models.BannerText; +import com.mapbox.core.utils.TextUtils; import com.mapbox.services.android.navigation.ui.v5.instruction.AbbreviationCoordinator.AbbreviationNode; import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionImageLoader.ShieldNode; import com.squareup.picasso.Picasso; @@ -31,10 +31,14 @@ public class InstructionLoader { private List bannerComponentNodes; public InstructionLoader(TextView textView, BannerText bannerText) { - this.abbreviationCoordinator = new AbbreviationCoordinator(); + this(textView, bannerText, InstructionImageLoader.getInstance(), new AbbreviationCoordinator()); + } + + public InstructionLoader(TextView textView, BannerText bannerText, InstructionImageLoader instructionImageLoader, AbbreviationCoordinator abbreviationCoordinator) { + this.abbreviationCoordinator = abbreviationCoordinator; this.textView = textView; bannerComponentNodes = new ArrayList<>(); - instructionImageLoader = InstructionImageLoader.getInstance(); + this.instructionImageLoader = instructionImageLoader; if (!hasComponents(bannerText)) { return; @@ -55,7 +59,7 @@ public void loadInstruction() { private List parseBannerComponents(List bannerComponents) { int length = 0; - List bannerComponentNodes = new ArrayList<>(); + bannerComponentNodes = new ArrayList<>(); for (BannerComponents components : bannerComponents) { BannerComponentNode node; diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java index 4c39b9d5b3e..9ac0f455202 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java @@ -1,7 +1,99 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; -import static org.junit.Assert.*; +import android.widget.TextView; + +import com.mapbox.api.directions.v5.models.BannerComponents; +import com.mapbox.api.directions.v5.models.BannerText; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class InstructionLoaderTest { + @Test + public void testPriorityInfoIsAdded() { + TextView textView = mock(TextView.class); + BannerText bannerText = mock(BannerText.class); + InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); + AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); + BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() + .abbreviationPriority(1) + .abbreviation("abbreviation text") + .build(); + List bannerComponentsList = new ArrayList<>(); + bannerComponentsList.add(bannerComponents); + when(bannerText.components()).thenReturn(bannerComponentsList); + + new InstructionLoader(textView, bannerText, instructionImageLoader, abbreviationCoordinator); + + verify(abbreviationCoordinator).addPriorityInfo(bannerComponents, 0); + } + + @Test + public void testShieldInfoIsAdded() { + TextView textView = mock(TextView.class); + BannerText bannerText = mock(BannerText.class); + InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); + AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); + BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() + .imageBaseUrl("string url") + .build(); + List bannerComponentsList = new ArrayList<>(); + bannerComponentsList.add(bannerComponents); + when(bannerText.components()).thenReturn(bannerComponentsList); + + new InstructionLoader(textView, bannerText, instructionImageLoader, abbreviationCoordinator); + + verify(instructionImageLoader).addShieldInfo(textView, bannerComponents, 0); + } + + @Test + public void testSetAbbreviatedText() { + TextView textView = mock(TextView.class); + BannerText bannerText = mock(BannerText.class); + InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); + AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); + BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() + .abbreviationPriority(1) + .abbreviation("abbrv text") + .build(); + List bannerComponentsList = new ArrayList<>(); + bannerComponentsList.add(bannerComponents); + when(bannerText.components()).thenReturn(bannerComponentsList); + String abbreviatedText = "abbreviated text"; + when(abbreviationCoordinator.abbreviateBannerText(any(List.class), any(TextView.class))).thenReturn(abbreviatedText); + InstructionLoader instructionLoader = new InstructionLoader(textView, bannerText, instructionImageLoader, abbreviationCoordinator); + + instructionLoader.loadInstruction(); + + verify(textView).setText(abbreviatedText); + } + + @Test + public void testLoadImages() { + TextView textView = mock(TextView.class); + BannerText bannerText = mock(BannerText.class); + InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); + AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); + BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() + .imageBaseUrl("string url") + .build(); + List bannerComponentsList = new ArrayList<>(); + bannerComponentsList.add(bannerComponents); + when(bannerText.components()).thenReturn(bannerComponentsList); + String abbreviatedText = "abbreviated text"; + when(abbreviationCoordinator.abbreviateBannerText(any(List.class), any(TextView.class))).thenReturn(abbreviatedText); + InstructionLoader instructionLoader = new InstructionLoader(textView, bannerText, instructionImageLoader, abbreviationCoordinator); + + instructionLoader.loadInstruction(); + + verify(instructionImageLoader).loadImages(any(TextView.class), any(List.class)); + } } \ No newline at end of file From ef3220b355f9a3c826f3ca3190a2b62dc2859c3c Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 9 May 2018 10:19:01 -0400 Subject: [PATCH 26/36] Refactored so to not add unnecessary parameter --- .../android/navigation/ui/v5/instruction/BannerShield.java | 4 ++-- .../ui/v5/instruction/InstructionImageLoader.java | 7 +++---- .../navigation/ui/v5/instruction/InstructionLoader.java | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java index 588080138dd..9a139869231 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java @@ -10,8 +10,8 @@ class BannerShield { private int nodeIndex; private int startIndex = -1; - BannerShield(Context context, BannerComponents bannerComponents, int nodeIndex) { - this.url = new UrlDensityMap(context).get(bannerComponents.imageBaseUrl()); + BannerShield(BannerComponents bannerComponents, int nodeIndex) { + this.url = bannerComponents.imageBaseUrl(); this.nodeIndex = nodeIndex; this.text = bannerComponents.text(); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index c6686a149db..50fa2c8a870 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -78,12 +78,11 @@ public void initialize(Context context) { * Uses the given BannerComponents object to construct a BannerShield object containing the * information needed to load the proper image into the TextView where appropriate. * - * @param textView to insert image into * @param bannerComponents containing image info * @param index of the BannerComponentNode which refers to the given BannerComponents */ - public void addShieldInfo(TextView textView, BannerComponents bannerComponents, int index) { - bannerShieldList.add(new BannerShield(textView.getContext(), bannerComponents, index)); + public void addShieldInfo(BannerComponents bannerComponents, int index) { + bannerShieldList.add(new BannerShield(bannerComponents, index)); } /** @@ -183,7 +182,7 @@ public void onInstructionLoaded(InstructionTarget target) { private void loadTargets() { for (InstructionTarget target : new ArrayList<>(targets)) { - picassoImageLoader.load(target.getShield().getUrl()) + picassoImageLoader.load(urlDensityMap.get(target.getShield().getUrl())) .into(target); } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index c2307f57ceb..abc57d66bf8 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -64,7 +64,7 @@ private List parseBannerComponents(List b for (BannerComponents components : bannerComponents) { BannerComponentNode node; if (hasImageUrl(components)) { - node = setupImageNode(components, textView, bannerComponentNodes.size(), length - 1); + node = setupImageNode(components, bannerComponentNodes.size(), length - 1); } else if (hasAbbreviation(components)) { node = setupAbbreviationNode(components, bannerComponentNodes.size(), length - 1); } else { @@ -77,8 +77,8 @@ private List parseBannerComponents(List b return bannerComponentNodes; } - private ShieldNode setupImageNode(BannerComponents components, TextView textView, int index, int startIndex) { - instructionImageLoader.addShieldInfo(textView, components, index); + private ShieldNode setupImageNode(BannerComponents components, int index, int startIndex) { + instructionImageLoader.addShieldInfo(components, index); return new InstructionImageLoader.ShieldNode(components, startIndex); } From a14bf82b9171455ce744378d5199d106dbdb14df Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 9 May 2018 10:30:14 -0400 Subject: [PATCH 27/36] Cleanup --- .../android/navigation/ui/v5/instruction/BannerShield.java | 2 -- .../navigation/ui/v5/instruction/InstructionLoader.java | 3 ++- .../ui/v5/instruction/InstructionImageLoaderTest.java | 7 ------- .../ui/v5/instruction/InstructionLoaderTest.java | 2 +- 4 files changed, 3 insertions(+), 11 deletions(-) delete mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoaderTest.java diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java index 9a139869231..d3f80daacef 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerShield.java @@ -1,7 +1,5 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; -import android.content.Context; - import com.mapbox.api.directions.v5.models.BannerComponents; class BannerShield { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index abc57d66bf8..de6fa020c9f 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -34,7 +34,8 @@ public InstructionLoader(TextView textView, BannerText bannerText) { this(textView, bannerText, InstructionImageLoader.getInstance(), new AbbreviationCoordinator()); } - public InstructionLoader(TextView textView, BannerText bannerText, InstructionImageLoader instructionImageLoader, AbbreviationCoordinator abbreviationCoordinator) { + public InstructionLoader(TextView textView, BannerText bannerText, InstructionImageLoader instructionImageLoader, + AbbreviationCoordinator abbreviationCoordinator) { this.abbreviationCoordinator = abbreviationCoordinator; this.textView = textView; bannerComponentNodes = new ArrayList<>(); diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoaderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoaderTest.java deleted file mode 100644 index bac61ca5c12..00000000000 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoaderTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.mapbox.services.android.navigation.ui.v5.instruction; - -import static org.junit.Assert.*; - -public class InstructionImageLoaderTest { - -} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java index 9ac0f455202..399c71a0f4d 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java @@ -51,7 +51,7 @@ public void testShieldInfoIsAdded() { new InstructionLoader(textView, bannerText, instructionImageLoader, abbreviationCoordinator); - verify(instructionImageLoader).addShieldInfo(textView, bannerComponents, 0); + verify(instructionImageLoader).addShieldInfo(bannerComponents, 0); } @Test From 50e8adf8026852a49808c778f1deb86d3395b670 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 16 May 2018 09:53:18 -0400 Subject: [PATCH 28/36] Extracted booleans into variables --- .../ui/v5/instruction/AbbreviationCoordinator.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index f8ad9579553..3303996b6e8 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -3,6 +3,7 @@ import android.widget.TextView; import com.mapbox.api.directions.v5.models.BannerComponents; +import com.mapbox.api.directions.v5.models.BannerText; import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.BannerComponentNode; import com.mapbox.services.android.navigation.ui.v5.utils.TextViewUtils; @@ -28,7 +29,6 @@ public AbbreviationCoordinator(TextViewUtils textViewUtils) { this.textViewUtils = textViewUtils; } - public AbbreviationCoordinator() { this(new TextViewUtils()); } @@ -66,7 +66,11 @@ public String abbreviateBannerText(List bannerComponentNode int currAbbreviationPriority = 0; int maxAbbreviationPriority = Collections.max(abbreviations.keySet()); - while (!textViewUtils.textFits(textView, bannerText) && (currAbbreviationPriority <= maxAbbreviationPriority)) { + + boolean needsMoreAbbreviations = !textViewUtils.textFits(textView, bannerText); + boolean abbreviationsLeft = currAbbreviationPriority <= maxAbbreviationPriority; + + while (needsMoreAbbreviations && abbreviationsLeft) { List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); if (indices == null) { @@ -78,6 +82,8 @@ public String abbreviateBannerText(List bannerComponentNode } bannerText = join(bannerComponentNodes); + needsMoreAbbreviations = !textViewUtils.textFits(textView, bannerText); + abbreviationsLeft = currAbbreviationPriority <= maxAbbreviationPriority; } abbreviations.clear(); From bf3453749da8bbe2e2b9d336a2b802b5d52e2b20 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 16 May 2018 16:15:32 -0400 Subject: [PATCH 29/36] Refactored for clarity --- .../instruction/AbbreviationCoordinator.java | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index 3303996b6e8..02c540a589b 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -3,7 +3,6 @@ import android.widget.TextView; import com.mapbox.api.directions.v5.models.BannerComponents; -import com.mapbox.api.directions.v5.models.BannerText; import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.BannerComponentNode; import com.mapbox.services.android.navigation.ui.v5.utils.TextViewUtils; @@ -67,29 +66,36 @@ public String abbreviateBannerText(List bannerComponentNode int currAbbreviationPriority = 0; int maxAbbreviationPriority = Collections.max(abbreviations.keySet()); - boolean needsMoreAbbreviations = !textViewUtils.textFits(textView, bannerText); - boolean abbreviationsLeft = currAbbreviationPriority <= maxAbbreviationPriority; - - while (needsMoreAbbreviations && abbreviationsLeft) { + while (shouldKeepAbbreviating(textView, bannerText, currAbbreviationPriority, maxAbbreviationPriority)) { List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); - if (indices == null) { - continue; - } + boolean abbreviationPriorityExists = abbreviateAtAbbreviationPriority(bannerComponentNodes, indices); - for (Integer index : indices) { - abbreviate(bannerComponentNodes.get(index)); + if (abbreviationPriorityExists) { + bannerText = join(bannerComponentNodes); } - - bannerText = join(bannerComponentNodes); - needsMoreAbbreviations = !textViewUtils.textFits(textView, bannerText); - abbreviationsLeft = currAbbreviationPriority <= maxAbbreviationPriority; } abbreviations.clear(); return bannerText; } + private boolean shouldKeepAbbreviating(TextView textView, String bannerText, int currAbbreviationPriority, int maxAbbreviationPriority) { + return !textViewUtils.textFits(textView, bannerText) && currAbbreviationPriority <= maxAbbreviationPriority; + } + + private boolean abbreviateAtAbbreviationPriority(List bannerComponentNodes, List indices) { + if (indices == null) { + return false; + } + + for (Integer index : indices) { + abbreviate(bannerComponentNodes.get(index)); + } + + return true; + } + private void abbreviate(BannerComponentNode bannerComponentNode) { ((AbbreviationNode) bannerComponentNode).setAbbreviate(true); } From 8858ac2be586e8a888a5c134960904085ba5ab25 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Wed, 16 May 2018 16:17:40 -0400 Subject: [PATCH 30/36] Fixed checkstyle issues --- .../ui/v5/instruction/AbbreviationCoordinator.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index 02c540a589b..d67fb999eac 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -80,11 +80,13 @@ public String abbreviateBannerText(List bannerComponentNode return bannerText; } - private boolean shouldKeepAbbreviating(TextView textView, String bannerText, int currAbbreviationPriority, int maxAbbreviationPriority) { + private boolean shouldKeepAbbreviating(TextView textView, String bannerText, + int currAbbreviationPriority, int maxAbbreviationPriority) { return !textViewUtils.textFits(textView, bannerText) && currAbbreviationPriority <= maxAbbreviationPriority; } - private boolean abbreviateAtAbbreviationPriority(List bannerComponentNodes, List indices) { + private boolean abbreviateAtAbbreviationPriority(List bannerComponentNodes, + List indices) { if (indices == null) { return false; } From 1edda009afb4585a0a6ae76038cb17eb69b3fb0f Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Thu, 17 May 2018 14:37:43 -0400 Subject: [PATCH 31/36] Made changes according to PR comments --- .../instruction/AbbreviationCoordinator.java | 23 +++++++------- .../instruction/InstructionImageLoader.java | 4 +-- .../ui/v5/instruction/InstructionLoader.java | 31 +++++++------------ .../ui/v5/instruction/InstructionView.java | 17 ++++++++-- .../{utils => instruction}/TextViewUtils.java | 6 ++-- .../AbbreviationCoordinatorTest.java | 14 ++++----- .../v5/instruction/BannerComponentsFaker.java | 4 +-- .../v5/instruction/InstructionLoaderTest.java | 17 +++------- 8 files changed, 55 insertions(+), 61 deletions(-) rename libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/{utils => instruction}/TextViewUtils.java (57%) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index d67fb999eac..f93894d1a61 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -4,7 +4,6 @@ import com.mapbox.api.directions.v5.models.BannerComponents; import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.BannerComponentNode; -import com.mapbox.services.android.navigation.ui.v5.utils.TextViewUtils; import java.util.ArrayList; import java.util.Collections; @@ -18,17 +17,17 @@ * BannerComponents containing abbreviation information and given a list of BannerComponentNodes, * constructed by InstructionLoader. */ -public class AbbreviationCoordinator { +class AbbreviationCoordinator { private static final String SINGLE_SPACE = " "; private Map> abbreviations; private TextViewUtils textViewUtils; - public AbbreviationCoordinator(TextViewUtils textViewUtils) { + AbbreviationCoordinator(TextViewUtils textViewUtils) { this.abbreviations = new HashMap<>(); this.textViewUtils = textViewUtils; } - public AbbreviationCoordinator() { + AbbreviationCoordinator() { this(new TextViewUtils()); } @@ -40,9 +39,9 @@ public AbbreviationCoordinator() { * @param bannerComponents object holding the abbreviation information * @param index in the list of BannerComponentNodes */ - public void addPriorityInfo(BannerComponents bannerComponents, int index) { - int abbreviationPriority = bannerComponents.abbreviationPriority(); - if (abbreviations.get(Integer.valueOf(abbreviationPriority)) == null) { + void addPriorityInfo(BannerComponents bannerComponents, int index) { + Integer abbreviationPriority = bannerComponents.abbreviationPriority(); + if (abbreviations.get(abbreviationPriority) == null) { abbreviations.put(abbreviationPriority, new ArrayList()); } abbreviations.get(abbreviationPriority).add(index); @@ -50,13 +49,13 @@ public void addPriorityInfo(BannerComponents bannerComponents, int index) { /** * Using the abbreviations HashMap which should already be populated, abbreviates the text in the - * bannerConmponentNodes until the text fits the given TextView. + * bannerComponentNodes until the text fits the given TextView. * * @param bannerComponentNodes containing the text to construct * @param textView to check the text fits * @return the properly abbreviated string that will fit in the TextView */ - public String abbreviateBannerText(List bannerComponentNodes, TextView textView) { + String abbreviateBannerText(List bannerComponentNodes, TextView textView) { String bannerText = join(bannerComponentNodes); if (abbreviations.isEmpty()) { @@ -67,7 +66,7 @@ public String abbreviateBannerText(List bannerComponentNode int maxAbbreviationPriority = Collections.max(abbreviations.keySet()); while (shouldKeepAbbreviating(textView, bannerText, currAbbreviationPriority, maxAbbreviationPriority)) { - List indices = abbreviations.get(new Integer(currAbbreviationPriority++)); + List indices = abbreviations.get(currAbbreviationPriority++); boolean abbreviationPriorityExists = abbreviateAtAbbreviationPriority(bannerComponentNodes, indices); @@ -127,7 +126,7 @@ private String join(List tokens) { * Class used by InstructionLoader to determine that a BannerComponent contains an abbreviation */ static class AbbreviationNode extends BannerComponentNode { - protected boolean abbreviate; + boolean abbreviate; AbbreviationNode(BannerComponents bannerComponents, int startIndex) { super(bannerComponents, startIndex); @@ -138,7 +137,7 @@ public String toString() { return abbreviate ? bannerComponents.abbreviation() : bannerComponents.text(); } - public void setAbbreviate(boolean abbreviate) { + void setAbbreviate(boolean abbreviate) { this.abbreviate = abbreviate; } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index 50fa2c8a870..77ebf01bbea 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -25,7 +25,7 @@ * URL taking priority). *

* If a shield URL is found, {@link Picasso} is used to load the image. Then, once the image is loaded, - * a new {@link ImageSpan} is created and set to the appropriate position of the {@link Spannable}/ + * a new {@link ImageSpan} is created and set to the appropriate position of the {@link Spannable} */ public class InstructionImageLoader { @@ -162,7 +162,7 @@ private void fetchImageBaseUrls(BannerText bannerText) { } } - public boolean hasImageUrl(BannerComponents components) { + private boolean hasImageUrl(BannerComponents components) { return !TextUtils.isEmpty(components.imageBaseUrl()); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index de6fa020c9f..ed3af0b6b36 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -1,5 +1,6 @@ package com.mapbox.services.android.navigation.ui.v5.instruction; +import android.support.annotation.NonNull; import android.text.Spannable; import android.text.style.ImageSpan; import android.widget.TextView; @@ -24,28 +25,24 @@ * If a shield URL is found, {@link Picasso} is used to load the image. Then, once the image is loaded, * a new {@link ImageSpan} is created and set to the appropriate position of the {@link Spannable}/ */ -public class InstructionLoader { - private static InstructionImageLoader instructionImageLoader; +class InstructionLoader { + private InstructionImageLoader instructionImageLoader; private AbbreviationCoordinator abbreviationCoordinator; private TextView textView; private List bannerComponentNodes; - public InstructionLoader(TextView textView, BannerText bannerText) { - this(textView, bannerText, InstructionImageLoader.getInstance(), new AbbreviationCoordinator()); + InstructionLoader(TextView textView, @NonNull List bannerComponents) { + this(textView, bannerComponents, InstructionImageLoader.getInstance(), new AbbreviationCoordinator()); } - public InstructionLoader(TextView textView, BannerText bannerText, InstructionImageLoader instructionImageLoader, - AbbreviationCoordinator abbreviationCoordinator) { + InstructionLoader(TextView textView, @NonNull List bannerComponents, + InstructionImageLoader instructionImageLoader, AbbreviationCoordinator abbreviationCoordinator) { this.abbreviationCoordinator = abbreviationCoordinator; this.textView = textView; bannerComponentNodes = new ArrayList<>(); this.instructionImageLoader = instructionImageLoader; - if (!hasComponents(bannerText)) { - return; - } - - bannerComponentNodes = parseBannerComponents(bannerText.components()); + bannerComponentNodes = parseBannerComponents(bannerComponents); } /** @@ -53,7 +50,7 @@ public InstructionLoader(TextView textView, BannerText bannerText, InstructionIm * a new {@link Spannable} with text / {@link ImageSpan}s which is loaded * into the given {@link TextView}. */ - public void loadInstruction() { + void loadInstruction() { setText(textView, bannerComponentNodes); loadImages(textView, bannerComponentNodes); } @@ -109,18 +106,14 @@ private boolean hasImageUrl(BannerComponents components) { return !TextUtils.isEmpty(components.imageBaseUrl()); } - private static boolean hasComponents(BannerText bannerText) { - return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); - } - /** * Class used to construct a list of BannerComponents to be populated into a TextView */ static class BannerComponentNode { - protected BannerComponents bannerComponents; - protected int startIndex; + BannerComponents bannerComponents; + int startIndex; - protected BannerComponentNode(BannerComponents bannerComponents, int startIndex) { + BannerComponentNode(BannerComponents bannerComponents, int startIndex) { this.bannerComponents = bannerComponents; this.startIndex = startIndex; } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java index 3c69fa351c5..068f0e7d307 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java @@ -35,6 +35,7 @@ import android.widget.RelativeLayout; import android.widget.TextView; +import com.mapbox.api.directions.v5.models.BannerText; import com.mapbox.api.directions.v5.models.IntersectionLanes; import com.mapbox.api.directions.v5.models.LegStep; import com.mapbox.services.android.navigation.ui.v5.NavigationViewModel; @@ -683,7 +684,7 @@ private void distanceText(InstructionModel model) { */ private void updateTextInstruction(InstructionModel model) { if (model.getPrimaryBannerText() != null) { - new InstructionLoader(upcomingPrimaryText, model.getPrimaryBannerText()).loadInstruction(); + createInstructionLoader(upcomingPrimaryText, model.getPrimaryBannerText()).loadInstruction(); } if (model.getSecondaryBannerText() != null) { if (upcomingSecondaryText.getVisibility() == GONE) { @@ -691,7 +692,7 @@ private void updateTextInstruction(InstructionModel model) { upcomingPrimaryText.setMaxLines(1); adjustBannerTextVerticalBias(0.65f); } - new InstructionLoader(upcomingSecondaryText, model.getSecondaryBannerText()).loadInstruction(); + createInstructionLoader(upcomingSecondaryText, model.getSecondaryBannerText()).loadInstruction(); } else { upcomingPrimaryText.setMaxLines(2); upcomingSecondaryText.setVisibility(GONE); @@ -699,6 +700,18 @@ private void updateTextInstruction(InstructionModel model) { } } + private InstructionLoader createInstructionLoader(TextView textView, BannerText bannerText) { + if (hasComponents(bannerText)) { + return new InstructionLoader(textView, bannerText.components()); + } else { + return null; + } + } + + private boolean hasComponents(BannerText bannerText) { + return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); + } + /** * Looks to see if we have a new step. * diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/utils/TextViewUtils.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/TextViewUtils.java similarity index 57% rename from libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/utils/TextViewUtils.java rename to libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/TextViewUtils.java index 14eec43e972..fb5665be7aa 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/utils/TextViewUtils.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/TextViewUtils.java @@ -1,11 +1,11 @@ -package com.mapbox.services.android.navigation.ui.v5.utils; +package com.mapbox.services.android.navigation.ui.v5.instruction; import android.graphics.Paint; import android.widget.TextView; -public class TextViewUtils { +class TextViewUtils { - public boolean textFits(TextView textView, String text) { + boolean textFits(TextView textView, String text) { Paint paint = new Paint(textView.getPaint()); float width = paint.measureText(text); return width < textView.getWidth(); diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java index 70c50b1c0d6..b55c9f0176a 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java @@ -4,7 +4,6 @@ import com.mapbox.api.directions.v5.models.BannerComponents; import com.mapbox.services.android.navigation.ui.v5.BaseTest; -import com.mapbox.services.android.navigation.ui.v5.utils.TextViewUtils; import org.junit.Test; @@ -28,21 +27,20 @@ public void textIsAbbreviatedWhenItDoesntFit() { TextView textView = mock(TextView.class); when(textViewUtils.textFits(textView, abbreviation)).thenReturn(true); when(textViewUtils.textFits(textView, bannerComponents.text())).thenReturn(false); - AbbreviationCoordinator abbreviationCoordinator = new AbbreviationCoordinator(textViewUtils); abbreviationCoordinator.addPriorityInfo(bannerComponents, 0); - List bannerComponentNodes = new ArrayList<>(); bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationNode(bannerComponents, 0)); - assertEquals(abbreviation, abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView)); + String abbreviatedTextFromCoordinator = abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView); + + assertEquals(abbreviation, abbreviatedTextFromCoordinator); } @Test public void textIsNotAbbreviatedWhenItDoesFit() { String abbreviation = "smtxt"; String text = "some text"; - BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() .abbreviation(abbreviation) @@ -52,13 +50,13 @@ public void textIsNotAbbreviatedWhenItDoesFit() { TextViewUtils textViewUtils = mock(TextViewUtils.class); TextView textView = mock(TextView.class); when(textViewUtils.textFits(textView, bannerComponents.text())).thenReturn(true); - AbbreviationCoordinator abbreviationCoordinator = new AbbreviationCoordinator(textViewUtils); abbreviationCoordinator.addPriorityInfo(bannerComponents, 0); - List bannerComponentNodes = new ArrayList<>(); bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationNode(bannerComponents, 0)); - assertEquals(text, abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView)); + String abbreviatedTextFromCoordinator = abbreviationCoordinator.abbreviateBannerText(bannerComponentNodes, textView); + + assertEquals(text, abbreviatedTextFromCoordinator); } } diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerComponentsFaker.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerComponentsFaker.java index aa1b95fcd4b..79096670d8b 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerComponentsFaker.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/BannerComponentsFaker.java @@ -2,8 +2,8 @@ import com.mapbox.api.directions.v5.models.BannerComponents; -public class BannerComponentsFaker { - public static BannerComponents.Builder bannerComponents() { +class BannerComponentsFaker { + static BannerComponents.Builder bannerComponents() { return BannerComponents.builder() .type("some type") .text("some text"); diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java index 399c71a0f4d..b0092091a03 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java @@ -3,7 +3,6 @@ import android.widget.TextView; import com.mapbox.api.directions.v5.models.BannerComponents; -import com.mapbox.api.directions.v5.models.BannerText; import org.junit.Test; @@ -20,7 +19,6 @@ public class InstructionLoaderTest { @Test public void testPriorityInfoIsAdded() { TextView textView = mock(TextView.class); - BannerText bannerText = mock(BannerText.class); InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() @@ -29,9 +27,8 @@ public void testPriorityInfoIsAdded() { .build(); List bannerComponentsList = new ArrayList<>(); bannerComponentsList.add(bannerComponents); - when(bannerText.components()).thenReturn(bannerComponentsList); - new InstructionLoader(textView, bannerText, instructionImageLoader, abbreviationCoordinator); + new InstructionLoader(textView, bannerComponentsList, instructionImageLoader, abbreviationCoordinator); verify(abbreviationCoordinator).addPriorityInfo(bannerComponents, 0); } @@ -39,7 +36,6 @@ public void testPriorityInfoIsAdded() { @Test public void testShieldInfoIsAdded() { TextView textView = mock(TextView.class); - BannerText bannerText = mock(BannerText.class); InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() @@ -47,9 +43,8 @@ public void testShieldInfoIsAdded() { .build(); List bannerComponentsList = new ArrayList<>(); bannerComponentsList.add(bannerComponents); - when(bannerText.components()).thenReturn(bannerComponentsList); - new InstructionLoader(textView, bannerText, instructionImageLoader, abbreviationCoordinator); + new InstructionLoader(textView, bannerComponentsList, instructionImageLoader, abbreviationCoordinator); verify(instructionImageLoader).addShieldInfo(bannerComponents, 0); } @@ -57,7 +52,6 @@ public void testShieldInfoIsAdded() { @Test public void testSetAbbreviatedText() { TextView textView = mock(TextView.class); - BannerText bannerText = mock(BannerText.class); InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() @@ -66,10 +60,9 @@ public void testSetAbbreviatedText() { .build(); List bannerComponentsList = new ArrayList<>(); bannerComponentsList.add(bannerComponents); - when(bannerText.components()).thenReturn(bannerComponentsList); String abbreviatedText = "abbreviated text"; when(abbreviationCoordinator.abbreviateBannerText(any(List.class), any(TextView.class))).thenReturn(abbreviatedText); - InstructionLoader instructionLoader = new InstructionLoader(textView, bannerText, instructionImageLoader, abbreviationCoordinator); + InstructionLoader instructionLoader = new InstructionLoader(textView, bannerComponentsList, instructionImageLoader, abbreviationCoordinator); instructionLoader.loadInstruction(); @@ -79,7 +72,6 @@ public void testSetAbbreviatedText() { @Test public void testLoadImages() { TextView textView = mock(TextView.class); - BannerText bannerText = mock(BannerText.class); InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() @@ -87,10 +79,9 @@ public void testLoadImages() { .build(); List bannerComponentsList = new ArrayList<>(); bannerComponentsList.add(bannerComponents); - when(bannerText.components()).thenReturn(bannerComponentsList); String abbreviatedText = "abbreviated text"; when(abbreviationCoordinator.abbreviateBannerText(any(List.class), any(TextView.class))).thenReturn(abbreviatedText); - InstructionLoader instructionLoader = new InstructionLoader(textView, bannerText, instructionImageLoader, abbreviationCoordinator); + InstructionLoader instructionLoader = new InstructionLoader(textView, bannerComponentsList, instructionImageLoader, abbreviationCoordinator); instructionLoader.loadInstruction(); From b7d53a5586433b75beaf33d77732803fefeb456b Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Thu, 17 May 2018 17:25:53 -0400 Subject: [PATCH 32/36] Updated test names --- .../ui/v5/instruction/AbbreviationCoordinatorTest.java | 4 ++-- .../ui/v5/instruction/InstructionLoaderTest.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java index b55c9f0176a..ece3f95acd5 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinatorTest.java @@ -16,7 +16,7 @@ public class AbbreviationCoordinatorTest extends BaseTest { @Test - public void textIsAbbreviatedWhenItDoesntFit() { + public void onAbbreviateBannerText_textIsAbbreviated() { String abbreviation = "smtxt"; BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() @@ -38,7 +38,7 @@ public void textIsAbbreviatedWhenItDoesntFit() { } @Test - public void textIsNotAbbreviatedWhenItDoesFit() { + public void onAbbreviateBannerText_textIsNotAbbreviated() { String abbreviation = "smtxt"; String text = "some text"; BannerComponents bannerComponents = diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java index b0092091a03..93068eeb953 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java @@ -17,7 +17,7 @@ public class InstructionLoaderTest { @Test - public void testPriorityInfoIsAdded() { + public void onInstructionLoaderCreated_priorityInfoIsAdded() { TextView textView = mock(TextView.class); InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); @@ -34,7 +34,7 @@ public void testPriorityInfoIsAdded() { } @Test - public void testShieldInfoIsAdded() { + public void onInstructionLoaderCreated_shieldInfoIsAdded() { TextView textView = mock(TextView.class); InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); @@ -50,7 +50,7 @@ public void testShieldInfoIsAdded() { } @Test - public void testSetAbbreviatedText() { + public void onLoadInstruction_textIsAbbreviated() { TextView textView = mock(TextView.class); InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); @@ -70,7 +70,7 @@ public void testSetAbbreviatedText() { } @Test - public void testLoadImages() { + public void onLoadInstruction_imagesAreLoaded() { TextView textView = mock(TextView.class); InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); From 4a8427bc0d06abf25a3c04b277e8c31482275fd4 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Fri, 18 May 2018 10:45:47 -0400 Subject: [PATCH 33/36] Cleanup from PR comments --- .../instruction/AbbreviationCoordinator.java | 10 ++- .../instruction/InstructionImageLoader.java | 61 +++++++++++-------- .../ui/v5/instruction/InstructionTarget.java | 47 +++++++------- 3 files changed, 70 insertions(+), 48 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index f93894d1a61..fb4ea51124c 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -62,8 +62,17 @@ String abbreviateBannerText(List bannerComponentNodes, Text return bannerText; } + abbreviateUntilTextFits(textView, bannerText, bannerComponentNodes); + + abbreviations.clear(); + return bannerText; + } + + private String abbreviateUntilTextFits(TextView textView, String startingText, + List bannerComponentNodes) { int currAbbreviationPriority = 0; int maxAbbreviationPriority = Collections.max(abbreviations.keySet()); + String bannerText = startingText; while (shouldKeepAbbreviating(textView, bannerText, currAbbreviationPriority, maxAbbreviationPriority)) { List indices = abbreviations.get(currAbbreviationPriority++); @@ -75,7 +84,6 @@ String abbreviateBannerText(List bannerComponentNodes, Text } } - abbreviations.clear(); return bannerText; } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index 77ebf01bbea..911d77d314b 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -62,14 +62,8 @@ public static synchronized InstructionImageLoader getInstance() { */ public void initialize(Context context) { if (!isInitialized) { - Picasso.Builder builder = new Picasso.Builder(context) - .loggingEnabled(true); - picassoImageLoader = builder.build(); - - this.urlDensityMap = new UrlDensityMap(context); - targets = new ArrayList<>(); - bannerShieldList = new ArrayList<>(); - + initializePicasso(context); + initializeData(context); isInitialized = true; } } @@ -91,25 +85,11 @@ public void addShieldInfo(BannerComponents bannerComponents, int index) { * If loaded successfully, this will allow the images to be displayed * without delay in the {@link InstructionView}. * - * @param step providing the image Urls + * @param legStep providing the image Urls */ - public void prefetchImageCache(LegStep step) { - if (step == null || step.bannerInstructions() == null - || step.bannerInstructions().isEmpty()) { - return; - } - + public void prefetchImageCache(LegStep legStep) { checkIsInitialized(); - - List bannerInstructionList = new ArrayList<>(step.bannerInstructions()); - for (BannerInstructions instructions : bannerInstructionList) { - if (hasComponents(instructions.primary())) { - fetchImageBaseUrls(instructions.primary()); - } - if (hasComponents(instructions.secondary())) { - fetchImageBaseUrls(instructions.secondary()); - } - } + fetchInstructions(legStep); } public void shutdown() { @@ -134,13 +114,42 @@ public void loadImages(TextView textView, List bannerCompon loadTargets(); } + private void initializePicasso(Context context) { + Picasso.Builder builder = new Picasso.Builder(context) + .loggingEnabled(true); + picassoImageLoader = builder.build(); + } + + private void initializeData(Context context) { + urlDensityMap = new UrlDensityMap(context); + targets = new ArrayList<>(); + bannerShieldList = new ArrayList<>(); + } + + private void fetchInstructions(LegStep legStep) { + if (legStep == null || legStep.bannerInstructions() == null + || legStep.bannerInstructions().isEmpty()) { + return; + } + + List bannerInstructionList = new ArrayList<>(legStep.bannerInstructions()); + for (BannerInstructions instructions : bannerInstructionList) { + if (hasComponents(instructions.primary())) { + fetchImageBaseUrls(instructions.primary()); + } + if (hasComponents(instructions.secondary())) { + fetchImageBaseUrls(instructions.secondary()); + } + } + } + private void updateShieldUrlIndices(List bannerComponentNodes) { for (BannerShield bannerShield : bannerShieldList) { bannerShield.setStartIndex(bannerComponentNodes.get(bannerShield.getNodeIndex()).startIndex); } } - private static boolean hasComponents(BannerText bannerText) { + private boolean hasComponents(BannerText bannerText) { return bannerText != null && bannerText.components() != null && !bannerText.components().isEmpty(); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java index 4cd032ade08..20576ca9dd5 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionTarget.java @@ -40,44 +40,49 @@ BannerShield getShield() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { - // Create a new Drawable with intrinsic bounds - Drawable drawable = new BitmapDrawable(textView.getContext().getResources(), bitmap); - - // width == (right - left), and height == (bottom - top) - int bottom = textView.getLineHeight(); - int right = bottom * bitmap.getWidth() / bitmap.getHeight(); - drawable.setBounds(0, 0, right, bottom); - - // Create and set a new ImageSpan at the given index with the Drawable - instructionSpannable.setSpan(new ImageSpan(drawable), - shield.getStartIndex(), shield.getEndIndex(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - - // Check if last in array, if so, set the text with the spannable - if (shields.indexOf(shield) == shields.size() - 1) { - // Make sure cut-off images aren't displayed at the end of the spannable - CharSequence truncatedSequence = truncateImageSpan(instructionSpannable, textView); - textView.setText(truncatedSequence); - } + Drawable drawable = createDrawable(bitmap); + createAndSetImageSpan(drawable); sendInstructionLoadedCallback(); } @Override public void onBitmapFailed(Drawable errorDrawable) { - // Set the backup text - textView.setText(shield.getText()); + setBackupText(); sendInstructionLoadedCallback(); Timber.e("Shield bitmap failed to load."); } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { - + // no op } interface InstructionLoadedCallback { void onInstructionLoaded(InstructionTarget target); } + private void setBackupText() { + textView.setText(shield.getText()); + } + + private void createAndSetImageSpan(Drawable drawable) { + instructionSpannable.setSpan(new ImageSpan(drawable), + shield.getStartIndex(), shield.getEndIndex(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + if (shields.indexOf(shield) == shields.size() - 1) { + CharSequence truncatedSequence = truncateImageSpan(instructionSpannable, textView); + textView.setText(truncatedSequence); + } + } + + private Drawable createDrawable(Bitmap bitmap) { + Drawable drawable = new BitmapDrawable(textView.getContext().getResources(), bitmap); + int bottom = textView.getLineHeight(); + int right = bottom * bitmap.getWidth() / bitmap.getHeight(); + drawable.setBounds(0, 0, right, bottom); + return drawable; + } + private void sendInstructionLoadedCallback() { if (instructionLoadedCallback != null) { instructionLoadedCallback.onInstructionLoaded(this); From 13dd6997c5faa860c6e04e21b04bf7b3d0f11edb Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Fri, 18 May 2018 10:50:20 -0400 Subject: [PATCH 34/36] Refactored name --- .../ui/v5/instruction/InstructionImageLoader.java | 4 ++-- .../navigation/ui/v5/instruction/InstructionLoader.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java index 911d77d314b..57c2e866ae7 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java @@ -202,9 +202,9 @@ private void checkIsInitialized() { } } - static class ShieldNode extends BannerComponentNode { + static class ImageNode extends BannerComponentNode { - ShieldNode(BannerComponents bannerComponents, int startIndex) { + ImageNode(BannerComponents bannerComponents, int startIndex) { super(bannerComponents, startIndex); } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index ed3af0b6b36..a22fefacc9f 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -9,7 +9,7 @@ import com.mapbox.api.directions.v5.models.BannerText; import com.mapbox.core.utils.TextUtils; import com.mapbox.services.android.navigation.ui.v5.instruction.AbbreviationCoordinator.AbbreviationNode; -import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionImageLoader.ShieldNode; +import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionImageLoader.ImageNode; import com.squareup.picasso.Picasso; import java.util.ArrayList; @@ -75,9 +75,9 @@ private List parseBannerComponents(List b return bannerComponentNodes; } - private ShieldNode setupImageNode(BannerComponents components, int index, int startIndex) { + private ImageNode setupImageNode(BannerComponents components, int index, int startIndex) { instructionImageLoader.addShieldInfo(components, index); - return new InstructionImageLoader.ShieldNode(components, startIndex); + return new ImageNode(components, startIndex); } private AbbreviationNode setupAbbreviationNode(BannerComponents components, int index, int startIndex) { From 2698e054ff43d4674329f7a38a4971a22d8ba122 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Fri, 18 May 2018 14:44:05 -0400 Subject: [PATCH 35/36] Renamed ImageLoader to ImageCoordinator --- .../navigation/ui/v5/NavigationView.java | 6 +++--- ...ImageLoader.java => ImageCoordinator.java} | 10 +++++----- .../ui/v5/instruction/InstructionLoader.java | 14 ++++++------- .../ui/v5/instruction/InstructionView.java | 2 +- .../v5/instruction/InstructionLoaderTest.java | 20 +++++++++---------- 5 files changed, 26 insertions(+), 26 deletions(-) rename libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/{InstructionImageLoader.java => ImageCoordinator.java} (96%) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationView.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationView.java index 1d2e1059a0e..44e936c3040 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationView.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationView.java @@ -32,7 +32,7 @@ import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin; import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.services.android.navigation.ui.v5.camera.NavigationCamera; -import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionImageLoader; +import com.mapbox.services.android.navigation.ui.v5.instruction.ImageCoordinator; import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionView; import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute; import com.mapbox.services.android.navigation.ui.v5.summary.SummaryBottomSheet; @@ -181,7 +181,7 @@ public void onRestoreInstanceState(Bundle savedInstanceState) { public void onDestroy() { mapView.onDestroy(); navigationViewModel.onDestroy(isChangingConfigurations()); - InstructionImageLoader.getInstance().shutdown(); + ImageCoordinator.getInstance().shutdown(); if (camera != null) { camera.onDestroy(); } @@ -404,7 +404,7 @@ public MapboxMap getMapboxMap() { } private void initializeView() { - InstructionImageLoader.getInstance().initialize(getContext()); + ImageCoordinator.getInstance().initialize(getContext()); inflate(getContext(), R.layout.navigation_view_layout, this); bind(); initializeNavigationViewModel(); diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/ImageCoordinator.java similarity index 96% rename from libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java rename to libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/ImageCoordinator.java index 57c2e866ae7..5d51d0d4670 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionImageLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/ImageCoordinator.java @@ -27,16 +27,16 @@ * If a shield URL is found, {@link Picasso} is used to load the image. Then, once the image is loaded, * a new {@link ImageSpan} is created and set to the appropriate position of the {@link Spannable} */ -public class InstructionImageLoader { +public class ImageCoordinator { - private static InstructionImageLoader instance; + private static ImageCoordinator instance; private boolean isInitialized; private Picasso picassoImageLoader; private List targets; private UrlDensityMap urlDensityMap; private List bannerShieldList; - private InstructionImageLoader() { + private ImageCoordinator() { } /** @@ -44,9 +44,9 @@ private InstructionImageLoader() { * * @return InstructionLoader */ - public static synchronized InstructionImageLoader getInstance() { + public static synchronized ImageCoordinator getInstance() { if (instance == null) { - instance = new InstructionImageLoader(); + instance = new ImageCoordinator(); } return instance; diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java index a22fefacc9f..a344818ccc7 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoader.java @@ -9,7 +9,7 @@ import com.mapbox.api.directions.v5.models.BannerText; import com.mapbox.core.utils.TextUtils; import com.mapbox.services.android.navigation.ui.v5.instruction.AbbreviationCoordinator.AbbreviationNode; -import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionImageLoader.ImageNode; +import com.mapbox.services.android.navigation.ui.v5.instruction.ImageCoordinator.ImageNode; import com.squareup.picasso.Picasso; import java.util.ArrayList; @@ -26,21 +26,21 @@ * a new {@link ImageSpan} is created and set to the appropriate position of the {@link Spannable}/ */ class InstructionLoader { - private InstructionImageLoader instructionImageLoader; + private ImageCoordinator imageCoordinator; private AbbreviationCoordinator abbreviationCoordinator; private TextView textView; private List bannerComponentNodes; InstructionLoader(TextView textView, @NonNull List bannerComponents) { - this(textView, bannerComponents, InstructionImageLoader.getInstance(), new AbbreviationCoordinator()); + this(textView, bannerComponents, ImageCoordinator.getInstance(), new AbbreviationCoordinator()); } InstructionLoader(TextView textView, @NonNull List bannerComponents, - InstructionImageLoader instructionImageLoader, AbbreviationCoordinator abbreviationCoordinator) { + ImageCoordinator imageCoordinator, AbbreviationCoordinator abbreviationCoordinator) { this.abbreviationCoordinator = abbreviationCoordinator; this.textView = textView; bannerComponentNodes = new ArrayList<>(); - this.instructionImageLoader = instructionImageLoader; + this.imageCoordinator = imageCoordinator; bannerComponentNodes = parseBannerComponents(bannerComponents); } @@ -76,7 +76,7 @@ private List parseBannerComponents(List b } private ImageNode setupImageNode(BannerComponents components, int index, int startIndex) { - instructionImageLoader.addShieldInfo(components, index); + imageCoordinator.addShieldInfo(components, index); return new ImageNode(components, startIndex); } @@ -86,7 +86,7 @@ private AbbreviationNode setupAbbreviationNode(BannerComponents components, int } private void loadImages(TextView textView, List bannerComponentNodes) { - instructionImageLoader.loadImages(textView, bannerComponentNodes); + imageCoordinator.loadImages(textView, bannerComponentNodes); } private void setText(TextView textView, List bannerComponentNodes) { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java index 068f0e7d307..4baf58031e8 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionView.java @@ -235,7 +235,7 @@ private void updateViews(InstructionModel model) { if (newStep(model.getProgress())) { // Pre-fetch the image URLs for the upcoming step LegStep upComingStep = model.getProgress().currentLegProgress().upComingStep(); - InstructionImageLoader.getInstance().prefetchImageCache(upComingStep); + ImageCoordinator.getInstance().prefetchImageCache(upComingStep); } } diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java index 93068eeb953..0391f2edcaf 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/instruction/InstructionLoaderTest.java @@ -19,7 +19,7 @@ public class InstructionLoaderTest { @Test public void onInstructionLoaderCreated_priorityInfoIsAdded() { TextView textView = mock(TextView.class); - InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); + ImageCoordinator imageCoordinator = mock(ImageCoordinator.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() .abbreviationPriority(1) @@ -28,7 +28,7 @@ public void onInstructionLoaderCreated_priorityInfoIsAdded() { List bannerComponentsList = new ArrayList<>(); bannerComponentsList.add(bannerComponents); - new InstructionLoader(textView, bannerComponentsList, instructionImageLoader, abbreviationCoordinator); + new InstructionLoader(textView, bannerComponentsList, imageCoordinator, abbreviationCoordinator); verify(abbreviationCoordinator).addPriorityInfo(bannerComponents, 0); } @@ -36,7 +36,7 @@ public void onInstructionLoaderCreated_priorityInfoIsAdded() { @Test public void onInstructionLoaderCreated_shieldInfoIsAdded() { TextView textView = mock(TextView.class); - InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); + ImageCoordinator imageCoordinator = mock(ImageCoordinator.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() .imageBaseUrl("string url") @@ -44,15 +44,15 @@ public void onInstructionLoaderCreated_shieldInfoIsAdded() { List bannerComponentsList = new ArrayList<>(); bannerComponentsList.add(bannerComponents); - new InstructionLoader(textView, bannerComponentsList, instructionImageLoader, abbreviationCoordinator); + new InstructionLoader(textView, bannerComponentsList, imageCoordinator, abbreviationCoordinator); - verify(instructionImageLoader).addShieldInfo(bannerComponents, 0); + verify(imageCoordinator).addShieldInfo(bannerComponents, 0); } @Test public void onLoadInstruction_textIsAbbreviated() { TextView textView = mock(TextView.class); - InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); + ImageCoordinator imageCoordinator = mock(ImageCoordinator.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() .abbreviationPriority(1) @@ -62,7 +62,7 @@ public void onLoadInstruction_textIsAbbreviated() { bannerComponentsList.add(bannerComponents); String abbreviatedText = "abbreviated text"; when(abbreviationCoordinator.abbreviateBannerText(any(List.class), any(TextView.class))).thenReturn(abbreviatedText); - InstructionLoader instructionLoader = new InstructionLoader(textView, bannerComponentsList, instructionImageLoader, abbreviationCoordinator); + InstructionLoader instructionLoader = new InstructionLoader(textView, bannerComponentsList, imageCoordinator, abbreviationCoordinator); instructionLoader.loadInstruction(); @@ -72,7 +72,7 @@ public void onLoadInstruction_textIsAbbreviated() { @Test public void onLoadInstruction_imagesAreLoaded() { TextView textView = mock(TextView.class); - InstructionImageLoader instructionImageLoader = mock(InstructionImageLoader.class); + ImageCoordinator imageCoordinator = mock(ImageCoordinator.class); AbbreviationCoordinator abbreviationCoordinator = mock(AbbreviationCoordinator.class); BannerComponents bannerComponents = BannerComponentsFaker.bannerComponents() .imageBaseUrl("string url") @@ -81,10 +81,10 @@ public void onLoadInstruction_imagesAreLoaded() { bannerComponentsList.add(bannerComponents); String abbreviatedText = "abbreviated text"; when(abbreviationCoordinator.abbreviateBannerText(any(List.class), any(TextView.class))).thenReturn(abbreviatedText); - InstructionLoader instructionLoader = new InstructionLoader(textView, bannerComponentsList, instructionImageLoader, abbreviationCoordinator); + InstructionLoader instructionLoader = new InstructionLoader(textView, bannerComponentsList, imageCoordinator, abbreviationCoordinator); instructionLoader.loadInstruction(); - verify(instructionImageLoader).loadImages(any(TextView.class), any(List.class)); + verify(imageCoordinator).loadImages(any(TextView.class), any(List.class)); } } \ No newline at end of file From 7de31c7bae200385a8a01e0c1df7ea9dc844e64e Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Fri, 18 May 2018 14:51:35 -0400 Subject: [PATCH 36/36] Fixed bug --- .../navigation/ui/v5/instruction/AbbreviationCoordinator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java index fb4ea51124c..1c1a08247b0 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/instruction/AbbreviationCoordinator.java @@ -62,7 +62,7 @@ String abbreviateBannerText(List bannerComponentNodes, Text return bannerText; } - abbreviateUntilTextFits(textView, bannerText, bannerComponentNodes); + bannerText = abbreviateUntilTextFits(textView, bannerText, bannerComponentNodes); abbreviations.clear(); return bannerText;