android联动动画,利用 CollapsingToolbarLayout 完成联动的动画效果

最近项目中需要实现个动画效果,研究了下这里做下简单的分享.

效果图如下:

c643d277fe41

示例.gif

最初的想法是自己去利用 Android 的嵌套滚动机制,去实现上面的嵌套滚动效果.但最后为了开发效率直接利用了 CollapsingToolbarLayout 和 CoordinatorLayout 的效果.

实现效果的原理十分简单,监听 CollapsingToolbarLayout 收缩和扩展的距离,换算成你想要的一个范围比如移动的距离,缩放的比例.

部分源码:

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.xf.mylab.activity.CollapsingToolbarLayoutTestActivity">

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.wswy.chechengwang.view.activity.SubscriptionDetailActivity">

android:id="@+id/app_bar"

android:layout_width="match_parent"

android:layout_height="@dimen/subscription_head">

android:layout_width="match_parent"

android:layout_height="match_parent"

app:layout_scrollFlags="scroll|exitUntilCollapsed">

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="@dimen/toolbar_height"

app:layout_collapseMode="pin">

android:id="@+id/back"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_vertical"

android:src="@drawable/ic_white_left_arrow" />

android:id="@+id/subscription_show"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@color/white"

app:layout_behavior="@string/appbar_scrolling_view_behavior">

android:layout_width="match_parent"

android:layout_height="match_parent"

android:gravity="center"

android:text="夏洛克的猫"

android:textSize="30sp" />

android:layout_width="match_parent"

android:layout_height="@dimen/subscription_head"

android:gravity="center"

android:orientation="vertical">

android:id="@+id/iv_head"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@drawable/ic_default_subscription" />

android:id="@+id/subscription_title"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:text="夏洛克的猫"

android:textColor="@color/white"

android:textSize="16sp" />

android:id="@+id/subscribe"

android:layout_width="75dp"

android:layout_height="24dp"

android:layout_marginTop="8dp"

android:button="@null"

android:checked="false"

android:gravity="center"

android:text="订阅"

android:textColor="@color/white" />

public class CollapsingToolbarLayoutTestActivity extends AppCompatActivity {

private float mSelfHeight = 0;//用以判断是否得到正确的宽高值

private float mTitleScale;

private float mSubScribeScale;

private float mSubScribeScaleX;

private float mHeadImgScale;

@Bind(R.id.iv_head)

ImageView mHeadImage;

@Bind(R.id.subscription_title)

TextView mSubscriptionTitle;

@Bind(R.id.subscribe)

TextView mSubscribe;

@Bind(R.id.app_bar)

AppBarLayout mAppBar;

@Bind(R.id.toolbar)

Toolbar mToolbar;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_collapsing_toolbar_layout_test);

ButterKnife.bind(this);

final float screenW = getResources().getDisplayMetrics().widthPixels;

final float toolbarHeight = getResources().getDimension(R.dimen.toolbar_height);

final float initHeight = getResources().getDimension(R.dimen.subscription_head);

mAppBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {

@Override

public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

if (mSelfHeight == 0) {

mSelfHeight = mSubscriptionTitle.getHeight();

float distanceTitle = mSubscriptionTitle.getTop() + (mSelfHeight - toolbarHeight) / 2.0f;

float distanceSubscribe = mSubscribe.getY() + (mSubscribe.getHeight() - toolbarHeight) / 2.0f;

float distanceHeadImg = mHeadImage.getY() + (mHeadImage.getHeight() - toolbarHeight) / 2.0f;

float distanceSubscribeX = screenW / 2.0f - (mSubscribe.getWidth() / 2.0f + getResources().getDimension(R.dimen.normal_space));

mTitleScale = distanceTitle / (initHeight - toolbarHeight);

mSubScribeScale = distanceSubscribe / (initHeight - toolbarHeight);

mHeadImgScale = distanceHeadImg / (initHeight - toolbarHeight);

mSubScribeScaleX = distanceSubscribeX / (initHeight - toolbarHeight);

}

float scale = 1.0f - (-verticalOffset) / (initHeight - toolbarHeight);

mHeadImage.setScaleX(scale);

mHeadImage.setScaleY(scale);

mHeadImage.setTranslationY(mHeadImgScale * verticalOffset);

mSubscriptionTitle.setTranslationY(mTitleScale * verticalOffset);

mSubscribe.setTranslationY(mSubScribeScale * verticalOffset);

mSubscribe.setTranslationX(-mSubScribeScaleX * verticalOffset);

}

});

}

}

代码其实没啥可说的,主要是一些距离的计算,主要就是顶在最上方时,文字都到了居中的位置.大家在图中画出开始和结束的位置,都能计算出来.

有一点提一下,最初我是把布局嵌入到 CollapsingToolbarLayout 中去的,但是由于 CollapsingToolbarLayout 自身的收缩和扩展改变了自身高度,会影响里面的 View 的位置,如果按照静态的起始和结束位置计算,加上自身高度对 View 布局的影响,这就复杂了,我没有细研究.采用了一个笨拙的方式,用 FrameLayout 把布局给抽取到顶部,不让他们受到 CollapsingToolbarLayout 的影响.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值