WIP Update to Android 15: edge to edge fixes

This commit is contained in:
Daniele Verducci 2024-10-01 08:58:47 +02:00
parent a0978d8a54
commit f70fa7163f
15 changed files with 243 additions and 93 deletions

View File

@ -22,6 +22,7 @@ android {
applicationId "it.danieleverducci.nextcloudmaps"
minSdkVersion 23
targetSdkVersion 35
compileSdk 35
versionCode 9
versionName "0.4.0"

View File

@ -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() {

View File

@ -61,6 +61,9 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
private List<Geofavorite> 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<GeofavoriteAdapter.
holder.tv_title.setText(Html.fromHtml(geofavorite.getName() == null ? "" : geofavorite.getName()));
holder.tv_content.setText(geofavorite.getComment() == null ? "" : geofavorite.getComment());
holder.tv_date.setText(geofavorite.getLocalDateCreated().format(dateFormatter));
// Last item: Clear bottom system bar
holder.root_view.setPadding(
leftInset,
holder.root_view.getPaddingTop(),
rightInset,
position == getItemCount() - 1 ? bottomInset : 0
);
}
@Override
@ -117,7 +128,20 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
return items.size();
}
public void setBottomInset(int inset) {
this.bottomInset = inset;
}
public void setLeftInset(int inset) {
this.leftInset = inset;
}
public void setRightInset(int inset) {
this.rightInset = inset;
}
class GeofavoriteViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
View root_view;
TextView tv_category, tv_title, tv_content, tv_date;
ImageView bt_context_menu;
ImageView bt_nav;
@ -128,6 +152,7 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
GeofavoriteViewHolder(@NonNull View itemView, ItemClickListener itemClickListener) {
super(itemView);
root_view = itemView;
tv_category = itemView.findViewById(R.id.tv_category);
tv_title = itemView.findViewById(R.id.title);
tv_content = itemView.findViewById(R.id.content);

View File

@ -25,7 +25,10 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.GravityCompat;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
@ -48,6 +51,7 @@ import it.danieleverducci.nextcloudmaps.api.ApiProvider;
import it.danieleverducci.nextcloudmaps.fragments.GeofavoriteListFragment;
import it.danieleverducci.nextcloudmaps.fragments.GeofavoriteMapFragment;
import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository;
import it.danieleverducci.nextcloudmaps.utils.EdgeToEdgeUtils;
import it.danieleverducci.nextcloudmaps.utils.SettingsManager;
public class MainActivity extends NextcloudMapsStyledActivity {
@ -123,15 +127,7 @@ public class MainActivity extends NextcloudMapsStyledActivity {
else
showList();
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());
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<NavigationItem> navItems = new ArrayList<>();
navigationCommonAdapter = new NavigationAdapter(this, item -> {

View File

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

View File

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

View File

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

View File

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

View File

@ -10,14 +10,12 @@
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="250dp"
android:fitsSystemWindows="true">
android:layout_height="250dp">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="@color/defaultBrand"
app:layout_scrollFlags="scroll|snap|exitUntilCollapsed"
app:title="@string/new_geobookmark"

View File

@ -30,12 +30,18 @@
tools:layout="@layout/fragment_geofavorite_list" />
<FrameLayout
android:id="@+id/fab_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="bottom|end">
<!-- Add from map FAB -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_from_map"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_gravity="bottom"
android:layout_margin="24dp"
android:src="@drawable/ic_add_map"
app:backgroundTint="@color/defaultBrand"
@ -70,3 +76,5 @@
android:contentDescription="@string/open_fab"/>
</FrameLayout>
</FrameLayout>

View File

@ -35,8 +35,7 @@
<com.google.android.material.navigation.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
android:layout_gravity="start">
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
@ -49,17 +48,21 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
<FrameLayout
android:id="@+id/header_view"
android:layout_width="match_parent"
android:layout_height="@dimen/drawer_header_height"
android:layout_height="wrap_content"
android:background="@color/defaultBrand">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/logo"
android:layout_width="@dimen/drawer_header_logo_size"
android:layout_height="@dimen/drawer_header_logo_size"
android:layout_centerVertical="true"
android:layout_margin="@dimen/spacer_2x"
android:gravity="center"
android:src="@drawable/ic_app" />
@ -68,18 +71,20 @@
android:id="@+id/app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/logo"
android:ellipsize="end"
android:lines="2"
android:fontFamily="sans-serif-light"
android:gravity="center_vertical"
android:text="@string/app_name"
android:textColor="@android:color/white"
android:textSize="24sp"
android:layout_toRightOf="@id/logo" />
</RelativeLayout>
android:textSize="24sp"/>
</LinearLayout>
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/navigationCommon"

View File

@ -3,6 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">

View File

@ -17,7 +17,6 @@
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?android:attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:toolbarId="@+id/toolbar" >

View File

@ -53,17 +53,24 @@
</androidx.appcompat.widget.LinearLayoutCompat>
<FrameLayout
android:id="@+id/center_position_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="100dp"
android:layout_gravity="bottom|right">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/center_position"
android:layout_width="@dimen/floating_bar_height"
android:layout_height="@dimen/floating_bar_height"
android:layout_marginRight="100dp"
android:layout_marginBottom="25dp"
android:layout_gravity="bottom|right"
android:background="@drawable/unselected_floating_semitransparent_button_background"
android:padding="5dp"
android:tint="@color/text_color"
android:src="@drawable/ic_add_gps"
android:visibility="gone"/>
android:visibility="visible"/>
</FrameLayout>
</FrameLayout>

View File

@ -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"