2016-07-12 78 views
3

我已經實現了主/細節流程,並且我想在添加片段(與打開導航抽屜時的動畫相同)後,從漢堡包圖標到箭頭圖標的過渡動畫。從漢堡包過渡到添加片段的箭頭圖標

我使用的代碼象下面這樣:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_home); 

    toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 
    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 

    drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
    toggle = new ActionBarDrawerToggle(this, drawer, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 
    drawer.setDrawerListener(toggle); 
    toggle.setDrawerIndicatorEnabled(true); 
    toggle.syncState(); 

    //Add home page fragment 
    FragmentManager fragmentManager = getFragmentManager(); 
    HabitHomeFragment homePageFragment = new HabitHomeFragment(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    fragmentTransaction.replace(R.id.habit_home, homePageFragment); 
    fragmentTransaction.commit();} 

雖然增加細節片段:

public void showDetails() { 
     toggle.setDrawerIndicatorEnabled(false); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     fragmentTransaction.replace(R.id.habit_home, habitDetailsFragment).addToBackStack("detail").commit();} 

和工具欄:

<android.support.design.widget.AppBarLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:theme="@style/AppTheme.AppBarOverlay"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     android:background="?attr/colorPrimary" 
     app:popupTheme="@style/AppTheme.PopupOverlay" /> 

</android.support.design.widget.AppBarLayout> 
....  

目前改變片段後,圖標只是改變,沒有動畫。

+0

你有沒有找到解決方案? – Questioner

+0

我還沒找到解決這個問題的辦法。 – user1030150

+0

@Questioner,我找到了兩個解決方案。查看答案。 – babay

回答

4

先解釋一下。

  1. android.support.v7.app.ActionBarDrawerToggle對漢堡包到箭頭的圖標和動畫使用特殊的可繪製類。

  2. 類是android.support.v7.graphics.drawable.DrawerArrowDrawable

  3. DrawerArrowDrawable實現與方法setProgress(float progress),其中進展是從0(漢堡包)動畫爲1(箭頭)。

  4. ActionBarDrawerToggle使用private void setPosition(float position)調用DrawerArrowDrawable.setProgress()

  5. ActionBarDrawerToggle使用public void onDrawerSlide(View drawerView, float slideOffset)調用私有setPosition()

  6. ActionBarDrawerToggle電話toolbar.setNavigationOnClickListener()在構造函數與它的監聽器,用來切換抽屜。

  7. ActionBarDrawerToggle記錄實際的DrawerArrowDrawable狀態。 ToolbarActionBar不會跟蹤實際的DrawerArrowDrawable狀態。

所以,你應該在活動中做什麼。選項-A,使用ActionBarDrawerToggle。

// define a variable to track hamburger-arrow state 
    protected boolean isHomeAsUp = false; 

    protected DrawerLayout drawer; 
    protected Toolbar toolbar; 
    protected ActionBarDrawerToggle toggle; 

    // I've implemented it in setContentView(), but you can implement it in onCreate() 
    @Override 
    public void setContentView(@LayoutRes int layoutResID) { 
     super.setContentView(layoutResID); 

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

     drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
     toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close); 
     drawer.addDrawerListener(toggle); 
     toggle.syncState(); 

     // overwrite Navigation OnClickListener that is set by ActionBarDrawerToggle 
     toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (drawer.isDrawerOpen(GravityCompat.START)){ 
        drawer.closeDrawer(GravityCompat.START); 
       } else if (isHomeAsUp){ 
        onBackPressed(); 
       } else { 
        drawer.openDrawer(GravityCompat.START); 
       } 
      } 
     }); 
    } 

    // call this method for animation between hamburged and arrow 
    protected void setHomeAsUp(boolean isHomeAsUp){ 
     if (this.isHomeAsUp != isHomeAsUp) { 
      this.isHomeAsUp = isHomeAsUp; 

      ValueAnimator anim = isHomeAsUp ? ValueAnimator.ofFloat(0, 1) : ValueAnimator.ofFloat(1, 0); 
      anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
       @Override 
       public void onAnimationUpdate(ValueAnimator valueAnimator) { 
        float slideOffset = (Float) valueAnimator.getAnimatedValue(); 
        toggle.onDrawerSlide(drawer, slideOffset); 
       } 
      }); 
      anim.setInterpolator(new DecelerateInterpolator()); 
      // You can change this duration to more closely match that of the default animation. 
      anim.setDuration(400); 
      anim.start(); 
     } 
    } 

或者你可以設置一個DrawerArrowDrawabletoolbar.setNavigationIcon()導航圖標和動畫它沒有ActionBarDrawerToggle 見選項-B:https://stackoverflow.com/a/42024138/1148784

3

見我的另一個答案的解釋https://stackoverflow.com/a/42023946/1148784。這是選項-B。代碼爲Activity類。這裏我們不使用ActionBarDrawerToggle

protected boolean isHomeAsUp = false; 
    DrawerArrowDrawable homeDrawable; 
    protected Toolbar toolbar; 
    protected DrawerLayout drawer; 

    @Override 
    public void setContentView(@LayoutRes int layoutResID) { 
     super.setContentView(layoutResID); 

     toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 

     homeDrawable = new DrawerArrowDrawable(toolbar.getContext()); 
     toolbar.setNavigationIcon(homeDrawable); 

     toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (drawer.isDrawerOpen(GravityCompat.START)){ 
        drawer.closeDrawer(GravityCompat.START); 
       } else if (isHomeAsUp){ 
        onBackPressed(); 
       } else { 
        drawer.openDrawer(GravityCompat.START); 
       } 
      } 
     }); 
    } 

    protected void setHomeAsUp(boolean isHomeAsUp){ 
     if (this.isHomeAsUp != isHomeAsUp) { 
      this.isHomeAsUp = isHomeAsUp; 
      ValueAnimator anim = isHomeAsUp ? ValueAnimator.ofFloat(0, 1) : ValueAnimator.ofFloat(1, 0); 
      anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
       @Override 
       public void onAnimationUpdate(ValueAnimator valueAnimator) { 
        float slideOffset = (Float) valueAnimator.getAnimatedValue(); 
        homeDrawable.setProgress(slideOffset); 
       } 
      }); 
      anim.setInterpolator(new DecelerateInterpolator()); 
      anim.setDuration(400); 
      anim.start(); 
     } 
    } 
相關問題