簡體   English   中英

從添加片段的漢堡包到箭頭圖標過渡動畫

[英]Transition animation from hamburger to arrow icon on adding fragment

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

我使用的代碼如下:

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> 
....    

目前在更改片段后,圖標只是更改,沒有動畫。

先解釋一下。

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

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

  3. DrawerArrowDrawable使用方法setProgress(float progress)實現動畫,其中progress從0(漢堡包)到1(箭頭)。

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

  5. ActionBarDrawerToggle使用public void onDrawerSlide(View drawerView, float slideOffset)來調用private 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();
        }
    }

或者您可以使用DrawerArrowDrawable toolbar.setNavigationIcon()DrawerArrowDrawable設置為導航圖標,並在不使用ActionBarDrawerToggle情況下為其設置動畫。請參閱選項-B: httpsDrawerArrowDrawable

請參閱我的另一個答案以獲取解釋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();
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM