FloatingActionButton的学习总结

  最近在学习android材料设计的新控件,前面一篇文章讲到 CoordinatorLayout 结合几个新控件可以实现的几个效果。其中第一个是,Coordinatorlayout + FloatingActionButton,配合使用,当弹出 Snackbar 的时候,FloatingActionBar会跟随上移和下移。这次再针对 FloatingActionButton 具体分析一下。先贴出布局文件和java代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btnSnackBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="点击弹出SnackBar"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/floatingActionBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:src="@mipmap/ic_launcher" />

</android.support.design.widget.CoordinatorLayout>
public class MainActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sixth);
        ((Button) findViewById(R.id.btnSnackBar)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Snackbar.make(v,"这是一个snackBar",Snackbar.LENGTH_SHORT).show();
            }
        });
    }
}

代码很简洁,效果如下:

  

  这个效果只有在CoordinatorLayout下,FloatingActionButton 配合 Snackbar 使用才会有。

  我们知道,FloatingActionButton 间接继承自 ImagButton, 如果将 FloatingActionButton 换成常用的 ImagButton 或者 ImageView,效果将不存在。为什么会这样呢。在 FloatingActionButton 的定义中发现,通过反射,利用注解注入了一个 behavior 属性。FloatingActionButton 类中定义了一个内部类——Behaivor,继承自 CoordinatorLayout.Behavior<FloatingActionButton> 。里面有两个方法如下:

  

     @Override
     public boolean layoutDependsOn(CoordinatorLayout parent,FloatingActionButton child, View dependency) {
            // We‘re dependent on all SnackbarLayouts (if enabled)
            return SNACKBAR_BEHAVIOR_ENABLED && dependency instanceof Snackbar.SnackbarLayout;
        }

     @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child,View dependency) {
            if (dependency instanceof Snackbar.SnackbarLayout) {
                updateFabTranslationForSnackbar(parent, child, dependency);
            } else if (dependency instanceof AppBarLayout) {
                // If we‘re depending on an AppBarLayout we will show/hide it automatically
                // if the FAB is anchored to the AppBarLayout
                updateFabVisibility(parent, (AppBarLayout) dependency, child);
            }
            return false;
        }

     private float getFabTranslationYForSnackbar(CoordinatorLayout parent,FloatingActionButton fab) {
            float minOffset = 0;
            final List<View> dependencies = parent.getDependencies(fab);
            for (int i = 0, z = dependencies.size(); i < z; i++) {
              final View view = dependencies.get(i);
              if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(fab, view)) {
                    minOffset = Math.min(minOffset,ViewCompat.getTranslationY(view) - view.getHeight());
               }
            }
            return minOffset;
          }

    layoutDependsOn 方法,判断底下弹出的是不是snackbar,如果是,floatingactionbutton才会联动。

    当需要联动的snackbar向上移动的过程中,会不断调用 onDependentViewChanged 方法。

     getFabTranslationYForSnackbar 用来获取SnackBar逐渐弹出来的时候变化的高度。

    明白了这三个方法之后,我们就可以对这个效果进行修改写。下面我们自己写一个类,让其继承自 CoordinatorLayout.Behavior<FloatingActionButton>,

 让FloatingActionButton在上升过程中实现随高度变化旋转效果。

    代码如下:

    

public class MyBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {
    /**
     * Default constructor for instantiating Behaviors.
     */
    public MyBehavior() {
    }

    /**
     * Default constructor for inflating Behaviors from layout. The Behavior will have
     * the opportunity to parse specially defined layout parameters. These parameters will
     * appear on the child view tag.
     *
     * @param context
     * @param attrs
     */
    public MyBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 判断底下弹出的是不是snackbar,如果是,floatingactionbutton才会联动
     *
     * @param parent
     * @param child
     * @param dependency
     * @return
     */
    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent,
                                   FloatingActionButton child, View dependency) {

        return dependency instanceof Snackbar.SnackbarLayout;
    }

    /**
     * 当需要联动的snackbar向上移动的过程中,会不断调用这个方法
     *
     * @param parent
     * @param child
     * @param dependency
     * @return
     */
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child,
                                          View dependency) {

        float fTransY = getFabTranslationYForSnackbar(parent, child);

        float iRate = -fTransY / dependency.getHeight();

        child.setRotation(iRate * 90);

        child.setTranslationY(fTransY);

        return false;
    }

    /**
     * 用来获取SnackBar逐渐弹出来的时候变化的高度
     *
     * @param parent
     * @param fab
     * @return
     */
    private float getFabTranslationYForSnackbar(CoordinatorLayout parent,
                                                FloatingActionButton fab) {
        float minOffset = 0;
        final List<View> dependencies = parent.getDependencies(fab);
        for (int i = 0, z = dependencies.size(); i < z; i++) {
            final View view = dependencies.get(i);
            if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(fab, view)) {
                minOffset = Math.min(minOffset,
                        ViewCompat.getTranslationY(view) - view.getHeight());
            }
        }
        return minOffset;
    }
}

   然后修改布局文件,为 FloatingActionButton 设置 layout_behavior 属性为自定义的MyBehavior,

   

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Button
        android:id="@+id/btnSnackBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="点击弹出SnackBar"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/floatingActionBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        app:layout_behavior="com.example.joy.coordinatorlayouttest.MyBehavior"
        android:src="@mipmap/ic_launcher" />

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

  效果如下:

  

  

时间: 2024-08-02 06:58:53

FloatingActionButton的学习总结的相关文章

学习笔记-Kuaihu(仿知乎日报)

本文目的:由于第一次学习较为完整的项目,故作记录以系统地整理APP开发知识 先看看整个项目结构: activity, fragment, 不用说了.可以看做MVC中的controller db, 存储json缓存用的,model就是一些bean类比如首页Item的对象,点开详情的文章对象 util嘛一些工具类.里面可以对已有的HTTP工具再次进行封装. view就是一些自定义的或者第三方view类. Kpplication就是自己写的application类,里面进行了第三方工具的初始化,其他没

Android学习笔记--design包下的两个控件

今天学习了design包下的两个控件,记录一下,首先需要我们依赖 1 compile 'com.android.support:design:25.0.0' 之后在XML文件中就可以使用了 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 x

Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用

[转载请注明出处:http://blog.csdn.net/feiduclear_up/article/details/46500865 CSDN 废墟的树] 在前不久的谷歌2015 I/O大会上,发布了Android新版本M,貌似从这个版本开始Android不在以数字命名版本了. 在这次的I/O大会上谷歌对Android并没有很大的改变,主要是修改完善之前Android L版本.不过在谷歌推出 Material Design设计风格之后,还是做了很多风格上的兼容,比如v7包的 Recycler

【转】Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用

Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用 分类: Android UI2015-06-15 16:44 1145人阅读 评论(5) 收藏 举报 MaterialDesingsupportlibrary 目录(?)[-] 前提 FloatingActionButton TextInputLayout Snackbar的使用 TabLayout [转载请注明出处:http://blog.csdn.n

Android 用户表单融合各类简易控件以及融入FloatingActionButton以及butterknife(一)

转载请注明出处王亟亟的大牛之路 空了2个礼拜,终于开始有事做了,用了午休时间和下午的大概1个小时,完成了这个例子,让小伙伴们,对一些常用的表单所需的控件,做一个温故,再配合炫酷的FloatingActionButton以及好用butterknife,可以有效的提高我们的效率. 本文为2部分,还有部分图片上传啊一些功能明天再做了,今天 有点来不及了. 包结构: 项目是Android Studio的所以贴下Gradle配置: apply plugin: 'com.android.applicatio

通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout

特别喜欢稀土掘金个人界面的样子,那我们就来看看如何实现这个效果吧,要想实现这个效果,肯定需要的是Material Design风格,那就需要学会使用以下控件:CoordinatorLayout,AppBarLayout,CollapsingToolbarLayout,Toolbar,TabLayout等,如果你做出这个效果来,那这些控件你就基本掌握了. 效果对比图 介绍之前,我们先来看看效果对比图: 稀土掘金app原图 模仿的效果图 CoordinatorLayout的介绍 Coordinato

Vue.js学习笔记:属性绑定 v-bind

v-bind  主要用于属性绑定,Vue官方提供了一个简写方式 :bind,例如: <!-- 完整语法 --> <a v-bind:href="url"></a> <!-- 缩写 --> <a :href="url"></a> 绑定HTML Class 一.对象语法: 我们可以给v-bind:class 一个对象,以动态地切换class.注意:v-bind:class指令可以与普通的class特

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程

微信小程序学习总结(2)------- 之for循环,绑定点击事件

最近公司有小程序的项目,本人有幸参与其中,一个项目做下来感觉受益匪浅,与大家做下分享,欢迎沟通交流互相学习. 先说一下此次项目本人体会较深的几个关键点:微信地图.用户静默授权.用户弹窗授权.微信充值等等. 言归正传,今天分享我遇到的关于wx:for循环绑定数据的一个tips:  1. 想必大家的都知道wx:for,如下就不用我啰嗦了: <view class="myNew" wx:for="{{list}}">{{item.title}}<view