diff --git a/app/build.gradle b/app/build.gradle index 815d139..95ba6c8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,6 +22,7 @@ android { applicationId "it.danieleverducci.nextcloudmaps" minSdkVersion 23 targetSdkVersion 35 + compileSdk 35 versionCode 9 versionName "0.4.0" diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivity.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivity.java index 49a9b05..d3e73ba 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivity.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivity.java @@ -54,6 +54,7 @@ import it.danieleverducci.nextcloudmaps.R; import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity; import it.danieleverducci.nextcloudmaps.databinding.ActivityGeofavoriteDetailBinding; import it.danieleverducci.nextcloudmaps.model.Geofavorite; +import it.danieleverducci.nextcloudmaps.utils.EdgeToEdgeUtils; import it.danieleverducci.nextcloudmaps.utils.GeoUriParser; import it.danieleverducci.nextcloudmaps.utils.IntentGenerator; import it.danieleverducci.nextcloudmaps.utils.MapUtils; @@ -76,6 +77,7 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple mViewHolder = new ViewHolder(getLayoutInflater()); setContentView(mViewHolder.getRootView()); + EdgeToEdgeUtils.clearTopBarWithPadding(mViewHolder.binding.appbar); mViewHolder.setOnSubmitListener(new OnSubmitListener() { @Override public void onBackPressed() { diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/GeofavoriteAdapter.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/GeofavoriteAdapter.java index a2121f1..70a1a3a 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/GeofavoriteAdapter.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/GeofavoriteAdapter.java @@ -61,6 +61,9 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter items = new ArrayList<>(); private int sortRule = SORT_BY_CREATED; + private int bottomInset = 0; + private int leftInset = 0; + private int rightInset = 0; // Contains the position of the element containing the overflow menu clicked private int overflowMenuSelectedPosition = -1; @@ -110,6 +113,14 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter openFab(!this.isFabOpen)); - - fab = findViewById(R.id.add_from_gps); - fab.setOnClickListener(view -> addGeofavoriteFromGps()); - - fab = findViewById(R.id.add_from_map); - fab.setOnClickListener(view -> addGeofavoriteFromMap()); - + setupFAB(); setupNavigationMenu(); drawerLayout = findViewById(R.id.drawerLayout); @@ -150,7 +146,32 @@ public class MainActivity extends NextcloudMapsStyledActivity { transaction.commit(); } + private void setupFAB() { + // Register listeners + FloatingActionButton fab = findViewById(R.id.open_fab); + fab.setOnClickListener(view -> openFab(!this.isFabOpen)); + + fab = findViewById(R.id.add_from_gps); + fab.setOnClickListener(view -> addGeofavoriteFromGps()); + + fab = findViewById(R.id.add_from_map); + fab.setOnClickListener(view -> addGeofavoriteFromMap()); + + // Clear system bars (in edge to edge mode) + EdgeToEdgeUtils.clearBottomBarWithMargin(findViewById(R.id.fab_container)); + } + private void setupNavigationMenu() { + //EdgeToEdgeUtils.clearTopBarWithPadding(findViewById(R.id.header_view)); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.drawerLayout), (v, windowInsets) -> { + Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); + View hv = findViewById(R.id.header_view); + hv.setPadding(insets.left, insets.top, insets.right, hv.getPaddingBottom()); + + //return WindowInsetsCompat.CONSUMED; + return windowInsets; + }); + ArrayList navItems = new ArrayList<>(); navigationCommonAdapter = new NavigationAdapter(this, item -> { diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoriteListFragment.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoriteListFragment.java index f149cff..6db5281 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoriteListFragment.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoriteListFragment.java @@ -13,6 +13,9 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatImageView; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import androidx.fragment.app.FragmentTransaction; import androidx.lifecycle.Observer; import androidx.recyclerview.widget.LinearLayoutManager; @@ -27,6 +30,7 @@ import it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter; import it.danieleverducci.nextcloudmaps.activity.main.MainActivity; import it.danieleverducci.nextcloudmaps.activity.main.SortingOrderDialogFragment; import it.danieleverducci.nextcloudmaps.model.Geofavorite; +import it.danieleverducci.nextcloudmaps.utils.EdgeToEdgeUtils; import it.danieleverducci.nextcloudmaps.utils.GeofavoritesFilter; import it.danieleverducci.nextcloudmaps.utils.SettingsManager; @@ -97,6 +101,17 @@ public class GeofavoriteListFragment extends GeofavoritesFragment implements Sor View showMapButton = v.findViewById(R.id.view_mode_map); showMapButton.setOnClickListener(View -> ((MainActivity)requireActivity()).showMap()); + // Clear top bar in edge to edge and notify the adapter about the system bar size to avoid the system bar covering the last row + ViewCompat.setOnApplyWindowInsetsListener(v.findViewById(R.id.activity_list_view), (rv, windowInsets) -> { + Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); + rv.setPadding(rv.getPaddingLeft(), insets.top, rv.getPaddingRight(), rv.getPaddingBottom()); + geofavoriteAdapter.setBottomInset(insets.bottom); + geofavoriteAdapter.setLeftInset(insets.left); + geofavoriteAdapter.setRightInset(insets.right); + //return WindowInsetsCompat.CONSUMED; + return windowInsets; + }); + return v; } diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoriteMapFragment.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoriteMapFragment.java index 5e3f315..29da306 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoriteMapFragment.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoriteMapFragment.java @@ -8,7 +8,6 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -17,7 +16,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.app.ActivityCompat; -import androidx.core.content.res.ResourcesCompat; import androidx.core.graphics.drawable.DrawableCompat; import androidx.lifecycle.Observer; @@ -34,13 +32,12 @@ import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider; import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay; import java.util.List; -import java.util.Set; import it.danieleverducci.nextcloudmaps.R; import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivity; import it.danieleverducci.nextcloudmaps.activity.main.MainActivity; -import it.danieleverducci.nextcloudmaps.activity.mappicker.MapPickerActivity; import it.danieleverducci.nextcloudmaps.model.Geofavorite; +import it.danieleverducci.nextcloudmaps.utils.EdgeToEdgeUtils; import it.danieleverducci.nextcloudmaps.utils.GeoUriParser; import it.danieleverducci.nextcloudmaps.utils.MapUtils; import it.danieleverducci.nextcloudmaps.utils.SettingsManager; @@ -64,7 +61,11 @@ public class GeofavoriteMapFragment extends GeofavoritesFragment implements Main View v = inflater.inflate(R.layout.fragment_geofavorite_map, container, false); // Register listeners - v.findViewById(R.id.center_position).setOnClickListener((cpv) -> moveToUserPosition()); + View centerPositionFab = v.findViewById(R.id.center_position); + centerPositionFab.setOnClickListener((cpv) -> moveToUserPosition()); + + // Clear bottom bar in edge to edge + EdgeToEdgeUtils.clearBottomBarWithMargin(v.findViewById(R.id.center_position_container)); // Setup map map = v.findViewById(R.id.map); diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoritesFragment.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoritesFragment.java index 1663cdb..0b41c09 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoritesFragment.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/fragments/GeofavoritesFragment.java @@ -38,6 +38,7 @@ import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivit import it.danieleverducci.nextcloudmaps.activity.main.GeofavoritesFragmentViewModel; import it.danieleverducci.nextcloudmaps.activity.main.MainActivity; import it.danieleverducci.nextcloudmaps.model.Geofavorite; +import it.danieleverducci.nextcloudmaps.utils.EdgeToEdgeUtils; import it.danieleverducci.nextcloudmaps.utils.GeofavoritesFilter; import it.danieleverducci.nextcloudmaps.utils.IntentGenerator; @@ -86,6 +87,8 @@ public abstract class GeofavoritesFragment extends Fragment { userBadgeContainer.setOnClickListener(v -> showSwitchAccountDialog()); // Setup toolbar/searchbar + View toolbarContainer = view.findViewById(R.id.toolbar_container); + EdgeToEdgeUtils.clearTopBarWithMargin(toolbarContainer); toolbar = view.findViewById(R.id.toolbar); homeToolbar = view.findViewById(R.id.home_toolbar); filterButton = view.findViewById(R.id.search_filter); diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/utils/EdgeToEdgeUtils.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/utils/EdgeToEdgeUtils.java new file mode 100644 index 0000000..6f3a4de --- /dev/null +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/utils/EdgeToEdgeUtils.java @@ -0,0 +1,62 @@ +package it.danieleverducci.nextcloudmaps.utils; + +import android.view.View; +import android.view.ViewGroup; + +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; + +public class EdgeToEdgeUtils { + + /** + * Clears the system bars in edge to edge mode (https://developer.android.com/develop/ui/views/layout/edge-to-edge) + * @param viewToClear the view to clear from system bars + */ + public static void clearBottomBarWithMargin(View viewToClear) { + ViewCompat.setOnApplyWindowInsetsListener(viewToClear, (v, windowInsets) -> { + Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); + ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) v.getLayoutParams(); + mlp.bottomMargin = insets.bottom; + mlp.leftMargin = insets.left; + mlp.rightMargin = insets.right; + v.setLayoutParams(mlp); + + //return WindowInsetsCompat.CONSUMED; + return windowInsets; + }); + } + + /** + * Clears the system bars in edge to edge mode (https://developer.android.com/develop/ui/views/layout/edge-to-edge) + * @param viewToClear the view to clear from system bars + */ + public static void clearTopBarWithMargin(View viewToClear) { + ViewCompat.setOnApplyWindowInsetsListener(viewToClear, (v, windowInsets) -> { + Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); + ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) v.getLayoutParams(); + mlp.topMargin = insets.top; + mlp.leftMargin = insets.left; + mlp.rightMargin = insets.right; + v.setLayoutParams(mlp); + + //return WindowInsetsCompat.CONSUMED; + return windowInsets; + }); + } + + /** + * Clears the system bars in edge to edge mode (https://developer.android.com/develop/ui/views/layout/edge-to-edge) + * @param viewToClear the view to clear from system bars + */ + public static void clearTopBarWithPadding(View viewToClear) { + ViewCompat.setOnApplyWindowInsetsListener(viewToClear, (v, windowInsets) -> { + Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(insets.left, insets.top, insets.right, v.getPaddingBottom()); + + //return WindowInsetsCompat.CONSUMED; + return windowInsets; + }); + } + +} diff --git a/app/src/main/res/layout/activity_geofavorite_detail.xml b/app/src/main/res/layout/activity_geofavorite_detail.xml index 4d10f5f..0c38e17 100644 --- a/app/src/main/res/layout/activity_geofavorite_detail.xml +++ b/app/src/main/res/layout/activity_geofavorite_detail.xml @@ -10,14 +10,12 @@ + android:layout_height="250dp"> - - + android:layout_height="match_parent" + android:layout_gravity="bottom|end"> - - + + - - + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 236f9f5..296aebb 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -35,8 +35,7 @@ + android:layout_gravity="start"> - - - - - + android:gravity="center_vertical"> + + + + + + + + diff --git a/app/src/main/res/layout/fragment_geofavorite_list.xml b/app/src/main/res/layout/fragment_geofavorite_list.xml index 412f866..208bd73 100644 --- a/app/src/main/res/layout/fragment_geofavorite_list.xml +++ b/app/src/main/res/layout/fragment_geofavorite_list.xml @@ -17,7 +17,6 @@ diff --git a/app/src/main/res/layout/fragment_geofavorite_map.xml b/app/src/main/res/layout/fragment_geofavorite_map.xml index df9c542..3e2ec86 100644 --- a/app/src/main/res/layout/fragment_geofavorite_map.xml +++ b/app/src/main/res/layout/fragment_geofavorite_map.xml @@ -53,17 +53,24 @@ - + android:layout_gravity="bottom|right"> + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_geofav.xml b/app/src/main/res/layout/item_geofav.xml index 0e9e5c2..4c2bb5b 100644 --- a/app/src/main/res/layout/item_geofav.xml +++ b/app/src/main/res/layout/item_geofav.xml @@ -22,7 +22,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="horizontal" android:layout_width="match_parent" - android:layout_height="90dp" + android:layout_height="wrap_content" android:gravity="center_vertical" android:clickable="true" android:focusable="true"> @@ -32,6 +32,8 @@ android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="4dp" + android:layout_marginTop="14dp" + android:layout_marginBottom="14dp" android:layout_weight="0" android:background="@drawable/ic_list_pin" android:gravity="top|center"