I am trying to put some animation in my application. Please find the photo attached to get animation idea.
I have used CoordinatorLayout. My search layout and toolbar is hosted inside AppBarLayout/CollapsingToolbarLayout. Below that is my NestedScrollView hosting fragment.
I am able to hide search layout when user scrolls using scroll flags. I am trying to implement a CoordinatorLayout.Behavior which will start moving the cart icon to the left and start search icon to scale from 0 to 1; as soon as the user scrolls and search layout starts to hide. When search layout is fully hidden, I want to show toolbar like in second screen. And it will come back to original state as shown in first screen when user scrolls down and search layout starts to show up by slowly moving cart to right and scaling down search icon.
Initially I have made the search icon on toolbar as hidden and cart icon & search icon are inside a linearlayout.
Please find my xml activity_home_page.xml
<?xml version="1.0" encoding="utf-8"?>
<com.example.ui.customviews.CustomDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/ab_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="131dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<LinearLayout
android:id="@+id/ll_search_layout"
android:layout_width="match_parent"
android:layout_height="75dp"
android:layout_gravity="bottom"
android:orientation="vertical"
android:visibility="visible"
app:layout_scrollFlags="scroll|snap">
<LinearLayout
android:id="@+id/ll_search_box"
android:layout_width="match_parent"
android:layout_height="51dp"
android:layout_marginBottom="@dimen/dimen_12_dp"
android:layout_marginLeft="@dimen/dimen_8_dp"
android:layout_marginRight="@dimen/dimen_8_dp"
android:layout_marginTop="@dimen/dimen_12_dp"
android:background="@drawable/round_corner_layout_white"
android:elevation="@dimen/dimen_5_dp"
android:focusableInTouchMode="true"
android:orientation="horizontal">
<EditText
android:id="@+id/et_search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dimen_15_dp"
android:layout_weight="80"
android:background="@android:color/transparent"
android:hint="Search for Products"
android:padding="@dimen/dimen_5_dp"
android:textColor="@color/black"
android:textColorHint="@color/hint_text_color"
android:textSize="@dimen/dimen_text_16_sp" />
<ImageView
android:id="@+id/iv_search_icon"
android:layout_width="@dimen/dimen_22_dp"
android:layout_height="@dimen/dimen_24_dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dimen_17_dp"
android:layout_marginRight="@dimen/dimen_20_dp"
android:src="@drawable/ic_search_grey" />
</LinearLayout>
</LinearLayout>
<include
layout="@layout/layout_primary_toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_primary_height"
android:layout_gravity="top"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/askme_blue"
app:layout_behavior="com.GetIt.animation.SearchLayoutBehavior"/>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
<fragment
android:id="@+id/navigation_drawer"
android:name="com.example.ui.fragment.SideMenuFragment"
android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start" />
</com.example.ui.customviews.CustomDrawerLayout>
My xml for layout_primary_toolbar.xml is
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_primary_height"
android:background="@color/askme_blue"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<LinearLayout
android:id="@+id/layout_toolbar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_drawer_menu"
android:layout_width="@dimen/dimen_22_dp"
android:layout_height="@dimen/dimen_22_dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dimen_16_dp"
android:layout_marginRight="@dimen/dimen_15_dp"
android:src="@drawable/ic_drawer_menu" />
<ImageView
android:id="@+id/iv_back_btn"
android:layout_width="@dimen/dimen_22_dp"
android:layout_height="@dimen/dimen_20_dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dimen_16_dp"
android:layout_marginRight="@dimen/dimen_15_dp"
android:src="@drawable/ic_back_button"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/ll_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<com.GetIt.ui.customviews.TextViewRRegular
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delhi"
android:textColor="@color/white"
android:textSize="20sp"
android:visibility="visible" />
<ImageView
android:id="@+id/toolbar_location_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="2dp"
android:layout_marginTop="2dp"
android:src="@drawable/ic_edit_location"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="right"
android:gravity="right"
android:layout_marginRight="@dimen/dimen_16_dp">
<RelativeLayout
android:id="@+id/rl_cart_count"
android:layout_width="@dimen/dimen_40_dp"
android:layout_height="@dimen/dimen_40_dp"
android:layout_centerVertical="true">
<ImageView
android:layout_width="@dimen/dimen_25_dp"
android:layout_height="@dimen/dimen_24_dp"
android:layout_centerInParent="true"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:scaleType="center"
android:src="@drawable/ic_cart" />
<TextView
android:id="@+id/tv_cart_count"
android:layout_width="@dimen/dimen_17_dp"
android:layout_height="@dimen/dimen_17_dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="@dimen/dimen_3_dp"
android:layout_marginTop="@dimen/dimen_3_dp"
android:background="@drawable/cart_count_background_circle"
android:elevation="@dimen/dimen_5_dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/dimen_text_10_sp"
android:textStyle="bold"
android:visibility="visible" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_search"
android:layout_width="@dimen/dimen_40_dp"
android:layout_height="@dimen/dimen_40_dp"
android:layout_centerVertical="true"
android:layout_marginLeft="14dp"
android:layout_toRightOf="@+id/rl_cart_count">
<ImageView
android:id="@+id/iv_search"
android:layout_width="@dimen/dimen_24_dp"
android:layout_height="@dimen/dimen_24_dp"
android:layout_centerInParent="true"
android:src="@drawable/ic_search" />
</RelativeLayout>
</RelativeLayout>
</android.support.v7.widget.Toolbar>
I am stuck on this for last 7 hours. I am new to android animation.
Initially I am hiding rl_search (search box) programmatically. I want that when ll_search_layout scrolls up (beneath the toolbar), rl_cart should move to left (which is its original position had rl_search not been made hidden) and rl_search should scale from 0 to 1.
I have used ObjectAnimator with LinearInterpolator but its not working at all.
Any suggestions how to achieve this?
P.S. - I can post the code if you guys need that for reference.
Thanks
You can use the view animation system to perform tweened animation on Views. Tween animation calculates the animation with information such as the start point, end point, size, rotation, and other common aspects of an animation.
AppBarLayout is a vertical LinearLayout which implements many of the features of material designs app bar concept, namely scrolling gestures. Children should provide their desired scrolling behavior through AppBarLayout.
After trying myself for over 2 days, finally I am able to do the animation. I am posting this answer for others if they also wants to do something like that.
I have not used animation utility of android but a hack to increase and decrease padding and scaling up and down the search icon.
This is my behaviour class
public class SearchLayoutBehavior extends CoordinatorLayout.Behavior<ImageView> {
Context mContext;
private static final int DIRECTION_UP = 1;
private static final int DIRECTION_DOWN = -1;
private static final int CART_PADDING_LOWER_LIMIT = 0;
private static int CART_PADDING_UPPER_LIMIT;
private static final float SEARCH_SCALING_LOWER_LIMIT = 0.0f;
private static final float SEARCH_SCALING_UPPER_LIMIT = 1.0f;
private float CART_PADDING_MULTIPLICATION_FACTOR;
private float SEARCH_SCALE_MULTIPLICATION_FACTOR;
RelativeLayout mRlSearch, mRlParentCart;
Toolbar mToolbar;
LinearLayout mLlSearchLayout;
boolean mIsSetupDone = false;
int mScrollingDirection, mPrevDiff1, mPrevDiff2;
public SearchLayoutBehavior() {
super();
}
public SearchLayoutBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, ImageView child, View dependency) {
return (dependency.getId() == R.id.ab_app_bar);
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, ImageView child, View dependency) {
mRlParentCart = (RelativeLayout) dependency.findViewById(R.id.rl_parent_cart_count);
mRlSearch = (RelativeLayout) dependency.findViewById(R.id.rl_search);
mToolbar = (Toolbar) dependency.findViewById(R.id.toolbar);
mLlSearchLayout = (LinearLayout) dependency.findViewById(R.id.ll_search_layout);
int searchLayoutBottom = mLlSearchLayout.getBottom();
int searchLayoutTop = mLlSearchLayout.getTop();
int toolbarBottom = mToolbar.getBottom();
int diff1 = searchLayoutBottom - toolbarBottom;
int diff2 = searchLayoutTop - toolbarBottom;
if (!mIsSetupDone) {
CART_PADDING_UPPER_LIMIT = mContext.getResources().getDimensionPixelSize(R.dimen.cart_animation_move_left);
CART_PADDING_MULTIPLICATION_FACTOR = (float) CART_PADDING_UPPER_LIMIT / diff1;
SEARCH_SCALE_MULTIPLICATION_FACTOR = (float) 1 / diff1;
mPrevDiff1 = diff1;
mPrevDiff2 = -diff1;
mIsSetupDone = true;
}
if (mScrollingDirection == DIRECTION_UP && mPrevDiff1 >= diff1) {
moveCart(mRlParentCart, mPrevDiff1 - diff1, true);
mPrevDiff1 = diff1;
} else if (mScrollingDirection == DIRECTION_DOWN && mPrevDiff2 <= diff2) {
moveCart(mRlParentCart, diff2 - mPrevDiff2, false);
mPrevDiff2 = diff2;
}
if (diff2 == 0) {
mPrevDiff1 = diff1;
mPrevDiff2 = -diff1;
}
return true;
}
private void moveCart(final View view, float by, boolean doMoveLeft) {
int paddingRight = view.getPaddingRight();
float scaleX = mRlSearch.getScaleX();
float scaleY = mRlSearch.getScaleY();
if (doMoveLeft) {
paddingRight += (int) (by * CART_PADDING_MULTIPLICATION_FACTOR);
if (paddingRight >= CART_PADDING_UPPER_LIMIT) {
view.setPadding(0, 0, CART_PADDING_UPPER_LIMIT, 0);
} else {
view.setPadding(0, 0, paddingRight, 0);
}
scaleX += by * SEARCH_SCALE_MULTIPLICATION_FACTOR;
scaleY += by * SEARCH_SCALE_MULTIPLICATION_FACTOR;
if (Float.compare(scaleX, SEARCH_SCALING_UPPER_LIMIT) >= 0) {
mRlSearch.setScaleX(SEARCH_SCALING_UPPER_LIMIT);
} else {
mRlSearch.setScaleX(scaleX);
}
if (Float.compare(scaleY, SEARCH_SCALING_UPPER_LIMIT) >= 0) {
mRlSearch.setScaleY(SEARCH_SCALING_UPPER_LIMIT);
} else {
mRlSearch.setScaleY(scaleY);
}
} else {
paddingRight -= (int) (by * CART_PADDING_MULTIPLICATION_FACTOR);
if (paddingRight <= CART_PADDING_LOWER_LIMIT) {
view.setPadding(0, 0, CART_PADDING_LOWER_LIMIT, 0);
} else {
view.setPadding(0, 0, paddingRight, 0);
}
scaleX -= by * SEARCH_SCALE_MULTIPLICATION_FACTOR;
scaleY -= by * SEARCH_SCALE_MULTIPLICATION_FACTOR;
if (Float.compare(scaleX, SEARCH_SCALING_LOWER_LIMIT) == -1) {
mRlSearch.setScaleX(SEARCH_SCALING_LOWER_LIMIT);
} else {
mRlSearch.setScaleX(scaleX);
}
if (Float.compare(scaleY, SEARCH_SCALING_LOWER_LIMIT) == -1) {
mRlSearch.setScaleY(SEARCH_SCALING_LOWER_LIMIT);
} else {
mRlSearch.setScaleY(scaleY);
}
}
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, ImageView child, View target, int dx, int dy, int[] consumed) {
//Determine direction changes here
if (dy > 0 && mScrollingDirection != DIRECTION_UP) {
mScrollingDirection = DIRECTION_UP;
} else if (dy < 0 && mScrollingDirection != DIRECTION_DOWN) {
mScrollingDirection = DIRECTION_DOWN;
}
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, ImageView child, View directTargetChild, View target, int nestedScrollAxes) {
return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
}
}
This is my xml which uses coordinator layout. When the search layout moves up, cart moves to left and search icon scales up.
<com.example.ui.customviews.CustomDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/ab_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="131dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<LinearLayout
android:id="@+id/ll_search_layout"
android:layout_width="match_parent"
android:layout_height="75dp"
android:layout_gravity="bottom"
android:orientation="vertical"
android:visibility="visible"
android:background="@drawable/search_layout_twin_background"
app:layout_scrollFlags="scroll|snap">
<LinearLayout
android:id="@+id/ll_search_box"
android:layout_width="match_parent"
android:layout_height="51dp"
android:layout_marginBottom="@dimen/dimen_12_dp"
android:layout_marginLeft="@dimen/dimen_8_dp"
android:layout_marginRight="@dimen/dimen_8_dp"
android:layout_marginTop="@dimen/dimen_12_dp"
android:background="@drawable/round_corner_layout_white"
android:elevation="@dimen/dimen_5_dp"
android:focusableInTouchMode="true"
android:orientation="horizontal">
<EditText
android:id="@+id/et_search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dimen_15_dp"
android:layout_weight="80"
android:background="@android:color/transparent"
android:hint="Search for Products"
android:padding="@dimen/dimen_5_dp"
android:textColor="@color/black"
android:textColorHint="@color/hint_text_color"
android:textSize="@dimen/dimen_text_16_sp" />
<ImageView
android:id="@+id/iv_search_icon"
android:layout_width="@dimen/dimen_22_dp"
android:layout_height="@dimen/dimen_24_dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dimen_17_dp"
android:layout_marginRight="@dimen/dimen_20_dp"
android:src="@drawable/ic_search_grey" />
</LinearLayout>
</LinearLayout>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_primary_height"
android:background="@color/askme_blue"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<LinearLayout
android:id="@+id/layout_toolbar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_drawer_menu"
android:layout_width="@dimen/dimen_22_dp"
android:layout_height="@dimen/dimen_22_dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dimen_16_dp"
android:layout_marginRight="@dimen/dimen_15_dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_drawer_menu" />
<ImageView
android:id="@+id/iv_back_btn"
android:layout_width="@dimen/dimen_22_dp"
android:layout_height="@dimen/dimen_20_dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dimen_16_dp"
android:layout_marginRight="@dimen/dimen_15_dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_back_button"
android:visibility="gone" />
</FrameLayout>
<LinearLayout
android:id="@+id/ll_location"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="?attr/selectableItemBackgroundBorderless">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Delhi"
android:textColor="@color/white"
android:textSize="20sp"
android:visibility="visible" />
<ImageView
android:id="@+id/toolbar_location_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dimen_3_dp"
android:layout_marginTop="@dimen/dimen_4_dp"
android:src="@drawable/ic_edit_location"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>
<FrameLayout
android:layout_width="@dimen/dimen_100_dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:layout_marginRight="@dimen/dimen_16_dp"
android:gravity="right">
<RelativeLayout
android:id="@+id/rl_search"
android:layout_width="@dimen/dimen_40_dp"
android:layout_height="@dimen/dimen_40_dp"
android:layout_gravity="center_vertical|right"
android:layout_marginLeft="14dp"
android:background="?attr/selectableItemBackgroundBorderless">
<ImageView
android:id="@+id/iv_search"
android:layout_width="@dimen/dimen_24_dp"
android:layout_height="@dimen/dimen_24_dp"
android:layout_centerInParent="true"
android:src="@drawable/ic_search" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_parent_cart_count"
android:layout_width="94dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:gravity="right"
android:paddingRight="54dp">
<RelativeLayout
android:id="@+id/rl_cart_count"
android:layout_width="@dimen/dimen_40_dp"
android:layout_height="@dimen/dimen_40_dp"
android:layout_gravity="center_vertical|right"
android:background="?attr/selectableItemBackgroundBorderless">
<ImageView
android:layout_width="@dimen/dimen_25_dp"
android:layout_height="@dimen/dimen_24_dp"
android:layout_centerInParent="true"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:scaleType="center"
android:src="@drawable/ic_cart" />
<TextView
android:id="@+id/tv_cart_count"
android:layout_width="@dimen/dimen_17_dp"
android:layout_height="@dimen/dimen_17_dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="@dimen/dimen_3_dp"
android:layout_marginTop="@dimen/dimen_3_dp"
android:background="@drawable/cart_count_background_circle"
android:elevation="@dimen/dimen_5_dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/dimen_text_10_sp"
android:textStyle="bold"
android:visibility="visible" />
</RelativeLayout>
</RelativeLayout>
</FrameLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/askme_blue"
app:layout_behavior="com.GetIt.animation.SearchLayoutBehavior"/>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
<fragment
android:id="@+id/navigation_drawer"
android:name="com.example.ui.fragment.SideMenuFragment"
android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start" />
</com.example.ui.customviews.CustomDrawerLayout>
This is how it will look like.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With