与 ViewPager Fragments 一起使用时,动画工具栏徽标/标题发生变化

Animate Toolbar Logo / Title changes when using with ViewPager Fragments

我正在使用 ViewPager 在我的主 activity 中托管两个片段。一个片段旨在显示应用程序徽标,而另一个只是工具栏上的标题。我可以毫无问题地做到这一点。

但是,当我使用 ViewPager 上的滑动从一个片段滑动到另一个片段时,我想为这些变化设置动画,例如淡出徽标和淡入标题。

任何线索或想法我该怎么做。

好的,根据 Amir 的建议,我尝试使用以下布局:

    <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="wrap_content"
    android:layout_height="wrap_content">
<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <RelativeLayout
        android:id="@+id/toolbar_logo_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:alpha="1"
        >
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/logo"
        android:id="@+id/toolbar_logo_image"
        android:alpha="1"
       />
    </RelativeLayout>

    <RelativeLayout
        android:layout_toRightOf="@id/toolbar_log_container"
        android:layout_alignWithParentIfMissing="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/toolbar_info_container"
        >
    <ImageView
        android:id="@+id/toolbar_profile_pic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/one"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginRight="@dimen/value_12"
        />

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/toolbar_user_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextInfoName"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/toolbar_profile_pic"
        android:layout_toEndOf="@+id/toolbar_profile_pic"
        android:layout_marginTop="@dimen/value_8"
        />
    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/toolbar_user_detail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextInfoWork"
        android:layout_below="@+id/toolbar_user_name"
        android:layout_toRightOf="@+id/toolbar_profile_pic"
        android:layout_toEndOf="@+id/toolbar_profile_pic"
        android:layout_alignBottom="@id/toolbar_profile_pic"
        />
    </RelativeLayout>

</RelativeLayout>
</android.support.v7.widget.Toolbar>

而且有效!但是,如果我必须根据 ViewPager 的滚动位置执行此操作怎么办?我尝试将动画放在

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

部分代码,但是动画运行不受控,因为每次滚动开始都会调用这个回调,无论是否真正滚动。

对于动画 Toolbar 你应该定义你自己的 Toolbar 类似 this 的东西,对于 Toolbar 的动画元素在你的 MainActivity 你可以使用类似下面的代码:

 getLeftIcon().animate()
                .translationY(0)
                .setDuration(300)
                .setStartDelay(300);
        getAppLogo().animate()
                .translationY(0)
                .setDuration(300)
                .setStartDelay(400);

并且由于 ViewPager 位置而更改标题只需为您的 ViewPager 定义侦听器:

viewPager.setOnPageChangeListener(new OnPageChangeListener() {
    public void onPageScrollStateChanged(int state) {}
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

    public void onPageSelected(int position) {
        // Change your title here 
    }
});

动画部分代码可用here

最后,这是我为达到预期效果所做的工作:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            private float prevPosition = 0.0f;
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                ///hold current position
                if(prevPosition == 0) {
                    prevPosition = positionOffset;
                    return;
                }
                
                ///check if prev position is equal to current one, avoid multiple calls
                if(prevPosition == positionOffset) {
                    return;
                }
                
                /// zero position check
                if(prevPosition >= 0.9) {
                    if(positionOffset == 0.0f) {
                        Logger.log_error("Do not hide infoHolder");
                        return;
                    }
                }
                //update previous position
                prevPosition = positionOffset;
                
                ///animate title text and logoholder accordingly
                logoHolder.animate().translationX(logoHolder.getWidth() -positionOffset * logoHolder.getWidth()) .alpha(positionOffset).setDuration(0).start();
                mTitleText.animate().translationX(- positionOffset * mTitleText.getWidth()).alpha(1.0f - logoHolder.getAlpha()).setDuration(0).start();

            }

            @Override
            public void onPageSelected(int position) {
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
});

当片段在 viewpager 中滚动时,以上代码实现了平滑过渡 b/w 徽标和标题文本。

发布答案希望这对其他人有帮助。

感谢阿米尔的指导。