CoordinatorLayout与Behavior源码分析

CoordinatorLayout源码解析,探索Behavior机制的奥秘 1.文章内容概述 本文主要是针对Behavior的运作机制,通过对CoordinatorLayout的源码中对此Behavior的执行过程进行分析,得出其运行原理。本文主要是针对behavior的layout child的方式,touch事件的处理,以及内嵌滑动事件的处理进行重要分析。 2.阅读本文前的准备工作 关于内嵌滑动,这是在android5.0之后google提出的,并且在suppo 阅读详情

本文通过分析CoordinatorLayout的源码,总结了Behavior在CoordinatorLayout中是如何运作的。

1、Behavior

Behavior是CoordinatorLayout的静态抽象类public static abstract class Behavior<V extends View>,主要包含了以下方法:

第一组:拦截和触摸相关的方法

 - public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent ev) 

 - public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent ev)

第二组:依赖相关的方法

 - public boolean layoutDependsOn(CoordinatorLayout parent, V child, View dependency)

 - public boolean onDependentViewChanged(CoordinatorLayout parent, V child, View dependency)

第三组:测量和布局相关的方法

 - public boolean onMeasureChild(CoordinatorLayout parent, V child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)

 - public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection)

第四组:嵌套滑动相关的方法

 - public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes)

 - public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes)

 - public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target)

 - public void onNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)

 - public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed)

 - public boolean onNestedFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY, boolean consumed)

 - public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY)

我们对这几个方法应该比较熟悉,根据方法的作用,我将它们分成了四组,具体用法下面会分析。

2、CoordinatorLayout

下面对CoordinatorLayout的几个重要方法进行分析:

1、onMeasure方法

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //该方法执行完成后mDependencySortedChildren中保存了所有排好序的直接子view,被依赖的子view靠前。
        //mChildDag保存了CoordinatorLayout直接子view间的依赖关系,
        //其中mChildDag.getIncomingEdges(view)返回依赖于view的其他子view,
        //mChildDag.getOutgoingEdges(child)返回child依赖的子view。
        prepareChildren();
        //CoordiantorLayout的直接子view中,如果存在一个子view依赖于其他子view,则添加一个mOnPreDrawListener,
        //用于当被依赖的子view改变时,依赖它的子view能做出相应的动作。
        ensurePreDrawListener();

        ...

        final int childCount = mDependencySortedChildren.size();
        for (int i = 0; i < childCount; i++) {
            final View child = mDependencySortedChildren.get(i);

            ...

            int childWidthMeasureSpec = widthMeasureSpec;
            int childHeightMeasureSpec = heightMeasureSpec;

            ...

            //如果子view设置了Behavior并且Behavior的onMeasureChild方法返回true的话CoordiantorLayout的onMeasureChild方法就不会调用,
            //相应的子view的onMeasure方法就不会被调用。
            //我们可以得出结论:如果给子view设置的Behavior的onMeasureChild方法返回true的话,
            //那么Behavior的onMeasureChild方法可以接替子view的onMeasure方法执行子view的测量工作。
            if (b == null || !b.onMeasureChild(this, child, childWidthMeasureSpec, keylineWidthUsed,
                    childHeightMeasureSpec, 0)) {
                onMeasureChild(child, childWidthMeasureSpec, keylineWidthUsed,
                        childHeightMeasureSpec, 0);
            }

            widthUsed = Math.max(widthUsed, widthPadding + child.getMeasuredWidth() +
                    lp.leftMargin + lp.rightMargin);

            heightUsed = Math.max(heightUsed, heightPadding + child.getMeasuredHeight() +
                    lp.topMargin + lp.bottomMargin);
            childState = View.combineMeasuredStates(childState, child.getMeasuredState());
        }

        final int width = View.resolveSizeAndState(widthUsed, widthMeasureSpec,
                childState & View.MEASURED_STATE_MASK);
        final int height = View.resolveSizeAndState(heightUsed, heightMeasureSpec,
                childState << View.MEASURED_HEIGHT_STATE_SHIFT);
        setMeasuredDimension(width, height);
    }

2、onLayout方法

@Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int layoutDirection = ViewCompat.getLayoutDirection(this);
        final int childCount = mDependencySortedChildren.size();
        for (int i = 0; i < childCount; i++) {
            final View child = mDependencySortedChildren.get(i);
            if (child.getVisibility() == GONE) {
                // If the child is GONE, skip...
                continue;
            }

            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            final Behavior behavior = lp.getBehavior();

            //跟上面的onMeasure一样的套路,不再多说。
            if (behavior == null || !behavior.onLayoutChild(this, child, layoutDirection)) {
                onLayoutChild(child, layoutDirection);
            }
        }
    }

3、onInterceptTouchEvent

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        MotionEvent cancelEvent = null;

        final int action = ev.getActionMasked();

        // Make sure we reset in case we had missed a previous important event.
        if (action == MotionEvent.ACTION_DOWN) {
            resetTouchBehaviors();
        }

        final boolean intercepted = performIntercept(ev, TYPE_ON_INTERCEPT);

        if (cancelEvent != null) {
            cancelEvent.recycle();
        }

        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            resetTouchBehaviors();
        }

        return intercepted;
    }

onInterceptTouchEvent调用了performIntercept方法来决定是否拦截,传入的type是TYPE_ON_INTERCEPT。我们看一下performIntercept方法:

private boolean performIntercept(MotionEvent ev, final int type) {
        boolean intercepted = false;
        boolean newBlock = false;

        MotionEvent cancelEvent = null;

        final int action = ev.getActionMasked();

        final List<View> topmostChildList = mTempList1;
        //返回一个子view的列表,z轴上越靠上的越在列表的前面,便于事件分发
        getTopSortedChildren(topmostChildList);

        // Let topmost child views inspect first
        final int childCount = topmostChildList.size();
        for (int i = 0; i < childCount; i++) {
            final View child = topmostChildList.get(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            final Behavior b = lp.getBehavior();

            ...
            //如果还没有被拦截并且child的behavior不为空的话,将event交由behavior处理
            if (!intercepted && b != null) {
                switch (type) {
                    case TYPE_ON_INTERCEPT:
                        intercepted = b.onInterceptTouchEvent(this, child, ev);
                        break;
                    case TYPE_ON_TOUCH:
                        intercepted = b.onTouchEvent(this, child, ev);
                        break;
                }
                //如果child的behavior的相应方法返回true,使用mBehaviorTouchView记录这个child,
                //不再执行其他child的behavior的相应方法。
                if (intercepted) {
                    mBehaviorTouchView = child;
                }
            }

            ...

        }

        topmostChildList.clear();

        return intercepted;
    }

在没有Behavior之前,执不执行拦截event事件只能由父view决定(子view调用requestDisallowInterceptTouchEvent()除外),子view不能参与父view的拦截逻辑,现在有了Behavior,如果给子view设置Behavior,子view就可以通过Behavior参与到父view的操作逻辑中。
4、onTouchEvent

@Override
    public boolean onTouchEvent(MotionEvent ev) {
        boolean handled = false;
        boolean cancelSuper = false;
        MotionEvent cancelEvent = null;

        final int action = ev.getActionMasked();

        //如果mBehaviorTouchView不为空,即在CoordiantorLayout的onInterceptTouchEvent中
        //存在一个子view的behavior的onInterceptTouchEvent返回true,
        //则直接调用这个behavior的onTouchEvent。
        //否则同样执行performIntercept方法,传入的type是TYPE_ON_TOUCH,如果performIntercept返回true,则mBehaviorTouchView一定不为null,
        //此时直接交由mBehaviorTouchView的behavior的onTouchEvent方法处理。
        if (mBehaviorTouchView != null || (cancelSuper = performIntercept(ev, TYPE_ON_TOUCH))) {
            // Safe since performIntercept guarantees that
            // mBehaviorTouchView != null if it returns true
            final LayoutParams lp = (LayoutParams) mBehaviorTouchView.getLayoutParams();
            final Behavior b = lp.getBehavior();
            if (b != null) {
                handled = b.onTouchEvent(this, mBehaviorTouchView, ev);
            }
        }

        // 如果mBehaviorTouchView是null,
        //则说明CoordiantorLayout的子view都没有设置behavior或者设置的hehavior的onTouchEvent都是返回的false,
        //就继续按照没有behavior的流程进行常规的onTouchEvent()操作。
        if (mBehaviorTouchView == null) {
            handled |= super.onTouchEvent(ev);
        } else if (cancelSuper) {
            if (cancelEvent == null) {
                final long now = SystemClock.uptimeMillis();
                cancelEvent = MotionEvent.obtain(now, now,
                        MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
            }
            super.onTouchEvent(cancelEvent);
        }

        if (!handled && action == MotionEvent.ACTION_DOWN) {

        }

        if (cancelEvent != null) {
            cancelEvent.recycle();
        }

        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            resetTouchBehaviors();
        }

        return handled;
    }

5、onStartNestedScroll
CoordinatorLayout实现了NestedScrollingParent接口,可以处理嵌套滑动,对嵌套滑动机制不熟悉的可以去查阅相关的资料。

@Override
    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
        boolean handled = false;

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View view = getChildAt(i);
            if (view.getVisibility() == View.GONE) {
                // If it's GONE, don't dispatch
                continue;
            }
            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
            final Behavior viewBehavior = lp.getBehavior();
            //如果子view设置了behavior的话,调用behavior的相应onStartNestedScroll方法。
            //此处CoordinatorLayout将它的onStartNestedScroll方法委托给了子view的behavior进行处理,
            //如果存在一个子view的hehavior接收嵌套滑动,则CoordinatorLayout接受嵌套滑动。
            if (viewBehavior != null) {
                final boolean accepted = viewBehavior.onStartNestedScroll(this, view, child, target,
                        nestedScrollAxes);
                handled |= accepted;

                lp.acceptNestedScroll(accepted);
            } else {
                lp.acceptNestedScroll(false);
            }
        }
        return handled;
    }

6、onNestedScrollAccepted
同onStartNestedScroll差不多的套路
7、onStopNestedScroll
同onStartNestedScroll差不多的套路
8、onNestedScroll

@Override
    public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
            int dxUnconsumed, int dyUnconsumed) {
        final int childCount = getChildCount();
        boolean accepted = false;

        //遍历子view
        for (int i = 0; i < childCount; i++) {
            final View view = getChildAt(i);
            if (view.getVisibility() == GONE) {
                // If the child is GONE, skip...
                continue;
            }

            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
            //如果子view不接受嵌套滑动,跳过
            if (!lp.isNestedScrollAccepted()) {
                continue;
            }

            final Behavior viewBehavior = lp.getBehavior();
            //如果子view的hehavior不为空,执行hehavior的onNestedScroll方法
            if (viewBehavior != null) {
                viewBehavior.onNestedScroll(this, view, target, dxConsumed, dyConsumed,
                        dxUnconsumed, dyUnconsumed);
                accepted = true;
            }
        }

        //因为子view可能会在它的hehavior的onNestedScroll方法中对自己的位置、大小等参数进行更改,
        //所以这个地方调用了onChildViewsChanged方法来通知对它有依赖关系的其他子view作出相应的更改。
        if (accepted) {
            onChildViewsChanged(EVENT_NESTED_SCROLL);
        }
    }

我们来看一下onChildViewsChanged是什么样的逻辑:

//type有三种:EVENT_PRE_DRAW,EVENT_NESTED_SCROLL,EVENT_NESTED_SCROLL
//EVENT_PRE_DRAW:即将绘制视图树时执行onChildViewsChanged(EVENT_PRE_DRAW);
//EVENT_NESTED_SCROLL:onNestedScroll、onNestedPreScroll、onNestedFling中选择性执行onChildViewsChanged(EVENT_NESTED_SCROLL);
//EVENT_VIEW_REMOVED:当有子view被Remove的时候执行onChildViewsChanged(EVENT_VIEW_REMOVED)。
final void onChildViewsChanged(@DispatchChangeEvent final int type) {
        final int layoutDirection = ViewCompat.getLayoutDirection(this);
        final int childCount = mDependencySortedChildren.size();
        final Rect inset = acquireTempRect();
        final Rect drawRect = acquireTempRect();
        final Rect lastDrawRect = acquireTempRect();

        //遍历所有子view
        for (int i = 0; i < childCount; i++) {
            final View child = mDependencySortedChildren.get(i);

            ...

            //遍历当前子view后面的子view
            //(前面在prepareChildren()方法中将子view都放到了mDependencySortedChildren里面,
            //并且是排好序的即:被依赖的子view在前面,依赖的子view在后面)
            for (int j = i + 1; j < childCount; j++) {
                final View checkChild = mDependencySortedChildren.get(j);
                final LayoutParams checkLp = (LayoutParams) checkChild.getLayoutParams();
                final Behavior b = checkLp.getBehavior();

                //如果后面的子view依赖当前子view
                if (b != null && b.layoutDependsOn(this, checkChild, child)) {
                    if (type == EVENT_PRE_DRAW && checkLp.getChangedAfterNestedScroll()) {
                        // If this is from a pre-draw and we have already been changed
                        // from a nested scroll, skip the dispatch and reset the flag
                        checkLp.resetChangedAfterNestedScroll();
                        continue;
                    }

                    final boolean handled;
                    //调用后面子view的behavior的相应方法来配合当前子view联动。
                    switch (type) {
                        case EVENT_VIEW_REMOVED:
                            // EVENT_VIEW_REMOVED means that we need to dispatch
                            // onDependentViewRemoved() instead
                            b.onDependentViewRemoved(this, checkChild, child);
                            handled = true;
                            break;
                        default:
                            // Otherwise we dispatch onDependentViewChanged()
                            handled = b.onDependentViewChanged(this, checkChild, child);
                            break;
                    }

                    if (type == EVENT_NESTED_SCROLL) {
                        // If this is from a nested scroll, set the flag so that we may skip
                        // any resulting onPreDraw dispatch (if needed)
                        checkLp.setChangedAfterNestedScroll(handled);
                    }
                }
            }
        }

        releaseTempRect(inset);
        releaseTempRect(drawRect);
        releaseTempRect(lastDrawRect);
    }

9、onNestedPreScroll

@Override
    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
        int xConsumed = 0;
        int yConsumed = 0;
        boolean accepted = false;

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View view = getChildAt(i);
            if (view.getVisibility() == GONE) {
                // If the child is GONE, skip...
                continue;
            }

            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
            if (!lp.isNestedScrollAccepted()) {
                continue;
            }

            final Behavior viewBehavior = lp.getBehavior();
            if (viewBehavior != null) {
                mTempIntPair[0] = mTempIntPair[1] = 0;
                viewBehavior.onNestedPreScroll(this, view, target, dx, dy, mTempIntPair);
                //上面的逻辑跟onNestedScroll差不多。
                //这地方注意一下,如果有多个子view的behavior接受嵌套滑动,xConsumed、yConsumed 的取值是其中某一个子view的behavior消耗的最大值,
                //而不是所有子view的behavior消耗的值的总合。
                xConsumed = dx > 0 ? Math.max(xConsumed, mTempIntPair[0])
                        : Math.min(xConsumed, mTempIntPair[0]);
                yConsumed = dy > 0 ? Math.max(yConsumed, mTempIntPair[1])
                        : Math.min(yConsumed, mTempIntPair[1]);

                accepted = true;
            }
        }

        consumed[0] = xConsumed;
        consumed[1] = yConsumed;

        //同onNestedScroll
        if (accepted) {
            onChildViewsChanged(EVENT_NESTED_SCROLL);
        }
    }

10、onNestedFling
同onStartNestedScroll差不多的套路
11、onNestedPreFling
同onStartNestedScroll差不多的套路

综上:CoordinatorLayout的源码还是挺简单的,Behavior的存在使得子view可以决定自己的大小、位置,可以影响父view的事件传递,可以处理嵌套滑动,较传统的方式还是很新颖的。
后面有时间的话会分析一下AppBarLayout的Behavior、ScrollingViewBehavior是如何具体实现的。

如果大家有什么疑问或文章中有总结的不对的地方,欢迎大家提出来讨论,谢谢大家。

Python爬虫实战:抓取天气数据并生成可视化图表(完整可复制代码) 工具/库核心作用选型理由requests发送HTTP请求,获取天气网页内容语法简单,上手快,支持Headers配置(反爬)解析HTML页面,提取目标天气数据无需懂复杂XPath,API直观,快速定位标签pandas数据清洗、整理(如日期/温度格式化)一键处理数据格式,与matplotlib无缝适配matplotlib生成可视化图表(折线图/饼图/柱状图)Python主流可视化库,定制性强,支持保存高清图生成随机User-Agent,应对反爬自动更新UA池,避免手动维护。 阅读详情

相关推荐

5G-A无源物联网:深度解析“不插电“智能的底层技术原理

北京移动推出5G-A无源物联网技术,实现电动车标签"零功耗"运行。该技术通过射频能量收集(利用5G-A基站高功率信号转换为电能)和反向散射通信(调制反射信号传输数据)两大核心技术,使设备无需电池即可工作。5G-A相比4G在信号能量密度、通信速率和定位精度等方面显著提升,结合通感一体等创新技术,为无源物联网提供商用基础。该方案已在北京小区试点应用,实现电动车精准定位管理,标签寿命可达5年以上。专家预测,这项技术将大幅降低物联网部署成本,推动"万物智联"时代的到来。

通信行业老兵、物联网从业者,做一个有趣的普通人。 2014

Android CoordinatorLayout Behavior

&nbsp; &nbsp; &nbsp; &nbsp;Behavior是Android Support Design库里面新增的布局概念,主要的作用是用来协调CoordinatorLayout里面直接Child Views之间交互行为的。 特别要注意的点是Behavior只能作用于CoordinatorLayout的直接Child View. &nbsp; &nbsp; &nbsp; ...

旧路 1102

华为eNSP与VMware虚拟机联动实战:从零搭建仿真网络环境

本文详细介绍了如何从零开始搭建华为eNSP与VMware虚拟机的联动仿真网络环境。通过环境准备、网络适配器配置、eNSP与VMware网络集成、安全策略与NAT配置等步骤,帮助读者掌握构建企业级网络实验场景的关键技术。这种组合特别适合网络工程师进阶训练和华为认证考试准备,实现低成本、高灵活性的网络仿真实验。

weixin_30415113的博客 504

红橙Darren视频笔记 Behavior的工作原理源码分析

主要coordinatorlayout的代码来自coordinatorlayout-1.0.0-sources.jar 本文从源码介绍 CoordinatorLayout 的 behavior 怎么工作的 1 behavior的使用方法 不管是自定义behavior还是使用Android自带的behavior, 放的都是全类名,且外面包含CoordinatorLayout ,behavior的所在xml节点必须是CoordinatorLayout 的直接子布局(不能隔层嵌套) Behavior 是layou

积跬步 至千里 429

深入解析国家企业征信系统瑞数6vmp算法逆向实战

本文深入解析了国家企业征信系统所采用的双层防护机制,重点聚焦于瑞数6代vmp算法的逆向实战。文章详细拆解了从加速乐521状态码的绕过,到瑞数412挑战的核心算法还原过程,提供了通过动态Hook、日志分析进行算法逆向,并用Python实现自动化请求链的完整技术方案,旨在为安全研究与技术学习提供参考。

yellow的专栏 612

全栈开发指南:从前端到后端的全面掌握

全栈开发人员(Full Stack Developer)是指能够处理前端和后端开发工作的开发人员。他们需要掌握各种技术和工具,能够独立完成从需求分析、设计、开发到部署的整个流程。这篇博客将详细介绍全栈开发涉及的各个方面,为您提供从入门到进阶的指导。

Where there is a will, there is a way ! 3452

完全搞懂CoordinatorLayout Behavior之源码解析

前面我们已经简单介绍了CoordinatorLayout 的工作机制以及Behavior核心API,原则上是已经可以上手写demo。但是这一节,我想从源码的角度在讲一次CoordinatorLayout 与 Behavior的工作原理。 在看源码之前先要明白一个前提: 1、CoordinatorLayout 之所以能够协调子视图的相关动作,是因为它实现了NestedScrollingParent2...

HopCoder 546

halcon与c#联合编程实现相机控制+图像平移缩放+日志记录+缺陷检测+路径规划

halcon与c#联合编程实现相机控制+图像平移缩放+日志记录+缺陷检测+路径规划 前言 本人近期在工作中遇到需要对某场景下利用海康相机进行图像缺陷检测与对应路径规划。通过对海康相机示例代码进行吸收与借鉴,最终实现了对海康相机的控制,并增加HSmartWindowControl控件,实现图像的实时显示与平移缩放功能;通过listview+toolstrip实现日志显示与类型(提示、警告、错误)分类;同时自行编制算法实现对缺陷的识别以及缺陷外扩矩形范围内的路径规划。 1.日志记录 代码如下(示例):

weixin_37864926的博客 2717

源码看CoordinatorLayout.Behavior原理

在上一篇博客CoordinatorLayout高级用法-自定义Behavior中,我们介绍了如何去自定义一个CoordinatorLayout的Behavior,通过文章也可以看出Behavior在CoordinatorLayout中地位是相当高的,那么今天我们就来接着上篇博客来从源码分析一下Behavior的实现思路,如果你对CoordinatorLayout和Behavior还不熟悉的话,建议先

Loader's Blog 1万+

SpringAi 通过大模型来实现调用自己的Api

摘要 本文介绍了如何利用Spring AI的Tools机制扩展大模型能力,实现业务系统集成。通过@Tool和@ToolParam注解定义工具方法,将订单查询和关闭功能暴露给大模型调用。关键实现包括:1)使用详细描述标注工具方法和参数;2)在ChatClient中注册工具服务;3)集成对话记忆保持上下文。该方法使AI具备操作业务系统的能力,形成"认知-决策-执行"闭环,大幅提升了模型在实际业务场景中的应用价值。

又要搬砖了 836

微信浏览器input[file]拍照点确认后强刷新解决

微信浏览器input强刷新,input h5强刷新,微信浏览器上传图片后刷新,h5表单强刷新,h5调用拍照后返回首页,h5调用拍照后刷新,微信浏览器强制刷新,iOS上微信浏览器input强刷新,iOS上微信浏览器上传图片后强刷新,ios微信浏览器上传图片后页面刷数据,h5在ios浏览器闪频,h5在ios微信打开时强制刷新,ios手机上调用相机后页面刷新,ios手机上调用相机后页面后重置,ios拍照后刷新,ios拍照完页面大刷新

江拥羡橙的博客 1350

MD - CoordinatorLayout源码分析Behavior工作流程

MD - CoordinatorLayout源码分析Behavior工作流程1.概述2.分析前先思考三个问题  1.Behavior要有效果为什么必须要使用CoordinatorLayout包裹  2.为什么自定义的Behavior要放全类名  3.Behavior效果怎么传递的3. 源码分析  3.1.CoordinatorLayout的LayoutParams首先会获取子类属性。进行解析。  ...

weixin_45468727的博客 408

2025.06.18【转录组】|Ribo-seq/small RNA数据分析:rRNA和smRNA比对率统计全流程

本文介绍了一种自动化统计rRNA/smRNA比对率的方法,用于评估Ribo-seq或small RNA测序数据的质量。主要内容包括:分析原理(比对率定义、参考序列来源)、实践流程(构建索引、比对统计)以及结果可视化方法。通过Python和R脚本实现自动化处理,可生成汇总表格和柱状图。比对率结果能反映样品污染程度,建议控制在20%以下。该流程有助于快速评估测序质量,为后续分析提供可靠依据。文中还提供了常见问题解决方案和脚本示例,适用于生物信息学标准化质控环节。

1616

Android CoordinatorLayout和Behavior的源码分析(一)

CoordinatorLayout布局,是“com.android.support:design”包中很重要的一个控件,通过为CoordinatorLayout(以下简称Col)的子view直接设置一个Behavior,可以定制出很棒的交互体验。本文从使用到源码解析来学习Col,源码基于23.3.0版本。 一、CoordinatorLayout和Behavior的源码分析

Zhouxiaomeng0209的博客 659

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

CoordinatorLayout系列(一):Behavior

CoordinatorLayout是google在Material Design上提出的一个布局样式,这个布局的主要功能就是实现一个view跟随另一个view变化,具体变化逻辑,由Behavior来实现,一个好的跟随效果可以展现出很酷的动画,因此这个系列就从Behavior入手,来剖析CoordinatorLayout的细节。 一、使用方法 首先摆出效果: 功能就是实现一个球跟随另一个球移动,两...

whoami_I的博客 671

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Android CoordinatorLayout和Behavior的源码分析(四)

三、Behavior拦截机制 右滑删除view的实现(SwipeDismissBehavior),是通过重写Behavior的下面的方法实现: @Override public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) { switch (Motion

Zhouxiaomeng0209的博客 521

CoordinatorLayout从源码到实战,一文搞懂

/ 今日科技快讯 /近日,苹果、谷歌和微软等科技巨头联合宣布,将在未来一年内在他们控制的所有移动、桌面和浏览器平台上支持无密码登录功能。实际上,这意味着在不远的将来,无密码身份验证将进入所有主要的设备平台,包括安卓和iOS移动操作系统;Chrome、Edge和Safari浏览器;以及Windows和MacOS桌面环境。/ 作者简介 /周六,上班。本篇文章来...

郭霖 526

Android CoordinatorLayout和Behavior的源码分析(二)

2. Behavior如何进行代理的 我们按照以下三种情况分析如何用Behavior进行代理的: 2.1 子view依赖子view状态变化 2.2 嵌套滑动 2.3 Behavior拦截一切事件 具体调用Behavior的方法对应如下: 2.1 public boolean layoutDependsOn(CoordinatorLayout parent, V

Zhouxiaomeng0209的博客 552

CoordinatorLayout+ViewPager+Behavior仿喜马拉雅FM首页

实现方案 ViewPager CoordinatorLayout Behavior ViewPager变换 @Override public void onPageScroll(int enterPosition, int leavePosition, float percent) { try { ...

Fred 1891

Material Design之CoordinatorLayout原理剖析

一.CoordinatorLayout介绍 1.使用场景 一般作为应用的顶层布局,同时也作为一个管理容器,管理与子view或者子view之间的交互。那么都具体管理啥呢?可以分成四个部分 2.作用 ①处理子控件之间依赖下的交互 ②处理子控件之间的嵌套滑动 ③处理子控件的测量与布局 ④处理子控件的事件拦截与响应 以上四个功能,都建立于CoordainatorLayout中提供的一个叫做Behavior的“ 插件”之上。Behavior内部也提供了相应方法来对应这四个不同的功能。那么都有哪些方法呢? 3.Beha

Android小白 2570

CoordinatorLayout解析

CoordinatorLayout 在CoordinatorLayout出现之前,为了处理嵌套滑动逻辑,一般需要继承一个ViewGroup,重写onInterceptTouchEvent和onTouchEvent等方法并实现相应的逻辑,然后在布局中直接引用。这样做有一点非常不好的地方就是:代码冗余,同时处理逻辑也比较繁琐。为此,CoordinatorLayout提供了一套非常完美的解决方案,具体来...

zjf1165的专栏 421

Android CoordinatorLayout和Behavior的源码分析(三)

二、 嵌套滑动机制(NestedScroll) 上面看了Col的使用和自定义Behavior,下面我们来说一下这个效果实现原理,这里加入NestedScroll这个概念,是因为Col实质也是通过NestedScroll实现的各种效果。 在Android嵌套滑动机制出现之前,Android UI的滑动的组件有ListView和ScrollView,ViewPager就会有很多需求是要:L

Zhouxiaomeng0209的博客 666

Android进阶宝典 -- CoordinatorLayout协调者布局原理分析并实现吸顶效果

首先我们先从源码中能够看到,CoordinatorLayout只实现了parent接口(**这里如果不清楚parent接口是干什么的,建议看看前面的文章,不然根本不清楚我讲的是什么**),说明CoordinatorLayout只能作为父容器来使用。

bugyinyin的博客 3583

CoordinatorLayout 完全解析

一、CoordinatorLayout 的作用 CoordinatorLayout 作为一个 “super-powered FrameLayout”,主要有以下两个作用: 作为顶层布局; 作为协调子 View 之间交互的容器。 使用 CoordinatorLayout 需要在 build.gradle 加入: compile 'com.android.support:design:25.1.0' 二、CoordinatorLayout 与 FloatingActionButton 2.1 F

zhangmiaoping23的专栏 4612

android layout 界面开发,Android开发之CoordinatorLayout使用详解一

官网描述为:CoordinatorLayout是一个增强版的FrameLayout(继承自ViewGroup)用途:1、作为应用的顶层视图。2、作为一个可以指定子View之间相互作用的容器,通过给CoordinatorLayout的子View指定CoordinatorLayout.Behavior 来定义子view之间的相互作用。(你可以想象成:CoordinatorLayout相当于在两个Vie...

weixin_31260665的博客 613

完全搞懂CoordinatorLayout Behavior 你能做些什么

国外的一些应用经常可以看到一些比较炫酷的滑动动画交互,例如折叠、 放大缩小、平移、透明度变化等等,最近几年国内也有很多app逐渐使用了这种动画。比如这些。 只有完全搞懂CoordinatorLayout Behavior 相关的知识点,包括原理我们才能够对上面的各种动态效果信手拈来。在这之前我说一个我自己的经历,在我自己项目中,我之前第一次看到58同城的那个首页效果时就想搬到我自己的项目中...

HopCoder 436

CoordinatorLayout协调者布局原理分析并实现吸顶效果

首先我们先从源码中能够看到,CoordinatorLayout只实现了parent接口(这里如果不清楚parent接口是干什么的,建议看看前面的文章,不然根本不清楚我讲的是什么),说明CoordinatorLayout只能作为父容器来使用。复制代码所以对于CoordinatorLayout来说,它的主要作用就是用来管理子View或者子View之间的联动交互。所以在上一篇文章中,我们介绍的NestScroll嵌套滑动机制,它其实能够实现child与parent的嵌套滑动,但是是1对1的;

chuyouyinghe的专栏 1438
上一篇: Android进程间通信机制详解-AIDL
下一篇: 使用FFmpeg将pcm数据编码为aac
zakeper
博客等级 码龄17年 16粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值