mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-30 01:24:07 +00:00
[android] display info about available sockets on charging stations
This commit includes SVG icons of the sockets that are currently supported. This icons have been created for this specific occasion. Signed-off-by: Séverin Lemaignan <severin@guakamole.org>
This commit is contained in:
@@ -72,6 +72,7 @@ import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
|
||||
import app.organicmaps.util.bottomsheet.MenuBottomSheetItem;
|
||||
import app.organicmaps.widget.ArrowView;
|
||||
import app.organicmaps.widget.placepage.sections.PlacePageBookmarkFragment;
|
||||
import app.organicmaps.widget.placepage.sections.PlacePageChargeSocketsFragment;
|
||||
import app.organicmaps.widget.placepage.sections.PlacePageLinksFragment;
|
||||
import app.organicmaps.widget.placepage.sections.PlacePageOpeningHoursFragment;
|
||||
import app.organicmaps.widget.placepage.sections.PlacePagePhoneFragment;
|
||||
@@ -98,6 +99,7 @@ public class PlacePageView extends Fragment
|
||||
private static final String BOOKMARK_FRAGMENT_TAG = "BOOKMARK_FRAGMENT_TAG";
|
||||
private static final String TRACK_FRAGMENT_TAG = "TRACK_FRAGMENT_TAG";
|
||||
private static final String WIKIPEDIA_FRAGMENT_TAG = "WIKIPEDIA_FRAGMENT_TAG";
|
||||
private static final String CHARGE_SOCKETS_FRAGMENT_TAG = "CHARGE_SOCKETS_FRAGMENT_TAG";
|
||||
private static final String PHONE_FRAGMENT_TAG = "PHONE_FRAGMENT_TAG";
|
||||
private static final String OPENING_HOURS_FRAGMENT_TAG = "OPENING_HOURS_FRAGMENT_TAG";
|
||||
private static final String LINKS_FRAGMENT_TAG = "LINKS_FRAGMENT_TAG";
|
||||
@@ -405,6 +407,12 @@ public class PlacePageView extends Fragment
|
||||
R.id.place_page_opening_hours_fragment, !TextUtils.isEmpty(ohStr));
|
||||
}
|
||||
|
||||
private void updateChargeSocketsView()
|
||||
{
|
||||
updateViewFragment(PlacePageChargeSocketsFragment.class, CHARGE_SOCKETS_FRAGMENT_TAG,
|
||||
R.id.place_page_charge_sockets_fragment, mMapObject.hasChargeSockets());
|
||||
}
|
||||
|
||||
private void updatePhoneView()
|
||||
{
|
||||
updateViewFragment(PlacePagePhoneFragment.class, PHONE_FRAGMENT_TAG, R.id.place_page_phone_fragment,
|
||||
@@ -663,7 +671,8 @@ public class PlacePageView extends Fragment
|
||||
if (!lastChecked.isEmpty())
|
||||
{
|
||||
String periodSinceCheck = DateUtils.getRelativePeriodString(getResources(), lastChecked);
|
||||
UiUtils.setTextAndShow(mTvLastChecked, requireContext().getString(R.string.existence_confirmed_time_ago, periodSinceCheck));
|
||||
UiUtils.setTextAndShow(mTvLastChecked,
|
||||
requireContext().getString(R.string.existence_confirmed_time_ago, periodSinceCheck));
|
||||
}
|
||||
else
|
||||
UiUtils.hide(mTvLastChecked);
|
||||
@@ -700,6 +709,7 @@ public class PlacePageView extends Fragment
|
||||
updateOpeningHoursView();
|
||||
updateWikipediaView();
|
||||
updateBookmarkView();
|
||||
updateChargeSocketsView();
|
||||
updatePhoneView();
|
||||
updateTrackView();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package app.organicmaps.widget.placepage.sections;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.GridLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.google.android.material.imageview.ShapeableImageView;
|
||||
import com.google.android.material.textview.MaterialTextView;
|
||||
|
||||
import app.organicmaps.R;
|
||||
import app.organicmaps.sdk.Framework;
|
||||
import app.organicmaps.sdk.bookmarks.data.ChargeSocketDescriptor;
|
||||
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
||||
import app.organicmaps.sdk.bookmarks.data.Metadata;
|
||||
import app.organicmaps.widget.placepage.PlacePageViewModel;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class PlacePageChargeSocketsFragment extends Fragment implements Observer<MapObject>
|
||||
{
|
||||
private GridLayout mGrid;
|
||||
private PlacePageViewModel mViewModel;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
mViewModel = new ViewModelProvider(requireActivity()).get(PlacePageViewModel.class);
|
||||
return inflater.inflate(R.layout.place_page_charge_sockets_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
mGrid = view.findViewById(R.id.socket_grid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart()
|
||||
{
|
||||
super.onStart();
|
||||
mViewModel.getMapObject().observe(requireActivity(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop()
|
||||
{
|
||||
super.onStop();
|
||||
mViewModel.getMapObject().removeObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChanged(@Nullable MapObject mapObject)
|
||||
{
|
||||
if (mapObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mGrid.removeAllViews();
|
||||
|
||||
ChargeSocketDescriptor[] sockets = Framework.nativeGetActiveObjectChargeSockets();
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(requireContext());
|
||||
|
||||
for (ChargeSocketDescriptor socket : sockets)
|
||||
{
|
||||
View itemView = inflater.inflate(R.layout.item_charge_socket, mGrid, false);
|
||||
|
||||
MaterialTextView type = itemView.findViewById(R.id.socket_type);
|
||||
ShapeableImageView icon = itemView.findViewById(R.id.socket_icon);
|
||||
MaterialTextView power = itemView.findViewById(R.id.socket_power);
|
||||
MaterialTextView count = itemView.findViewById(R.id.socket_count);
|
||||
|
||||
// load SVG icon converted into VectorDrawable in res/drawable
|
||||
@SuppressLint("DiscouragedApi")
|
||||
int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.type(), "drawable",
|
||||
requireContext().getPackageName());
|
||||
if (resIconId != 0)
|
||||
{
|
||||
icon.setImageResource(resIconId);
|
||||
}
|
||||
|
||||
@SuppressLint("DiscouragedApi")
|
||||
int resTypeId =
|
||||
getResources().getIdentifier("charge_socket_" + socket.type(), "string", requireContext().getPackageName());
|
||||
if (resTypeId != 0)
|
||||
{
|
||||
type.setText(resTypeId);
|
||||
}
|
||||
|
||||
if (socket.power() != 0)
|
||||
{
|
||||
DecimalFormat df = new DecimalFormat("#.##");
|
||||
power.setText(getString(R.string.kw_label, df.format(socket.power())));
|
||||
}
|
||||
|
||||
if (socket.count() != 0)
|
||||
{
|
||||
count.setText(getString(R.string.count_label, socket.count()));
|
||||
}
|
||||
|
||||
mGrid.addView(itemView);
|
||||
}
|
||||
}
|
||||
}
|
||||
5
android/app/src/main/res/drawable/bg_badge.xml
Normal file
5
android/app/src/main/res/drawable/bg_badge.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="?attr/colorPrimary"/>
|
||||
<corners android:radius="8dp"/>
|
||||
</shape>
|
||||
64
android/app/src/main/res/layout/item_charge_socket.xml
Normal file
64
android/app/src/main/res/layout/item_charge_socket.xml
Normal file
@@ -0,0 +1,64 @@
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
app:cardCornerRadius="12dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp">
|
||||
|
||||
<!-- Top-left badge -->
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/socket_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_badge"
|
||||
android:paddingHorizontal="6dp"
|
||||
android:paddingVertical="2dp"
|
||||
android:text="x ?"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body4"
|
||||
/>
|
||||
|
||||
<!-- Icon -->
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/socket_icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
app:srcCompat="@drawable/ic_charge_socket_unknown"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
/>
|
||||
|
||||
<!-- Socket type -->
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/socket_type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/socket_icon"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/unknown_socket_type"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body5"
|
||||
/>
|
||||
|
||||
<!-- Power -->
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/socket_power"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/socket_type"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/unknown_power_output"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body4"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@@ -0,0 +1,9 @@
|
||||
<GridLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/socket_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:columnCount="3"
|
||||
android:padding="16dp"
|
||||
android:alignmentMode="alignMargins"
|
||||
android:columnOrderPreserved="false" />
|
||||
@@ -16,6 +16,12 @@
|
||||
android:background="?ppBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/place_page_charge_sockets_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:layout="@layout/place_page_charge_sockets_fragment" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/place_page_wikipedia_fragment"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -880,4 +880,11 @@
|
||||
<string name="hours_confirmed_time_ago">Confirmado %s</string>
|
||||
<string name="share_track">Compartir traza</string>
|
||||
<string name="pref_tts_no_system_tts_short">No se ha encontrado ningún motor de texto-a-voz, comprueba la configuración de la aplicación</string>
|
||||
<string name="unknown_power_output">potencia desconocida</string>
|
||||
<string name="charge_socket_type2">Tipo 2 (sin cable)</string>
|
||||
<string name="charge_socket_type2_cable">Tipo 2 (con cable)</string>
|
||||
<string name="charge_socket_type2_combo">Tipo 2 combo</string>
|
||||
<string name="charge_socket_type1">Tipo 1</string>
|
||||
<string name="charge_socket_nacs">NACS</string>
|
||||
<string name="charge_socket_chademo">CHAdeMO</string>
|
||||
</resources>
|
||||
|
||||
@@ -879,4 +879,11 @@
|
||||
<string name="existence_confirmed_time_ago">Existence confirmée %s</string>
|
||||
<string name="hours_confirmed_time_ago">Confirmé %s</string>
|
||||
<string name="pref_tts_no_system_tts_short">Impossible de lire ce texte à voix haute, vérifiez les paramètres de l’application</string>
|
||||
<string name="unknown_power_output">puissance inconnue</string>
|
||||
<string name="charge_socket_type2">Type 2 (sans câble)</string>
|
||||
<string name="charge_socket_type2_cable">Type 2 (avec câble)</string>
|
||||
<string name="charge_socket_type2_combo">Type 2 combo</string>
|
||||
<string name="charge_socket_type1">Type 1</string>
|
||||
<string name="charge_socket_nacs">NACS</string>
|
||||
<string name="charge_socket_chademo">CHAdeMO</string>
|
||||
</resources>
|
||||
|
||||
@@ -98,4 +98,6 @@
|
||||
<string name="vk" translatable="false">VK</string>
|
||||
<string name="lemmy" translatable="false">Lemmy</string>
|
||||
<string name="pixelfed" translatable="false">Pixelfed</string>
|
||||
<string name="count_label" translatable="false">× %d</string>
|
||||
<string name="kw_label" translatable="false">%s kW</string>
|
||||
</resources>
|
||||
|
||||
@@ -915,4 +915,12 @@
|
||||
<string name="share_track">Share Track</string>
|
||||
<string name="delete_track_dialog_title">Delete %s?</string>
|
||||
<string name="pref_tts_no_system_tts_short">No text-to-speech engine found, check the app settings</string>
|
||||
<string name="unknown_power_output">unknown power</string>
|
||||
<string name="charge_socket_type2">Type 2 (no cable)</string>
|
||||
<string name="charge_socket_type2_cable">Type 2 (w/ cable)</string>
|
||||
<string name="charge_socket_type2_combo">Type 2 combo</string>
|
||||
<string name="charge_socket_type1">Type 1</string>
|
||||
<string name="charge_socket_nacs">NACS</string>
|
||||
<string name="charge_socket_chademo">CHAdeMO</string>
|
||||
<string name="unknown_socket_type">unknown socket</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user