[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:
Séverin Lemaignan
2025-09-11 22:43:19 +02:00
committed by x7z4w
parent 431852f8cc
commit a74ae0fa3a
28 changed files with 729 additions and 1 deletions

View File

@@ -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();
}

View File

@@ -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);
}
}
}