18

I want to implement animation like the below image.

I have already used ThreePhaseBottomLibrary and as per my experience animation should go parallel as per above image when I scroll it up!

Below is my Fragment class. It works fine except this Image parallel animation as per the screen:

Myfragment.java

public class MyFragment extends BottomSheetFragment {
private BottomSheetLayout mBottomSheetLayout;
private ImageView mBottomSheetBackgroundImageView;
private int mBottomSheetHeight;
private ImageView movingIconImageView;
private AppBarLayout mAppBarLayout;
private int mMStartMarginBottom;
private int mMStartMarginLeft;
private Toolbar mToolbar;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_my, container, false);
    mBottomSheetHeight = getResources().getDimensionPixelSize(R.dimen.header_height);
    mAppBarLayout = (AppBarLayout) view.findViewById(R.id.appbar);
    view.setMinimumHeight(getResources().getDisplayMetrics().heightPixels);
    CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) view.findViewById(R.id.collapsing_toolbar);
    //collapsingToolbar.setTitle("Title");
    collapsingToolbar.setTitleEnabled(false);
    mToolbar = (Toolbar) view.findViewById(R.id.toolbar);
    //final AppCompatActivity activity = (AppCompatActivity) getActivity();
    //activity.setSupportActionBar(toolbar);
    //final ActionBar actionBar = activity.getSupportActionBar();
    //actionBar.setDisplayHomeAsUpEnabled(true);
    //actionBar.setTitle(null);
    mToolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
    mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mBottomSheetLayout.dismissSheet();
        }
    });
    mToolbar.setAlpha(0);
    mBottomSheetBackgroundImageView = (ImageView) view.findViewById(R.id.backdrop);
    mBottomSheetBackgroundImageView.setAlpha(0.0f);
    movingIconImageView = (ImageView) view.findViewById(R.id.movingIconImageView);
    Glide.with(this).load(R.drawable.cheese_1).centerCrop().into(mBottomSheetBackgroundImageView);
    if (mBottomSheetLayout != null)
        mBottomSheetLayout.setAppBarLayout(mAppBarLayout);
    final int actionBarHeight = getActionBarHeight(getActivity());
    mMStartMarginBottom = getResources().getDimensionPixelSize(R.dimen.header_view_start_margin_bottom);
    mMStartMarginLeft = getResources().getDimensionPixelSize(R.dimen.header_view_start_margin_left);
    movingIconImageView.setPivotX(0);
    final float actionBarIconPadding = getResources().getDimensionPixelSize(R.dimen.action_bar_icon_padding);
    mAppBarLayout.addOnOffsetChangedListener(new OnOffsetChangedListener() {
        float startY = 0;
        float scaleDiff = 0;

        @Override
        public void onOffsetChanged(final AppBarLayout appBarLayout, final int verticalOffset) {
            if (mBottomSheetLayout != null && mBottomSheetLayout.isSheetShowing() && mBottomSheetLayout.getState() == State.EXPANDED) {
                float progress = (float) -verticalOffset / mAppBarLayout.getTotalScrollRange();
                movingIconImageView.setX(mMStartMarginLeft + (progress * (actionBarHeight - mMStartMarginLeft)));
                if (startY == 0)
                    startY = movingIconImageView.getY();
                if (scaleDiff == 0) {
                    scaleDiff = 1 - (actionBarHeight - actionBarIconPadding) / movingIconImageView.getHeight();
                    movingIconImageView.setPivotY(movingIconImageView.getHeight());
                }
                movingIconImageView.setScaleX(1f - progress * scaleDiff);
                movingIconImageView.setScaleY(1f - progress * scaleDiff);
                movingIconImageView.setY(startY - progress * actionBarIconPadding / 2 + mMStartMarginBottom * progress);
            }
        }
    });
    return view;
}

/**
 * returns the height of the action bar
 */
public static int getActionBarHeight(final Context context) {
    // based on http://stackoverflow.com/questions/12301510/how-to-get-the-actionbar-height
    final TypedValue tv = new TypedValue();
    int actionBarHeight = 0;
    if (context.getTheme().resolveAttribute(R.attr.actionBarSize, tv, true))
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources()
                .getDisplayMetrics());
    return actionBarHeight;
}

public void setBottomSheetLayout(final BottomSheetLayout bottomSheetLayout)     {
    mBottomSheetLayout = bottomSheetLayout;
    if (mBottomSheetLayout != null && mAppBarLayout != null)
        mBottomSheetLayout.setAppBarLayout(mAppBarLayout);
    mBottomSheetLayout.addOnSheetStateChangeListener(new OnSheetStateChangeListener() {
        private ViewPropertyAnimator mToolbarAnimation;
        State lastState;

        @Override
        public void onSheetStateChanged(final State state) {
            if (lastState == state)
                return;
            lastState = state;
            if (state != State.EXPANDED) {
                if (mToolbarAnimation != null)
                    mToolbarAnimation.cancel();
                mToolbarAnimation = null;
                mToolbar.setAlpha(0);
                mToolbar.setVisibility(View.INVISIBLE);
            } else if (mToolbarAnimation == null) {
                mToolbar.setVisibility(View.VISIBLE);
                mToolbar.setTranslationY(-mToolbar.getHeight() / 3);
                mToolbarAnimation = mToolbar.animate().setDuration(getResources().getInteger(android.R.integer.config_longAnimTime));
                mToolbarAnimation.alpha(1).translationY(0).start();
            }
        }
    });
}

@Override
public ViewTransformer getViewTransformer() {
    return new BaseViewTransformer() {
        private ViewPropertyAnimator mBottomSheetBackgroundImageViewFadeInAnimation, mBottomSheetBackgroundImageViewFadeOutAnimation;
        private Float mOriginalContactPhotoXCoordinate = null;
        private final float mOriginalBottomSheetBackgroundImageViewTranslationY = mBottomSheetBackgroundImageView.getTranslationY();

        @Override
        public void transformView(final float translation, final float maxTranslation, final float peekedTranslation, final BottomSheetLayout parent, final View view) {
            if (mOriginalContactPhotoXCoordinate == null)
                mOriginalContactPhotoXCoordinate = movingIconImageView.getX();
            if (translation < mBottomSheetHeight)
                return;
            if (translation == mBottomSheetHeight) {
                if (mBottomSheetBackgroundImageViewFadeInAnimation != null)
                    mBottomSheetBackgroundImageViewFadeInAnimation.cancel();
                mBottomSheetBackgroundImageViewFadeInAnimation = null;
                if (mBottomSheetBackgroundImageViewFadeOutAnimation == null)
                    mBottomSheetBackgroundImageViewFadeOutAnimation = mBottomSheetBackgroundImageView.animate().alpha(0);
            } else {
                if (mBottomSheetBackgroundImageViewFadeOutAnimation != null)
                    mBottomSheetBackgroundImageViewFadeOutAnimation.cancel();
                mBottomSheetBackgroundImageViewFadeOutAnimation = null;
                if (mBottomSheetBackgroundImageViewFadeInAnimation == null) {
                    mBottomSheetBackgroundImageViewFadeInAnimation = mBottomSheetBackgroundImageView.animate().alpha(1);
                }
            }
            float progress = (translation - mBottomSheetHeight) / (maxTranslation - mBottomSheetHeight);
            //Log.d("AppLog", "translation:" + translation + " maxTranslation:" + maxTranslation + " progress:" + progress);

            //movingIconImageView.setY(progress * (mBottomSheetHeight - movingIconImageView.getHeight()));
            movingIconImageView.setY(progress * (mBottomSheetHeight - movingIconImageView.getHeight() - mMStartMarginBottom));
            movingIconImageView.setX(mOriginalContactPhotoXCoordinate - progress * (mOriginalContactPhotoXCoordinate - mMStartMarginLeft));
            //mBottomSheetBackgroundImageView.setAlpha(progress);
            mBottomSheetBackgroundImageView.setTranslationY(mOriginalBottomSheetBackgroundImageViewTranslationY - progress * mOriginalBottomSheetBackgroundImageViewTranslationY);

        }
    };
}
}

Here is my xml:-

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="@dimen/header_height"
    android:background="@null">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:expandedTitleMarginEnd="64dp"
        app:expandedTitleMarginStart="48dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="168dp"
            android:layout_marginTop="40dp"
            android:background="#eee">

        </FrameLayout>

        <ImageView
            android:id="@+id/backdrop"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:translationY="40dp"
            app:layout_collapseMode="parallax"/>

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/ToolbarColoredBackArrow"/>

        <ImageView
            android:id="@+id/movingIconImageView"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_gravity="center_horizontal" android:background="#f00"
            android:src="@drawable/test"/>

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

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

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/window_color"
        android:orientation="vertical"
        android:paddingTop="24dp">

        <include layout="@layout/junk_cardview"/>

        <include layout="@layout/junk_cardview"/>

        <include layout="@layout/junk_cardview"/>

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>


<!--<android.support.design.widget.FloatingActionButton-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_margin="@dimen/fab_margin"-->
<!--android:clickable="true"-->
<!--android:src="@android:drawable/ic_menu_send"-->
<!--app:layout_anchor="@id/appbar"-->
<!--app:layout_anchorGravity="bottom|right|end"/>-->

I want my backdrop image to slide up which only fading out with slide!

Note: In the library sample I am getting ImageView alpha from 0 to 1 but I want to slide my imageUp not just animate as like alpha animation!

Ravi
  • 34,851
  • 21
  • 122
  • 183
Hardy
  • 2,576
  • 1
  • 23
  • 45
  • 2
    This question [has been referenced from meta](https://meta.stackoverflow.com/q/312797/3614835). – Jeffrey Bosboom Dec 17 '15 at 23:09
  • @JeffreyBosboom yes i reviewd that but i didn't mean to ask a good question or bad question just this is the site i want to ask my query or question as what site is supposed to be . – Hardy Dec 18 '15 at 05:20
  • 1
    @JeffreyBosboom and also if you cannot answer the question then why people make it negative point to it? i can't understand it – Hardy Dec 18 '15 at 05:22
  • can you post your xml? – Pratik Butani Dec 19 '15 at 13:02
  • @PratikButani have a look – Hardy Dec 19 '15 at 13:24
  • Can you post version of design library? – Pratik Butani Dec 19 '15 at 13:30
  • 1
    hi, @Hardy did you try making the layout which wraps that header image change its position rather than fading in and out, mechanism like that of FAB might help you, some implement hide in show out while other transition is go down and come up from below the screen like google+ app. – mfaisalhyder Aug 10 '16 at 07:39

1 Answers1

4

The image you posted is originally from a post about the design of the Google I/O app in 2014. A corresponding image showed what this motion would actually look like in practice [on the right]:

Material design principles

As stated in the article, the source for this app was made public on GitHub. I suggest you take a look at that code in order to get your answer. Though the source currently available is the 2015 version of the app, not the 2014 version mentioned in the article.

Bryan
  • 14,756
  • 10
  • 70
  • 125