[android] Highlight turn lanes and use correct icons

The Android UI highlights the recommended turn lanes and chooses an
icon corresponding to a direction of the turn lane.

Needed for: #1404

Signed-off-by: Nathan Varner <nathanmvarner@protonmail.com>
This commit is contained in:
Nathan Varner 2023-03-07 02:28:19 -05:00 committed by Viktor Govako
parent 26108812d4
commit f8c940009d
5 changed files with 73 additions and 28 deletions

View file

@ -106,12 +106,15 @@
</RelativeLayout>
<FrameLayout
android:id="@+id/lanes_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_half"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nav_next_turn_container"
app:layout_constraintTop_toBottomOf="@+id/street_frame">
app:layout_constraintTop_toBottomOf="@+id/street_frame"
android:visibility="gone"
tools:visibility="visible">
<include layout="@layout/nav_lanes" />
</FrameLayout>

View file

@ -1,5 +1,7 @@
package app.organicmaps.routing;
import android.content.res.ColorStateList;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -64,8 +66,25 @@ public class LanesAdapter extends RecyclerView.Adapter<LanesAdapter.LanesViewHol
mArrow = itemView.findViewById(R.id.lane_image);
}
private void setIconTint(@NonNull SingleLaneInfo info)
{
int iconTint = info.mIsActive ? R.attr.iconTint : R.attr.iconTintLight;
TypedValue color = new TypedValue();
mArrow.getContext().getTheme().resolveAttribute(iconTint, color, true);
mArrow.setImageTintList(ColorStateList.valueOf(color.data));
}
private void setIcon(@NonNull SingleLaneInfo info)
{
boolean haveLaneData = (info.mLane.length > 0);
int imageRes = haveLaneData ? info.mLane[0].mTurnRes : 0;
mArrow.setImageResource(imageRes);
}
void bind(@NonNull SingleLaneInfo info)
{
setIconTint(info);
setIcon(info);
}
}
}

View file

@ -53,6 +53,8 @@ public class NavigationController implements Application.ActivityLifecycleCallba
private final View mStreetFrame;
private final TextView mNextStreet;
@NonNull
private final View mLanesFrame;
@NonNull
private final RecyclerView mLanes;
@NonNull
@ -126,7 +128,8 @@ public class NavigationController implements Application.ActivityLifecycleCallba
mStreetFrame = topFrame.findViewById(R.id.street_frame);
mNextStreet = mStreetFrame.findViewById(R.id.street);
mLanes = topFrame.findViewById(R.id.lanes);
mLanesFrame = topFrame.findViewById(R.id.lanes_frame);
mLanes = mLanesFrame.findViewById(R.id.lanes);
mLanesAdapter = new LanesAdapter();
initLanesRecycler();
@ -205,9 +208,15 @@ public class NavigationController implements Application.ActivityLifecycleCallba
info.nextCarDirection.setNextTurnDrawable(mNextNextTurnImage);
if (info.lanes != null)
{
UiUtils.show(mLanesFrame);
mLanesAdapter.setItems(Arrays.asList(info.lanes));
}
else
{
UiUtils.hide(mLanesFrame);
mLanesAdapter.clearItems();
}
}
private void updatePedestrian(RoutingInfo info)

View file

@ -133,27 +133,6 @@ public class RoutingInfo
}
}
/**
* IMPORTANT : Order of enum values MUST BE the same
* with native LaneWay enum (see routing/turns.hpp for details).
* Information for every lane is composed of some number values below.
* For example, a lane may have THROUGH and RIGHT values.
*/
public enum LaneWay
{
NONE,
REVERSE,
SHARP_LEFT,
LEFT,
SLIGHT_LEFT,
MERGE_TO_RIGHT,
THROUGH,
MERGE_TO_LEFT,
SLIGHT_RIGHT,
RIGHT,
SHARP_RIGHT
}
public RoutingInfo(String distToTarget, String units, String distTurn, String turnSuffix, String currentStreet, String nextStreet, double completionPercent,
int vehicleTurnOrdinal, int vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
int totalTime, SingleLaneInfo[] lanes, boolean speedLimitExceeded,

View file

@ -1,13 +1,48 @@
package app.organicmaps.routing;
import androidx.annotation.DrawableRes;
import app.organicmaps.R;
public class SingleLaneInfo
{
byte[] mLane;
LaneWay[] mLane;
boolean mIsActive;
SingleLaneInfo(byte[] lane, boolean isActive)
/**
* IMPORTANT : Order of enum values MUST BE the same
* with native LaneWay enum (see routing/turns.hpp for details).
* Information for every lane is composed of some number values below.
* For example, a lane may have THROUGH and RIGHT values.
*/
public enum LaneWay
{
mLane = lane;
NONE(R.drawable.ic_turn_straight),
REVERSE(R.drawable.ic_turn_uleft),
SHARP_LEFT(R.drawable.ic_turn_left_sharp),
LEFT(R.drawable.ic_turn_left),
SLIGHT_LEFT(R.drawable.ic_turn_left_slight),
MERGE_TO_RIGHT(R.drawable.ic_turn_right_slight),
THROUGH(R.drawable.ic_turn_straight),
MERGE_TO_LEFT(R.drawable.ic_turn_left_slight),
SLIGHT_RIGHT(R.drawable.ic_turn_right_slight),
RIGHT(R.drawable.ic_turn_right),
SHARP_RIGHT(R.drawable.ic_turn_right_sharp);
public final int mTurnRes;
LaneWay(@DrawableRes int turnRes)
{
mTurnRes = turnRes;
}
}
SingleLaneInfo(byte[] laneOrdinals, boolean isActive)
{
mLane = new LaneWay[laneOrdinals.length];
final LaneWay[] values = LaneWay.values();
for (int i = 0; i < mLane.length; i++)
mLane[i] = values[laneOrdinals[i]];
mIsActive = isActive;
}
@ -17,8 +52,8 @@ public class SingleLaneInfo
final int initialCapacity = 32;
StringBuilder sb = new StringBuilder(initialCapacity);
sb.append("Is the lane active? ").append(mIsActive).append(". The lane directions IDs are");
for (byte i : mLane)
sb.append(" ").append(i);
for (LaneWay i : mLane)
sb.append(" ").append(i.ordinal());
return sb.toString();
}
}