2016-04-14 1 views
3

アップルのナビゲーションにハンバーガーを実装するソリューションを見てきました。そして私はDrawerLayoutが使われているところを見ただけです。Gmailのようなアップボタンからハンバーガーへのアニメーション化の方法

今は活動AとB

活動Aは、ランチャーの活動であるが、それはアクションバーでハンバーガーのアイコンを持っており、それがDreawerLayout内外にスライドアップボタン/ハンバーガーのアニメーションを実装しています。

どこかアクティビティAにおいて、活性B.アクティビティBはsupport.v7アクションバーを有し、

ActionBar actionBar = getSupportActionBar(); 
     actionBar.setDisplayHomeAsUpEnabled(true); 

onCreateで呼び出され起動ボタンがあります。これにより、アップボタンが設定され、アクティビティAに戻ります。

アクティビティAのハンバーグにアニメーションを付けるには、アクティビティBのアップボタンをどのように設定しますか?

Gmailはこれを行います:完全な電子メールの上のボタンをクリックすると、電子メールのリストに移動します。

+0

これは機能しませんでした。 – X09

+0

テーマはどのアクティビティに設定しますか? – X09

+0

よろしくお願いします。 – X09

答えて

0

ご質問が正しく理解されている場合: できません。 hamburgermenuとback arrowの間のアニメーションは、ナビゲーションドロワに固有です。アクティビティを切り替えるときは、アクションバー上のものをアニメーション化することはできません。

+0

Gmailアプリはどのように機能しますか? Gmailの受信トレイに移動し、メールをクリックして、上のボタンを押します。あなたは何を見たの? – X09

+1

彼はそうです。私が知る限り、ハンバーガーメニューをアニメートして、さまざまなアクティビティに切り替えることはできません。あなたができることは、同じ活動にとどまって、さまざまな断片を切り換えることです。 –

2

これは説明に時間がかかります。簡単に言えば、それを操作するにはDrawerToogleへの参照を取得する必要があります。どうやって? ActionBarDrawerToggleクラスの独自の実装を提供する必要があります。

は、ここ(Googleの独自の実装からのコピー&ペーストの多い)例

package com.example.navigationdrawertest; 

import android.app.Activity; 
import android.content.Context; 
import android.content.res.Configuration; 
import android.graphics.drawable.Drawable; 
import android.support.annotation.Nullable; 
import android.support.annotation.StringRes; 
import android.support.v4.view.GravityCompat; 
import android.support.v4.widget.DrawerLayout; 
import android.support.v7.graphics.drawable.DrawerArrowDrawable; 
import android.support.v7.widget.Toolbar; 
import android.util.Log; 
import android.view.MenuItem; 
import android.view.View; 

/** 
* This class provides a handy way to tie together the functionality of 
* {@link android.support.v4.widget.DrawerLayout} and the framework <code>ActionBar</code> to 
* implement the recommended design for navigation drawers. 
* 
* <p>To use <code>ActionBarDrawerToggle</code>, create one in your Activity and call through 
* to the following methods corresponding to your Activity callbacks:</p> 
* 
* <ul> 
* <li>{@link android.app.Activity#onConfigurationChanged(android.content.res.Configuration) 
* onConfigurationChanged} 
* <li>{@link android.app.Activity#onOptionsItemSelected(android.view.MenuItem) 
* onOptionsItemSelected}</li> 
* </ul> 
* 
* <p>Call {@link #syncState()} from your <code>Activity</code>'s 
* {@link android.app.Activity#onPostCreate(android.os.Bundle) onPostCreate} to synchronize the 
* indicator with the state of the linked DrawerLayout after <code>onRestoreInstanceState</code> 
* has occurred.</p> 
* 
* <p><code>ActionBarDrawerToggle</code> can be used directly as a 
* {@link android.support.v4.widget.DrawerLayout.DrawerListener}, or if you are already providing 
* your own listener, call through to each of the listener methods from your own.</p> 
* 
* <p> 
* You can customize the the animated toggle by defining the 
* {@link android.support.v7.appcompat.R.styleable#DrawerArrowToggle drawerArrowStyle} in your 
* ActionBar theme. 
*/ 
public class ActionBarDrawerToggle implements DrawerLayout.DrawerListener { 

    /** 
    * Allows an implementing Activity to return an {@link ActionBarDrawerToggle.Delegate} to use 
    * with ActionBarDrawerToggle. 
    */ 
    public interface DelegateProvider { 

     /** 
     * @return Delegate to use for ActionBarDrawableToggles, or null if the Activity 
     * does not wish to override the default behavior. 
     */ 
     @Nullable 
     Delegate getDrawerToggleDelegate(); 
    } 

    public interface Delegate { 

     /** 
     * Set the Action Bar's up indicator drawable and content description. 
     * 
     * @param upDrawable  - Drawable to set as up indicator 
     * @param contentDescRes - Content description to set 
     */ 
     void setActionBarUpIndicator(Drawable upDrawable, @StringRes int contentDescRes); 

     /** 
     * Set the Action Bar's up indicator content description. 
     * 
     * @param contentDescRes - Content description to set 
     */ 
     void setActionBarDescription(@StringRes int contentDescRes); 

     /** 
     * Returns the drawable to be set as up button when DrawerToggle is disabled 
     */ 
     Drawable getThemeUpIndicator(); 

     /** 
     * Returns the context of ActionBar 
     */ 
     Context getActionBarThemedContext(); 

     /** 
     * Returns whether navigation icon is visible or not. 
     * Used to print warning messages in case developer forgets to set displayHomeAsUp to true 
     */ 
     boolean isNavigationVisible(); 
    } 

    private final Delegate mActivityImpl; 
    private final DrawerLayout mDrawerLayout; 

    private DrawerToggle mSlider; 
    private Drawable mHomeAsUpIndicator; 
    private boolean mDrawerIndicatorEnabled = true; 
    private boolean mHasCustomUpIndicator; 
    private final int mOpenDrawerContentDescRes; 
    private final int mCloseDrawerContentDescRes; 
    // used in toolbar mode when DrawerToggle is disabled 
    private View.OnClickListener mToolbarNavigationClickListener; 
    // If developer does not set displayHomeAsUp, DrawerToggle won't show up. 
    // DrawerToggle logs a warning if this case is detected 
    private boolean mWarnedForDisplayHomeAsUp = false; 

    /** 
    * Construct a new ActionBarDrawerToggle with a Toolbar. 
    * <p> 
    * The given {@link Activity} will be linked to the specified {@link DrawerLayout} and 
    * the Toolbar's navigation icon will be set to a custom drawable. Using this constructor 
    * will set Toolbar's navigation click listener to toggle the drawer when it is clicked. 
    * <p> 
    * This drawable shows a Hamburger icon when drawer is closed and an arrow when drawer 
    * is open. It animates between these two states as the drawer opens. 
    * <p> 
    * String resources must be provided to describe the open/close drawer actions for 
    * accessibility services. 
    * 
    * @param activity     The Activity hosting the drawer. 
    * @param toolbar     The toolbar to use if you have an independent Toolbar. 
    * @param drawerLayout    The DrawerLayout to link to the given Activity's ActionBar 
    * @param openDrawerContentDescRes A String resource to describe the "open drawer" action 
    *         for accessibility 
    * @param closeDrawerContentDescRes A String resource to describe the "close drawer" action 
    *         for accessibility 
    */ 
    public ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, 
           Toolbar toolbar, @StringRes int openDrawerContentDescRes, 
           @StringRes int closeDrawerContentDescRes) { 
     this(activity, toolbar, drawerLayout, null, openDrawerContentDescRes, 
       closeDrawerContentDescRes); 
    } 

    /** 
    * In the future, we can make this constructor public if we want to let developers customize 
    * the animation. 
    */ 
    <T extends Drawable & DrawerToggle> ActionBarDrawerToggle(Activity activity, Toolbar toolbar, 
                   DrawerLayout drawerLayout, T slider, 
                   @StringRes int openDrawerContentDescRes, 
                   @StringRes int closeDrawerContentDescRes) { 
     mActivityImpl = new ToolbarCompatDelegate(toolbar); 
     toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (mDrawerIndicatorEnabled) { 
        toggle(); 
       } else if (mToolbarNavigationClickListener != null) { 
        mToolbarNavigationClickListener.onClick(v); 
       } 
      } 
     }); 

     mDrawerLayout = drawerLayout; 
     mOpenDrawerContentDescRes = openDrawerContentDescRes; 
     mCloseDrawerContentDescRes = closeDrawerContentDescRes; 
     if (slider == null) { 
      mSlider = new DrawerArrowDrawableToggle(activity, 
        mActivityImpl.getActionBarThemedContext()); 
     } else { 
      mSlider = slider; 
     } 

     mHomeAsUpIndicator = getThemeUpIndicator(); 
    } 

    /** 
    * Synchronize the state of the drawer indicator/affordance with the linked DrawerLayout. 
    * 
    * <p>This should be called from your <code>Activity</code>'s 
    * {@link Activity#onPostCreate(android.os.Bundle) onPostCreate} method to synchronize after 
    * the DrawerLayout's instance state has been restored, and any other time when the state 
    * may have diverged in such a way that the ActionBarDrawerToggle was not notified. 
    * (For example, if you stop forwarding appropriate drawer events for a period of time.)</p> 
    */ 
    public void syncState() { 
     if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) { 
      mSlider.setPosition(1); 
     } else { 
      mSlider.setPosition(0); 
     } 
     if (mDrawerIndicatorEnabled) { 
      setActionBarUpIndicator((Drawable) mSlider, 
        mDrawerLayout.isDrawerOpen(GravityCompat.START) ? 
          mCloseDrawerContentDescRes : mOpenDrawerContentDescRes); 
     } 
    } 

    /** 
    * This method should always be called by your <code>Activity</code>'s 
    * {@link Activity#onConfigurationChanged(android.content.res.Configuration) 
    * onConfigurationChanged} 
    * method. 
    * 
    * @param newConfig The new configuration 
    */ 
    public void onConfigurationChanged(Configuration newConfig) { 
     // Reload drawables that can change with configuration 
     if (!mHasCustomUpIndicator) { 
      mHomeAsUpIndicator = getThemeUpIndicator(); 
     } 
     syncState(); 
    } 

    /** 
    * This method should be called by your <code>Activity</code>'s 
    * {@link Activity#onOptionsItemSelected(android.view.MenuItem) onOptionsItemSelected} method. 
    * If it returns true, your <code>onOptionsItemSelected</code> method should return true and 
    * skip further processing. 
    * 
    * @param item the MenuItem instance representing the selected menu item 
    * @return true if the event was handled and further processing should not occur 
    */ 
    public boolean onOptionsItemSelected(MenuItem item) { 
     if (item != null && item.getItemId() == android.R.id.home && mDrawerIndicatorEnabled) { 
      toggle(); 
      return true; 
     } 
     return false; 
    } 

    private void toggle() { 
     int drawerLockMode = mDrawerLayout.getDrawerLockMode(GravityCompat.START); 
     if (mDrawerLayout.isDrawerVisible(GravityCompat.START) 
       && (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_OPEN)) { 
      mDrawerLayout.closeDrawer(GravityCompat.START); 
     } else if (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_CLOSED) { 
      mDrawerLayout.openDrawer(GravityCompat.START); 
     } 
    } 

    /** 
    * Set the up indicator to display when the drawer indicator is not 
    * enabled. 
    * <p> 
    * If you pass <code>null</code> to this method, the default drawable from 
    * the theme will be used. 
    * 
    * @param indicator A drawable to use for the up indicator, or null to use 
    *     the theme's default 
    * @see #setDrawerIndicatorEnabled(boolean) 
    */ 
    public void setHomeAsUpIndicator(Drawable indicator) { 
     if (indicator == null) { 
      mHomeAsUpIndicator = getThemeUpIndicator(); 
      mHasCustomUpIndicator = false; 
     } else { 
      mHomeAsUpIndicator = indicator; 
      mHasCustomUpIndicator = true; 
     } 

     if (!mDrawerIndicatorEnabled) { 
      setActionBarUpIndicator(mHomeAsUpIndicator, 0); 
     } 
    } 

    /** 
    * Set the up indicator to display when the drawer indicator is not 
    * enabled. 
    * <p> 
    * If you pass 0 to this method, the default drawable from the theme will 
    * be used. 
    * 
    * @param resId Resource ID of a drawable to use for the up indicator, or 0 
    *    to use the theme's default 
    * @see #setDrawerIndicatorEnabled(boolean) 
    */ 
    public void setHomeAsUpIndicator(int resId) { 
     Drawable indicator = null; 
     if (resId != 0) { 
      indicator = mDrawerLayout.getResources().getDrawable(resId); 
     } 
     setHomeAsUpIndicator(indicator); 
    } 

    /** 
    * @return true if the enhanced drawer indicator is enabled, false otherwise 
    * @see #setDrawerIndicatorEnabled(boolean) 
    */ 
    public boolean isDrawerIndicatorEnabled() { 
     return mDrawerIndicatorEnabled; 
    } 

    /** 
    * Enable or disable the drawer indicator. The indicator defaults to enabled. 
    * 
    * <p>When the indicator is disabled, the <code>ActionBar</code> will revert to displaying 
    * the home-as-up indicator provided by the <code>Activity</code>'s theme in the 
    * <code>android.R.attr.homeAsUpIndicator</code> attribute instead of the animated 
    * drawer glyph.</p> 
    * 
    * @param enable true to enable, false to disable 
    */ 
    public void setDrawerIndicatorEnabled(boolean enable) { 
     if (enable != mDrawerIndicatorEnabled) { 
      if (enable) { 
       setActionBarUpIndicator((Drawable) mSlider, 
         mDrawerLayout.isDrawerOpen(GravityCompat.START) ? 
           mCloseDrawerContentDescRes : mOpenDrawerContentDescRes); 
      } else { 
       setActionBarUpIndicator(mHomeAsUpIndicator, 0); 
      } 
      mDrawerIndicatorEnabled = enable; 
     } 
    } 

    public DrawerToggle getSlider() { 
     return mSlider; 
    } 

    /** 
    * {@link DrawerLayout.DrawerListener} callback method. If you do not use your 
    * ActionBarDrawerToggle instance directly as your DrawerLayout's listener, you should call 
    * through to this method from your own listener object. 
    * 
    * @param drawerView The child view that was moved 
    * @param slideOffset The new offset of this drawer within its range, from 0-1 
    */ 
    @Override 
    public void onDrawerSlide(View drawerView, float slideOffset) { 
     mSlider.setPosition(Math.min(1f, Math.max(0, slideOffset))); 
    } 

    /** 
    * {@link DrawerLayout.DrawerListener} callback method. If you do not use your 
    * ActionBarDrawerToggle instance directly as your DrawerLayout's listener, you should call 
    * through to this method from your own listener object. 
    * 
    * @param drawerView Drawer view that is now open 
    */ 
    @Override 
    public void onDrawerOpened(View drawerView) { 
     mSlider.setPosition(1); 
     if (mDrawerIndicatorEnabled) { 
      setActionBarDescription(mCloseDrawerContentDescRes); 
     } 
    } 

    /** 
    * {@link DrawerLayout.DrawerListener} callback method. If you do not use your 
    * ActionBarDrawerToggle instance directly as your DrawerLayout's listener, you should call 
    * through to this method from your own listener object. 
    * 
    * @param drawerView Drawer view that is now closed 
    */ 
    @Override 
    public void onDrawerClosed(View drawerView) { 
     mSlider.setPosition(0); 
     if (mDrawerIndicatorEnabled) { 
      setActionBarDescription(mOpenDrawerContentDescRes); 
     } 
    } 

    /** 
    * {@link DrawerLayout.DrawerListener} callback method. If you do not use your 
    * ActionBarDrawerToggle instance directly as your DrawerLayout's listener, you should call 
    * through to this method from your own listener object. 
    * 
    * @param newState The new drawer motion state 
    */ 
    @Override 
    public void onDrawerStateChanged(int newState) { 
    } 

    /** 
    * Returns the fallback listener for Navigation icon click events. 
    * 
    * @return The click listener which receives Navigation click events from Toolbar when 
    * drawer indicator is disabled. 
    * @see #setToolbarNavigationClickListener(android.view.View.OnClickListener) 
    * @see #setDrawerIndicatorEnabled(boolean) 
    * @see #isDrawerIndicatorEnabled() 
    */ 
    public View.OnClickListener getToolbarNavigationClickListener() { 
     return mToolbarNavigationClickListener; 
    } 

    /** 
    * When DrawerToggle is constructed with a Toolbar, it sets the click listener on 
    * the Navigation icon. If you want to listen for clicks on the Navigation icon when 
    * DrawerToggle is disabled ({@link #setDrawerIndicatorEnabled(boolean)}, you should call this 
    * method with your listener and DrawerToggle will forward click events to that listener 
    * when drawer indicator is disabled. 
    * 
    * @see #setDrawerIndicatorEnabled(boolean) 
    */ 
    public void setToolbarNavigationClickListener(
      View.OnClickListener onToolbarNavigationClickListener) { 
     mToolbarNavigationClickListener = onToolbarNavigationClickListener; 
    } 

    void setActionBarUpIndicator(Drawable upDrawable, int contentDescRes) { 
     if (!mWarnedForDisplayHomeAsUp && !mActivityImpl.isNavigationVisible()) { 
      Log.w("ActionBarDrawerToggle", "DrawerToggle may not show up because NavigationIcon" 
        + " is not visible. You may need to call " 
        + "actionbar.setDisplayHomeAsUpEnabled(true);"); 
      mWarnedForDisplayHomeAsUp = true; 
     } 
     mActivityImpl.setActionBarUpIndicator(upDrawable, contentDescRes); 
    } 

    void setActionBarDescription(int contentDescRes) { 
     mActivityImpl.setActionBarDescription(contentDescRes); 
    } 

    Drawable getThemeUpIndicator() { 
     return mActivityImpl.getThemeUpIndicator(); 
    } 

    static class DrawerArrowDrawableToggle extends DrawerArrowDrawable implements DrawerToggle { 
     private final Activity mActivity; 

     public DrawerArrowDrawableToggle(Activity activity, Context themedContext) { 
      super(themedContext); 
      mActivity = activity; 
     } 

     public void setPosition(float position) { 
      if (position == 1f) { 
       setVerticalMirror(true); 
      } else if (position == 0f) { 
       setVerticalMirror(false); 
      } 
      setProgress(position); 
     } 

     public float getPosition() { 
      return getProgress(); 
     } 
    } 

    /** 
    * Interface for toggle drawables. Can be public in the future 
    */ 
    public interface DrawerToggle { 

     public void setPosition(float position); 

     public float getPosition(); 
    } 

    /** 
    * Used when DrawerToggle is initialized with a Toolbar 
    */ 
    static class ToolbarCompatDelegate implements Delegate { 

     final Toolbar mToolbar; 
     final Drawable mDefaultUpIndicator; 
     final CharSequence mDefaultContentDescription; 

     ToolbarCompatDelegate(Toolbar toolbar) { 
      mToolbar = toolbar; 
      mDefaultUpIndicator = toolbar.getNavigationIcon(); 
      mDefaultContentDescription = toolbar.getNavigationContentDescription(); 
     } 

     @Override 
     public void setActionBarUpIndicator(Drawable upDrawable, @StringRes int contentDescRes) { 
      mToolbar.setNavigationIcon(upDrawable); 
      setActionBarDescription(contentDescRes); 
     } 

     @Override 
     public void setActionBarDescription(@StringRes int contentDescRes) { 
      if (contentDescRes == 0) { 
       mToolbar.setNavigationContentDescription(mDefaultContentDescription); 
      } else { 
       mToolbar.setNavigationContentDescription(contentDescRes); 
      } 
     } 

     @Override 
     public Drawable getThemeUpIndicator() { 
      return mDefaultUpIndicator; 
     } 

     @Override 
     public Context getActionBarThemedContext() { 
      return mToolbar.getContext(); 
     } 

     @Override 
     public boolean isNavigationVisible() { 
      return true; 
     } 
    } 
} 

この方法だ、あなたはactionBarDrawerToggle.getSlider()を呼び出すことによってDrawerToogleへの参照を取得し、drawerToogle.setPosition(some_float_between_0_and_1)を呼び出すことにより、状態をアニメーション化することができます。

私のGithubリポジトリをチェックしてください。here

+0

これはうまくいきます!彼らがこれを簡単に成し遂げたり、ActionBarDrawerToggle.DrawerToogleを一般公開しない理由を不思議に思う – marchinram

関連する問題