Skip to content

Commit

Permalink
[Predictive Back] Update side container back helper to support contai…
Browse files Browse the repository at this point in the history
…ners with arbitrary child views

PiperOrigin-RevId: 525466973
  • Loading branch information
dsn5ft authored and drchen committed Apr 19, 2023
1 parent 5da4c02 commit 9405121
Show file tree
Hide file tree
Showing 8 changed files with 491 additions and 49 deletions.
4 changes: 4 additions & 0 deletions catalog/java/io/material/catalog/AndroidManifest.xml
Expand Up @@ -51,6 +51,10 @@
android:name=".navigationdrawer.NavigationDrawerDemoActivity"
android:exported="true"
android:label="@string/cat_navigationdrawer_title" />
<activity
android:name=".navigationdrawer.CustomNavigationDrawerDemoActivity"
android:exported="true"
android:label="@string/cat_navigationdrawer_custom_title" />
<activity
android:name=".topappbar.TopAppBarActionBarDemoActivity"
android:exported="true"
Expand Down
@@ -0,0 +1,169 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.material.catalog.navigationdrawer;

import io.material.catalog.R;

import android.animation.Animator.AnimatorListener;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.window.BackEvent;
import android.window.OnBackAnimationCallback;
import android.window.OnBackInvokedDispatcher;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.os.BuildCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.drawerlayout.widget.DrawerLayout.LayoutParams;
import androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListener;
import com.google.android.material.motion.MaterialSideContainerBackHelper;
import com.google.android.material.navigation.DrawerLayoutUtils;
import io.material.catalog.feature.DemoActivity;

/** A fragment that displays a custom Navigation Drawer demo for the Catalog app. */
@SuppressWarnings("RestrictTo")
public class CustomNavigationDrawerDemoActivity extends DemoActivity {

@RequiresApi(VERSION_CODES.UPSIDE_DOWN_CAKE)
private final OnBackAnimationCallback drawerOnBackAnimationCallback =
new OnBackAnimationCallback() {
@Override
public void onBackStarted(@NonNull BackEvent backEvent) {
sideContainerBackHelper.startBackProgress(backEvent);
}

@Override
public void onBackProgressed(@NonNull BackEvent backEvent) {
DrawerLayout.LayoutParams drawerLayoutParams =
(LayoutParams) currentDrawerView.getLayoutParams();
sideContainerBackHelper.updateBackProgress(backEvent, drawerLayoutParams.gravity);
}

@Override
public void onBackInvoked() {
BackEvent backEvent = sideContainerBackHelper.onHandleBackInvoked();
if (backEvent == null) {
drawerLayout.closeDrawers();
return;
}

DrawerLayout.LayoutParams drawerLayoutParams =
(LayoutParams) currentDrawerView.getLayoutParams();
int gravity = drawerLayoutParams.gravity;
AnimatorListener scrimCloseAnimatorListener =
DrawerLayoutUtils.getScrimCloseAnimatorListener(drawerLayout, currentDrawerView);
AnimatorUpdateListener scrimCloseAnimatorUpdateListener =
DrawerLayoutUtils.getScrimCloseAnimatorUpdateListener(drawerLayout);

sideContainerBackHelper.finishBackProgress(
backEvent, gravity, scrimCloseAnimatorListener, scrimCloseAnimatorUpdateListener);
}

@Override
public void onBackCancelled() {
sideContainerBackHelper.cancelBackProgress();
}
};

private final OnBackPressedCallback drawerOnBackPressedCallback =
new OnBackPressedCallback(/* enabled= */ true) {
@Override
public void handleOnBackPressed() {
drawerLayout.closeDrawers();
}
};

private DrawerLayout drawerLayout;
private View currentDrawerView;
private MaterialSideContainerBackHelper sideContainerBackHelper;

@NonNull
@Override
public View onCreateDemoView(
@NonNull LayoutInflater layoutInflater,
@Nullable ViewGroup viewGroup,
@Nullable Bundle bundle) {
View view =
layoutInflater.inflate(
R.layout.cat_navigationdrawer_custom, viewGroup, false /* attachToRoot */);

Toolbar toolbar = view.findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

drawerLayout = view.findViewById(R.id.drawer);
drawerLayout.addDrawerListener(
new ActionBarDrawerToggle(
this,
drawerLayout,
toolbar,
R.string.cat_navigationdrawer_button_show_content_description,
R.string.cat_navigationdrawer_button_hide_content_description));
drawerLayout.addDrawerListener(
new SimpleDrawerListener() {
@Override
public void onDrawerOpened(@NonNull View drawerView) {
currentDrawerView = drawerView;
sideContainerBackHelper = new MaterialSideContainerBackHelper(drawerView);

if (BuildCompat.isAtLeastU()) {
drawerLayout.post(
() ->
getOnBackInvokedDispatcher()
.registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_OVERLAY,
drawerOnBackAnimationCallback));
} else {
getOnBackPressedDispatcher()
.addCallback(
CustomNavigationDrawerDemoActivity.this, drawerOnBackPressedCallback);
}
}

@Override
public void onDrawerClosed(@NonNull View drawerView) {
currentDrawerView = null;
sideContainerBackHelper = null;

if (BuildCompat.isAtLeastU()) {
getOnBackInvokedDispatcher()
.unregisterOnBackInvokedCallback(drawerOnBackAnimationCallback);
} else {
drawerOnBackPressedCallback.remove();
}
}
});

View endDrawer = view.findViewById(R.id.custom_drawer_end);
view.findViewById(R.id.show_end_drawer_gravity)
.setOnClickListener(v -> drawerLayout.openDrawer(endDrawer));

return view;
}

@Override
protected boolean shouldShowDefaultDemoActionBar() {
return false;
}
}
Expand Up @@ -29,6 +29,8 @@
import io.material.catalog.feature.Demo;
import io.material.catalog.feature.DemoLandingFragment;
import io.material.catalog.feature.FeatureDemo;
import java.util.Arrays;
import java.util.List;

/** A landing fragment that links to navigation drawer demos for the Catalog app. */
public class NavigationDrawerFragment extends DemoLandingFragment {
Expand All @@ -54,6 +56,17 @@ public Intent createActivityIntent() {
};
}

@NonNull
@Override
public List<Demo> getAdditionalDemos() {
return Arrays.asList(new Demo(R.string.cat_navigationdrawer_custom_title) {
@Override
public Intent createActivityIntent() {
return new Intent(requireContext(), CustomNavigationDrawerDemoActivity.class);
}
});
}

/** The Dagger module for {@link NavigationDrawerFragment} dependencies. */
@dagger.Module
public abstract static class Module {
Expand Down

0 comments on commit 9405121

Please sign in to comment.