Skip to content

Commit

Permalink
Merge pull request #857 from ZeusWPI/enhance/predictive-back-navigation
Browse files Browse the repository at this point in the history
Support predictive back design
  • Loading branch information
niknetniko committed Nov 30, 2023
2 parents 197f29e + 759bd94 commit e4a3973
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 83 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
android:theme="@style/Hydra.Material"
android:localeConfig="@xml/locales_config"
android:networkSecurityConfig="@xml/network_security_config"
android:enableOnBackInvokedCallback="true"
tools:ignore="AllowBackup,GoogleAppIndexingWarning,UnusedAttribute"
tools:replace="android:supportsRtl">

Expand Down
90 changes: 35 additions & 55 deletions app/src/main/java/be/ugent/zeus/hydra/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.*;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.core.view.GravityCompat;
Expand Down Expand Up @@ -58,14 +59,15 @@
import be.ugent.zeus.hydra.resto.menu.RestoFragment;
import be.ugent.zeus.hydra.schamper.SchamperFragment;
import be.ugent.zeus.hydra.urgent.UrgentFragment;
import be.ugent.zeus.hydra.wpi.EnableManager;
import be.ugent.zeus.hydra.wpi.WpiActivity;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.shape.MaterialShapeDrawable;
import com.google.android.material.tabs.TabLayout;
import be.ugent.zeus.hydra.wpi.EnableManager;
import be.ugent.zeus.hydra.wpi.WpiActivity;
import dev.chrisbanes.insetter.Insetter;
import jonathanfinerty.once.Once;
import org.jetbrains.annotations.NotNull;

import static be.ugent.zeus.hydra.common.utils.FragmentUtils.requireArguments;

Expand Down Expand Up @@ -260,6 +262,37 @@ private void initialize(@Nullable Bundle savedInstanceState) {
// Register the listener for navigation events from the drawer.
binding.navigationView.setNavigationItemSelectedListener(this);

OnBackPressedCallback drawerCloser = new OnBackPressedCallback(false) {

@Override
public void handleOnBackPressed() {
binding.drawerLayout.closeDrawer(GravityCompat.START);
}
};
getOnBackPressedDispatcher().addCallback(this, drawerCloser);

binding.drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(@NonNull @NotNull View drawerView, float slideOffset) {
// Do nothing.
}

@Override
public void onDrawerOpened(@NonNull @NotNull View drawerView) {
drawerCloser.setEnabled(true);
}

@Override
public void onDrawerClosed(@NonNull @NotNull View drawerView) {
drawerCloser.setEnabled(false);
}

@Override
public void onDrawerStateChanged(int newState) {
// Do nothing.
}
});

toggle = new ActionBarDrawerToggle(this, binding.drawerLayout, binding.toolbar, R.string.action_drawer_open, R.string.action_drawer_close) {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
Expand Down Expand Up @@ -498,44 +531,6 @@ private void setFragment(Fragment fragment, MenuItem menuItem, @NavigationSource
binding.progressBar.progressBar.setVisibility(View.GONE);
}

/**
* Implements the correct back-button behaviour for the drawer. If the drawer does not consume the back press,
* the parent method is called.
*/
@Override
public void onBackPressed() {
// If the drawer is open, close it.
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START);
return;
}

// The super method handles both the fragment back stack and finishing the activity. To know what was executed,
// we need to add a listener.
FragmentManager.OnBackStackChangedListener listener = () -> {
Fragment current = getSupportFragmentManager().findFragmentById(R.id.content);
Log.w(TAG, "onBackPressed: current fragment is somehow null? Ignoring update for now.");
if (current == null) {
return;
}
MenuItem item = binding.navigationView.getMenu().findItem(getFragmentMenuId(current));
updateDrawer(current, item);
};

// Allow the current fragment to intercept the back press.
Fragment current = getSupportFragmentManager().findFragmentById(R.id.content);
if (current instanceof OnBackPressed && (((OnBackPressed) current).onBackPressed())) {
// The fragment has handled it.
return;
}

// We need to listen to the back stack to update the drawer.
getSupportFragmentManager().addOnBackStackChangedListener(listener);
super.onBackPressed();
// The drawer has been updated, so we abandon the listener.
getSupportFragmentManager().removeOnBackStackChangedListener(listener);
}

/**
* Set the menu ID as argument for a fragment.
*
Expand Down Expand Up @@ -665,21 +660,6 @@ public interface ScheduledRemovalListener {
void onRemovalScheduled();
}

/**
* Allows fragments to listen to and intercept back button presses.
*/
@FunctionalInterface
public interface OnBackPressed {

/**
* Called when the back button is pressed. This function provides the fragment
* with an opportunity to intercept the back press.
*
* @return True if consumed, false otherwise. Consumed events are not propagated.
*/
boolean onBackPressed();
}

private static final class TutorialEndEvent implements Event {
@Nullable
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
Expand Down Expand Up @@ -68,7 +69,7 @@
* @author ellen
* @author Niko Strijbol
*/
public class EventFragment extends Fragment implements MainActivity.ScheduledRemovalListener, MainActivity.OnBackPressed {
public class EventFragment extends Fragment implements MainActivity.ScheduledRemovalListener {

private static final String TAG = "EventFragment";

Expand Down Expand Up @@ -194,6 +195,30 @@ protected void onSuccess(@NonNull AssociationRequest.EventItemsAndAssociations d
.setOnClickListener(v -> viewModel.onRefresh());
view.<Button>findViewById(R.id.events_no_data_button_filters)
.setOnClickListener(v -> showSheet());

var callback = new OnBackPressedCallback(false) {
@Override
public void handleOnBackPressed() {
hideSheet();
}
};
var behavior = BottomSheetBehavior.from(bottomSheet);
behavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull @NotNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN || newState == BottomSheetBehavior.STATE_COLLAPSED) {
callback.setEnabled(false);
} else if (newState == BottomSheetBehavior.STATE_EXPANDED || newState == BottomSheetBehavior.STATE_HALF_EXPANDED) {
callback.setEnabled(true);
}
}

@Override
public void onSlide(@NonNull @NotNull View bottomSheet, float slideOffset) {
// Do nothing.
}
});
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), callback);
}

private void setupBottomSheet() {
Expand Down Expand Up @@ -262,14 +287,4 @@ private void hideSheet() {
private void showSheet() {
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}

@Override
public boolean onBackPressed() {
if (behavior.getState() != BottomSheetBehavior.STATE_HIDDEN) {
Log.d(TAG, "onBackPressed: hiding sheet");
hideSheet();
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MenuItem;
import androidx.annotation.Nullable;

import java.util.Objects;
Expand All @@ -53,6 +52,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
binding.apiTap.setText(AccountManager.getTapKey(this));
binding.apiUsername.setText(AccountManager.getUsername(this));
binding.doorApiKey.setText(AccountManager.getDoorKey(this));
setResult(RESULT_OK, new Intent());
}

@Override
Expand All @@ -73,22 +73,6 @@ protected void onStop() {
binding.doorApiKey.removeTextChangedListener(this);
}

@Override
public void onBackPressed() {
Intent intent = new Intent();
setResult(RESULT_OK, intent);
super.onBackPressed();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
Intent intent = new Intent();
setResult(RESULT_OK, intent);
}
return super.onOptionsItemSelected(item);
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Do nothing.
Expand Down

0 comments on commit e4a3973

Please sign in to comment.