I want do this but with Collapsing toolbar layout or display the logo and title in toolbar after scroll.
<!-- Toolbars -->
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="@dimen/detail_backdrop_height"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp"
android:fitsSystemWindows="true">
<ImageView
android:id="@+id/background_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/background_1"
app:layout_collapseMode="parallax"
android:fitsSystemWindows="true"/>
<RelativeLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ImageView
android:id="@+id/avatar_image"
android:layout_width="@dimen/circular_image_avatar"
android:layout_height="@dimen/circular_image_avatar"
android:gravity="center"
android:scaleType="centerCrop"
android:src="@drawable/ic_placerholder"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:transitionName="image_toolbar"/>
<TextView
android:id="@+id/profile_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Name title"
android:textAlignment="center"
android:layout_marginTop="@dimen/item_padding_top_bottom"
android:gravity="center"
style="@style/titleText_toolbar"
android:layout_below="@+id/avatar_image"
android:transitionName="title_toolbar"/>
<TextView
android:id="@+id/profile_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Subtitle"
android:textAlignment="center"
android:gravity="center"
style="@style/captionText_toolbar"
android:layout_below="@+id/profile_title" />
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin">
<!-- avatar image and title, subtitle -->
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
Please help me
CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar. It is designed to be used as a direct child of a AppBarLayout .
collapsingToolbarLayout. setTitleEnabled(false); toolbar. setTitle("My Title"); By calling setTitleEnabled(false); , the title appeared in the toolbar.
I have preperead two amaizing avatar collapsing demo samples with approach that doesn’t use a custom CoordinatorLayoutBehavior
!
To view my samples native code: "Collapsing Avatar Toolbar Sample"
To read my "Animation Collapsing Toolbar Android" post on Medium.
demo 1 demo 2
Instead of use use a custom CoordinatorLayoutBehavior
i use an OnOffsetChangedListener
which comes from AppBarLayout
.
private lateinit var appBarLayout: AppBarLayout override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_demo_1) ... appBarLayout = findViewById(R.id.app_bar_layout) /**/ appBarLayout.addOnOffsetChangedListener( AppBarLayout.OnOffsetChangedListener { appBarLayout, i -> ... /**/ updateViews(Math.abs(i / appBarLayout.totalScrollRange.toFloat())) }) }
in updateViews
method avatar changes the size and changes avatar’s X, Y position translation in first demo.
private fun updateViews(offset: Float) { ... /* Collapse avatar img*/ ivUserAvatar.apply { when { offset > avatarAnimateStartPointY -> { val avatarCollapseAnimateOffset = (offset - avatarAnimateStartPointY) * avatarCollapseAnimationChangeWeight val avatarSize = EXPAND_AVATAR_SIZE - (EXPAND_AVATAR_SIZE - COLLAPSE_IMAGE_SIZE) * avatarCollapseAnimateOffset this.layoutParams.also { it.height = Math.round(avatarSize) it.width = Math.round(avatarSize) } invisibleTextViewWorkAround.setTextSize(TypedValue.COMPLEX_UNIT_PX, offset) this.translationX = ((appBarLayout.width - horizontalToolbarAvatarMargin - avatarSize) / 2) * avatarCollapseAnimateOffset this.translationY = ((toolbar.height - verticalToolbarAvatarMargin - avatarSize ) / 2) * avatarCollapseAnimateOffset } else -> this.layoutParams.also { if (it.height != EXPAND_AVATAR_SIZE.toInt()) { it.height = EXPAND_AVATAR_SIZE.toInt() it.width = EXPAND_AVATAR_SIZE.toInt() this.layoutParams = it } translationX = 0f } } } }
to find avatarAnimateStartPointY
and avatarCollapseAnimationChangeWeight
(for convert general offset to avatar animate offset):
private var avatarAnimateStartPointY: Float = 0F private var avatarCollapseAnimationChangeWeight: Float = 0F private var isCalculated = false private var verticalToolbarAvatarMargin =0F ... if (isCalculated.not()) { avatarAnimateStartPointY = Math.abs((appBarLayout.height - (EXPAND_AVATAR_SIZE + horizontalToolbarAvatarMargin)) / appBarLayout.totalScrollRange) avatarCollapseAnimationChangeWeight = 1 / (1 - avatarAnimateStartPointY) verticalToolbarAvatarMargin = (toolbar.height - COLLAPSE_IMAGE_SIZE) * 2 isCalculated = true }
avatar change his size and than animate move to right at one moment with top toolbar text became to show and moving to left.
You need to track states: TO_EXPANDED_STATE
changing, TO_COLLAPSED_STATE
changing, WAIT_FOR_SWITCH
.
/*Collapsed/expended sizes for views*/ val result: Pair<Int, Int> = when { percentOffset < ABROAD -> { Pair(TO_EXPANDED_STATE, cashCollapseState?.second ?: WAIT_FOR_SWITCH) } else -> { Pair(TO_COLLAPSED_STATE, cashCollapseState?.second ?: WAIT_FOR_SWITCH) } }
Create animation for avatar on state switch change:
result.apply { var translationY = 0f var headContainerHeight = 0f val translationX: Float var currentImageSize = 0 when { cashCollapseState != null && cashCollapseState != this -> { when (first) { TO_EXPANDED_STATE -> { translationY = toolbar.height.toFloat() headContainerHeight = appBarLayout.totalScrollRange.toFloat() currentImageSize = EXPAND_AVATAR_SIZE.toInt() /**/ titleToolbarText.visibility = View.VISIBLE titleToolbarTextSingle.visibility = View.INVISIBLE background.setBackgroundColor(ContextCompat.getColor(this@Demo2Activity, R.color.color_transparent)) /**/ ivAvatar.translationX = 0f } TO_COLLAPSED_STATE -> { background.setBackgroundColor(ContextCompat.getColor(this@Demo2Activity, R.color.colorPrimary)) currentImageSize = COLLAPSE_IMAGE_SIZE.toInt() translationY = appBarLayout.totalScrollRange.toFloat() - (toolbar.height - COLLAPSE_IMAGE_SIZE) / 2 headContainerHeight = toolbar.height.toFloat() translationX = appBarLayout.width / 2f - COLLAPSE_IMAGE_SIZE / 2 - margin * 2 /**/ ValueAnimator.ofFloat(ivAvatar.translationX, translationX).apply { addUpdateListener { if (cashCollapseState!!.first == TO_COLLAPSED_STATE) { ivAvatar.translationX = it.animatedValue as Float } } interpolator = AnticipateOvershootInterpolator() startDelay = 69 duration = 350 start() } ... } } ivAvatar.apply { layoutParams.height = currentImageSize layoutParams.width = currentImageSize } collapsingAvatarContainer.apply { layoutParams.height = headContainerHeight.toInt() this.translationY = translationY requestLayout() } /**/ cashCollapseState = Pair(first, SWITCHED) }
To view my samples native code: "Collapsing Avatar Toolbar Sample"
I think these type of animations can be achieved easily using MotionLayout. I have implemented sample collapsing layout using MotionLayout here. You can modify it for your use case. Simple change the start and end constraints.
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