您的位置:首页 > 其它

coordinatorLayout 的一个小效果

2016-03-15 23:42 555 查看
Design Support Library中 有个CoordinatorLayout类,效果挺不错的。先看看下面的效果:



布局代码:

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

<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="200.0dp"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_collapseMode="parallax">

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

<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/img_text2"
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" />

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

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

<android.support.v4.widget.NestedScrollView
android:id="@+id/scrollview"
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="1000.0dp"
android:orientation="vertical"
android:paddingBottom="10.0dp"
android:paddingTop="24dp">

</LinearLayout>

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

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end" />

</android.support.design.widget.CoordinatorLayout>
看了上面的效果,但是别误会了,我这篇文章要将的小效果是FloatingActionButton渐进渐出的效果,这个控件实现的效果跟NestScrollview中的layout_behavior中的的类同一个原理。都是去实现一个Behavior类来控制控件的效果。当有一个需求要在

FloatingActionButton的位置上放一个更复杂的布局,而不单单是一个FloatingActionButton,例如放其它的一个View。这时我们可以自己写一个behavior。先看看效果:





下面是自定义behavior的代码:

package com.example.arze.apptotest.Untils.AnimUntils;

/**
* Created by arze on 2016/3/14.
*/

import android.content.Context;
import android.os.Build;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorListener;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import com.example.arze.apptotest.R;

/**
* Created by arze on 2016/3/14.
*/
public class ViewBehavior extends CoordinatorLayout.Behavior<View> {
private boolean isOut = false;
private boolean isIn = false;
private Animation mAnimIn;
private Animation mAnimOut;
public ViewBehavior () {
super();
}
public ViewBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
mAnimIn = AnimationUtils.loadAnimation(context, R.anim.view_in);
mAnimOut = AnimationUtils.loadAnimation(context, R.anim.view_out);
}

/**
*
* @param parent   coordinatorLayout 父布局
* @param child    跟随变化的view
* @param dependency  这个view的改变会引发child的改变 ,当然要返回为true
* @return
*/
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof AppBarLayout;
}

/**
*  这个函数执行child的变换
* @param parent    coordinatorLayout 父布局
* @param child     跟随变化的view
* @param dependency  这个view的改变会引发child的改变
* @return
*/
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {

if (Math.abs(dependency.getTop()) > dependency.getHeight() / 2 && View.VISIBLE == child.getVisibility() && !isOut) {
animateOut(child);
} else if (Math.abs(dependency.getTop()) < dependency.getHeight() / 2 && View.GONE == child.getVisibility() && !isIn) {
animateIn(child);
}

return false;
}

/**
* 出现动画
* @param view
*/
private void animateIn(final View view) {

if (Build.VERSION.SDK_INT >= 14) {
ViewCompat.animate(view).scaleX(1.0F).scaleY(1.0F).alpha(1.0F).setInterpolator(
new FastOutSlowInInterpolator()).withLayer().setListener(new ViewPropertyAnimatorListener() {
@Override
public void onAnimationStart(View view) {
view.setVisibility(View.VISIBLE);
isIn = true;
}

@Override
public void onAnimationEnd(View view) {
isIn = false;
}

@Override
public void onAnimationCancel(View view) {
}
}).start();
} else {

mAnimIn.setInterpolator(new FastOutSlowInInterpolator());
mAnimIn.setDuration(200L);
mAnimIn.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
view.setVisibility(View.VISIBLE);
isIn = true;
}

@Override
public void onAnimationEnd(Animation animation) {
isIn = false;
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});
view.startAnimation(mAnimIn);

}
}
/**
*消失动画
* @param view
*/
private void animateOut(final View view) {

if (Build.VERSION.SDK_INT >= 14) {
ViewCompat.animate(view).scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setInterpolator(
new FastOutSlowInInterpolator()).withLayer().setListener(new ViewPropertyAnimatorListener() {
public void onAnimationStart(View view) {
isOut = true;
}

public void onAnimationCancel(View view) {
}

public void onAnimationEnd(View view) {
isOut = false;
view.setVisibility(View.GONE);
}
}).start();
} else {

mAnimOut.setInterpolator(new FastOutSlowInInterpolator());
mAnimOut.setDuration(200L);
mAnimOut.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
isOut = true;
}

@Override
public void onAnimationEnd(Animation animation) {
isOut = false;
view.setVisibility(View.GONE);
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});
view.startAnimation(mAnimOut);

}

}

}
使用方法是在布局文件中要跟随变化的view中添加layout_behavior = ViewBehavior的路径名 ,最终由CoordinatorLayout用过反射来实现类的实例化。当然这里只是简单的实现了behavior,因为Behavior这个抽象类还有很多方法。

用动画控制这个效果不太灵活,动画从开始到结束这个过程是固定的。我们可以通过view.set属性来控制view的变化。需要一个dependency 这个view的变化细节,比如定义一个float
类型来表示dependency 在一定区间内的变化率。用这个变化率来实现view的属性变化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: