Skip to content

Instantly share code, notes, and snippets.

@josefernand
Created August 19, 2018 13:33
Show Gist options
  • Save josefernand/b5ea3555f77ab20644f0bc7da751c6ac to your computer and use it in GitHub Desktop.
Save josefernand/b5ea3555f77ab20644f0bc7da751c6ac to your computer and use it in GitHub Desktop.
Android Navigation multiple start destinations. Java version based on Sam Clarke's workaround https://www.samclarke.com/android-navigation-component-multiple-start-destinations/
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.graphics.drawable.DrawerArrowDrawable;
import android.text.TextUtils;
import android.view.Gravity;
import java.util.List;
import androidx.navigation.NavController;
import androidx.navigation.NavDestination;
public class MultiStartNavigationUI {
public MultiStartNavigationUI() {
}
public static void setupActionBarWithNavController(@NonNull AppCompatActivity activity,
@NonNull NavController navController,
@NonNull List<Integer> startDestinations,
@Nullable DrawerLayout drawerLayout) {
navController.addOnNavigatedListener(new ActionBarOnNavigatedListener(
activity, startDestinations, drawerLayout));
}
public static boolean navigateUp(@Nullable DrawerLayout drawerLayout,
@NonNull NavController navController,
@NonNull List<Integer> startDestinations) {
if (drawerLayout != null && startDestinations.contains(navController.getCurrentDestination().getId())) {
drawerLayout.openDrawer(Gravity.START);
return true;
} else {
return navController.navigateUp();
}
}
public static boolean onBackPressed(@NonNull AppCompatActivity activity,
@NonNull NavController navController,
@NonNull List<Integer> startDestinations) {
if (startDestinations.contains(navController.getCurrentDestination().getId())) {
ActivityCompat.finishAfterTransition(activity);
return true;
}
return false;
}
private static class ActionBarOnNavigatedListener implements NavController.OnNavigatedListener {
private final AppCompatActivity mActivity;
@Nullable
private final DrawerLayout mDrawerLayout;
private DrawerArrowDrawable mArrowDrawable;
private ValueAnimator mAnimator;
private List<Integer> mStartDestinations;
ActionBarOnNavigatedListener(@NonNull AppCompatActivity activity,
@NonNull List<Integer> startDestinations,
@Nullable DrawerLayout drawerLayout) {
mActivity = activity;
mDrawerLayout = drawerLayout;
mStartDestinations= startDestinations;
}
@Override
public void onNavigated(@NonNull NavController controller,
@NonNull NavDestination destination) {
ActionBar actionBar = mActivity.getSupportActionBar();
CharSequence title = destination.getLabel();
if (!TextUtils.isEmpty(title)) {
actionBar.setTitle(title);
}
boolean isStartDestination = mStartDestinations.contains(destination.getId());
actionBar.setDisplayHomeAsUpEnabled(mDrawerLayout != null || !isStartDestination);
setActionBarUpIndicator(mDrawerLayout != null && isStartDestination);
}
void setActionBarUpIndicator(boolean showAsDrawerIndicator) {
ActionBarDrawerToggle.Delegate delegate = mActivity.getDrawerToggleDelegate();
boolean animate = true;
if (mArrowDrawable == null) {
mArrowDrawable = new DrawerArrowDrawable(
delegate.getActionBarThemedContext());
delegate.setActionBarUpIndicator(mArrowDrawable, 0);
// We're setting the initial state, so skip the animation
animate = false;
}
float endValue = showAsDrawerIndicator ? 0f : 1f;
if (animate) {
float startValue = mArrowDrawable.getProgress();
if (mAnimator != null) {
mAnimator.cancel();
}
mAnimator = ObjectAnimator.ofFloat(mArrowDrawable, "progress",
startValue, endValue);
mAnimator.start();
} else {
mArrowDrawable.setProgress(endValue);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment