diff options
11 files changed, 73 insertions, 22 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java index 010079744..bc35f5692 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java @@ -11,7 +11,7 @@ import static it.niedermann.nextcloud.deck.DeckApplication.saveCurrentAccount; import static it.niedermann.nextcloud.deck.DeckApplication.saveCurrentBoardId; import static it.niedermann.nextcloud.deck.DeckApplication.saveCurrentStackId; import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.observeOnce; -import static it.niedermann.nextcloud.deck.ui.branding.BrandingUtil.applyBrandToFAB; +import static it.niedermann.nextcloud.deck.ui.branding.BrandingUtil.applyBrandToExtendedFAB; import static it.niedermann.nextcloud.deck.ui.branding.BrandingUtil.applyBrandToPrimaryTabLayout; import static it.niedermann.nextcloud.deck.ui.branding.BrandingUtil.clearBrandColors; import static it.niedermann.nextcloud.deck.ui.branding.BrandingUtil.getSecondaryForegroundColorDependingOnTheme; @@ -28,6 +28,7 @@ import android.animation.AnimatorInflater; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.database.sqlite.SQLiteConstraintException; @@ -370,6 +371,8 @@ public class MainActivity extends AppCompatActivity implements DeleteStackListen binding.listMenuButton.setOnClickListener((v) -> listMenuPopup.show()); binding.fab.setOnClickListener((v) -> { + // TODO We should hide the FAB while the dialog is open - but how to detect the dialog has been closed? + binding.fab.hide(); if (this.boardsList.size() > 0) { try { NewCardDialog.newInstance( @@ -404,7 +407,7 @@ public class MainActivity extends AppCompatActivity implements DeleteStackListen } }); - showFabIfEditPermissionGranted(); + binding.fab.extend(); } @Override @@ -451,7 +454,7 @@ public class MainActivity extends AppCompatActivity implements DeleteStackListen private void applyBoardBranding(@ColorInt int mainColor) { applyBrandToPrimaryTabLayout(mainColor, binding.stackTitles); - applyBrandToFAB(mainColor, binding.fab); + applyBrandToExtendedFAB(mainColor, binding.fab); // TODO We assume, that the background of the spinner is always white binding.swipeRefreshLayout.setColorSchemeColors(contrastRatioIsSufficient(Color.WHITE, mainColor) ? mainColor : DeckApplication.isDarkTheme(this) ? Color.DKGRAY : colorAccent); DrawableCompat.setTint(binding.filterIndicator.getDrawable(), getSecondaryForegroundColorDependingOnTheme(this, mainColor)); @@ -807,6 +810,7 @@ public class MainActivity extends AppCompatActivity implements DeleteStackListen if (mainViewModel.currentBoardHasEditPermission()) { binding.fab.show(); binding.listMenuButton.setVisibility(View.VISIBLE); + binding.emptyContentViewStacks.showDescription(); } else { binding.fab.hide(); binding.listMenuButton.setVisibility(View.GONE); @@ -814,20 +818,19 @@ public class MainActivity extends AppCompatActivity implements DeleteStackListen } } - protected void showFabIfEditPermissionGranted() { - if (mainViewModel.currentBoardHasEditPermission()) { - binding.fab.show(); - } - } - @Override public void onScrollUp() { - showFabIfEditPermissionGranted(); + binding.fab.extend(); } @Override public void onScrollDown() { - binding.fab.hide(); + binding.fab.shrink(); + } + + @Override + public void onBottomReached() { + binding.fab.extend(); } @Override @@ -1048,6 +1051,11 @@ public class MainActivity extends AppCompatActivity implements DeleteStackListen } @Override + public void onDismiss(DialogInterface dialog) { + this.binding.fab.show(); + } + + @Override public void onStackDeleted(long stackLocalId) { int nextStackPosition; try { @@ -1120,7 +1128,7 @@ public class MainActivity extends AppCompatActivity implements DeleteStackListen BrandedSnackbar.make(binding.coordinatorLayout, R.string.synchronization_failed, Snackbar.LENGTH_LONG) .setAction(R.string.simple_more, v -> ExceptionDialogFragment.newInstance(throwable, mainViewModel.getCurrentAccount()).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())) .setAnchorView(binding.fab) - .show(); + .show(); } }); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/branding/BrandingUtil.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/branding/BrandingUtil.java index 3fd5c50e4..ee6a9ccdc 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/branding/BrandingUtil.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/branding/BrandingUtil.java @@ -17,6 +17,7 @@ import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; import androidx.preference.PreferenceManager; +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.tabs.TabLayout; import com.google.android.material.textfield.TextInputLayout; @@ -72,6 +73,16 @@ public abstract class BrandingUtil { fab.setColorFilter(contrastRatioIsSufficient ? ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(mainColor) : mainColor); } + public static void applyBrandToExtendedFAB(@ColorInt int mainColor, @NonNull ExtendedFloatingActionButton extendedFab) { + final boolean contrastRatioIsSufficient = contrastRatioIsSufficientBigAreas(mainColor, ContextCompat.getColor(extendedFab.getContext(), R.color.primary)); + @ColorInt final int color = contrastRatioIsSufficient + ? mainColor + : ContextCompat.getColor(extendedFab.getContext(), R.color.accent); + extendedFab.setTextColor(ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(color)); + extendedFab.setIconTint(ColorStateList.valueOf(ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(color))); + extendedFab.setBackgroundTintList(ColorStateList.valueOf(color)); + } + public static void applyBrandToPrimaryTabLayout(@ColorInt int mainColor, @NonNull TabLayout tabLayout) { @ColorInt final int finalMainColor = getSecondaryForegroundColorDependingOnTheme(tabLayout.getContext(), mainColor); tabLayout.setBackgroundColor(ContextCompat.getColor(tabLayout.getContext(), R.color.primary)); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CreateCardListener.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CreateCardListener.java index 522b7dc60..d8d174251 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CreateCardListener.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CreateCardListener.java @@ -1,11 +1,15 @@ package it.niedermann.nextcloud.deck.ui.card; +import android.content.DialogInterface; + import it.niedermann.nextcloud.deck.model.full.FullCard; -public interface CreateCardListener { +public interface CreateCardListener extends DialogInterface.OnDismissListener { /** * This method is called when a new Card is created + * * @param createdCard The new Card's data */ void onCardCreated(FullCard createdCard); + }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/NewCardDialog.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/NewCardDialog.java index 87361169f..2801c0d7a 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/NewCardDialog.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/NewCardDialog.java @@ -216,6 +216,12 @@ public class NewCardDialog extends DialogFragment implements DialogInterface.OnC } } + @Override + public void onDismiss(@NonNull DialogInterface dialog) { + super.onDismiss(dialog); + this.createCardListener.onDismiss(dialog); + } + private static boolean inputIsValid(@Nullable CharSequence input) { return input != null && !input.toString().trim().isEmpty(); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/OnScrollListener.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/OnScrollListener.java index edfe5e349..ca16d254a 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/OnScrollListener.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/OnScrollListener.java @@ -4,4 +4,6 @@ public interface OnScrollListener { void onScrollUp(); void onScrollDown(); + + void onBottomReached(); }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/StackFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/StackFragment.java index 91b8df21b..c28573289 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/StackFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/StackFragment.java @@ -19,8 +19,10 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.List; import it.niedermann.android.crosstabdnd.DragAndDropTab; +import it.niedermann.android.util.DimensionUtil; import it.niedermann.nextcloud.deck.DeckApplication; import it.niedermann.nextcloud.deck.DeckLog; +import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.api.IResponseCallback; import it.niedermann.nextcloud.deck.databinding.FragmentStackBinding; import it.niedermann.nextcloud.deck.model.Card; @@ -91,16 +93,25 @@ public class StackFragment extends Fragment implements DragAndDropTab<CardAdapte binding.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - if (dy > 0) + if (!recyclerView.canScrollVertically(1)) { + onScrollListener.onBottomReached(); + } else if (dy > 0) { onScrollListener.onScrollDown(); - else if (dy < 0) + } else if (dy < 0) { onScrollListener.onScrollUp(); + } } }); } if (!mainViewModel.currentBoardHasEditPermission()) { binding.emptyContentView.hideDescription(); + binding.recyclerView.setPadding( + binding.recyclerView.getPaddingTop(), + binding.recyclerView.getPaddingEnd(), + DimensionUtil.INSTANCE.dpToPx(requireContext(), R.dimen.spacer_1x), + binding.recyclerView.getPaddingStart() + ); } final Observer<List<FullCard>> cardsObserver = (fullCards) -> activity.runOnUiThread(() -> { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/view/EmptyContentView.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/view/EmptyContentView.java index b103e528a..bd0bb68d9 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/view/EmptyContentView.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/view/EmptyContentView.java @@ -16,7 +16,7 @@ public class EmptyContentView extends RelativeLayout { private static final int NO_DESCRIPTION = -1; - private WidgetEmptyContentViewBinding binding; + private final WidgetEmptyContentViewBinding binding; public EmptyContentView(@NonNull Context context, AttributeSet attrs) { super(context, attrs); @@ -41,4 +41,8 @@ public class EmptyContentView extends RelativeLayout { public void hideDescription() { binding.description.setVisibility(View.GONE); } + + public void showDescription() { + binding.description.setVisibility(View.VISIBLE); + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SelectCardForWidgetActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SelectCardForWidgetActivity.java index c52772361..c664f1441 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SelectCardForWidgetActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SelectCardForWidgetActivity.java @@ -64,7 +64,11 @@ public class SelectCardForWidgetActivity extends MainActivity implements SelectC } @Override - protected void showFabIfEditPermissionGranted() { /* Silence is gold */ } + protected void showEditButtonsIfPermissionsGranted() { + binding.fab.hide(); + binding.listMenuButton.setVisibility(View.GONE); + binding.emptyContentViewStacks.hideDescription(); + } @Override public boolean onCreateOptionsMenu(Menu menu) { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 384cd007f..a02b252ac 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -239,15 +239,14 @@ </com.google.android.material.appbar.AppBarLayout> - <com.google.android.material.floatingactionbutton.FloatingActionButton + <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" - android:contentDescription="@string/add_card" - app:backgroundTint="@color/defaultBrand" - app:srcCompat="@drawable/ic_add_white_24dp" /> + android:text="@string/add_card" + app:icon="@drawable/ic_add_white_24dp" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/app/src/main/res/layout/fragment_stack.xml b/app/src/main/res/layout/fragment_stack.xml index 729b08fe6..481143860 100644 --- a/app/src/main/res/layout/fragment_stack.xml +++ b/app/src/main/res/layout/fragment_stack.xml @@ -26,7 +26,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" - android:paddingVertical="@dimen/spacer_1x" + android:paddingTop="@dimen/spacer_1x" + android:paddingBottom="80dp" android:scrollbarStyle="outsideOverlay" android:scrollbars="vertical" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" diff --git a/fastlane/metadata/android/en-US/changelogs/1021008.txt b/fastlane/metadata/android/en-US/changelogs/1021008.txt index c6edf45e7..8688e7d10 100644 --- a/fastlane/metadata/android/en-US/changelogs/1021008.txt +++ b/fastlane/metadata/android/en-US/changelogs/1021008.txt @@ -1,2 +1,3 @@ - 🐞 Fix invisible description and assignees in boards which are shared read-only (#1401) - 🐞 Creating a card by shortcut does only work for last selected account (#1370) +- ➕ Adjust Floating Action Button behavior to Material 3 (#1419)
\ No newline at end of file |