coordinatorLayout 的一个小效果
2016-03-15 23:42
555 查看
Design Support Library中 有个CoordinatorLayout类,效果挺不错的。先看看下面的效果:
布局代码:
FloatingActionButton的位置上放一个更复杂的布局,而不单单是一个FloatingActionButton,例如放其它的一个View。这时我们可以自己写一个behavior。先看看效果:
下面是自定义behavior的代码:
用动画控制这个效果不太灵活,动画从开始到结束这个过程是固定的。我们可以通过view.set属性来控制view的变化。需要一个dependency 这个view的变化细节,比如定义一个float
类型来表示dependency 在一定区间内的变化率。用这个变化率来实现view的属性变化。
布局代码:
<?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的属性变化。
相关文章推荐
- 算法系列1、动态规划
- mount --bind 重启后失效的解决办法
- 25.Reverse Nodes in k-Group
- Ant自动化构建项目
- Qt 简介
- 29.UITableViewDataSource详解
- 数据结构(7)线性表之链表C++实现差集
- 单例模式
- iOS-UIDynamic物理仿真-附着-UIAttachmentBehavior
- SQL-创建表
- git 遇到的错误以及解决方式(持续更新...)
- 12c_Data redaction 数据编写策略
- android studio gradle 怎么更新
- /bin/bash
- POJO对象(一)简介
- ajax的几个坑,稍微留意
- 对象序列化
- spring笔记--通过注解(annotation)配置Bean
- synchronized锁重入
- 用LinearLayout和RelativeLayout分别实现简单的登陆界面