利用Android自帶嵌套滑動控件解決滑動沖突(NestingScroll,CoordinatorLayout與Behavior)

實(shí)現(xiàn)嵌套滑動有三種方案:

1. 純事件攔截與派發(fā)方案
2. 基于NestingScroll機(jī)制的實(shí)現(xiàn)方案
3. 基于CoordinatorLayout與Behavior的實(shí)現(xiàn)方案

第一種方案:靈活性最高,也最繁瑣览露。因?yàn)槭录臄r截是一錘子買賣汇陆,誰攔截了事件,當(dāng)前手勢接下來的事件都會交給攔截者來處理夺巩,除非等到下一次Down事件觸發(fā)。這很不方便多個View對同一個事件進(jìn)行處理。

第二種方案:其實(shí)就是對原始的事件攔截機(jī)制做了一層封裝海诲,通過子View實(shí)現(xiàn)NestedScrollingChild接口级野,父View實(shí)現(xiàn)NestedScrollingParent 接口页屠,并且在子View和父View中都分別有一個NestedScrollingChildHelper粹胯、NestedScrollingParentHelper來代理了父子之間的聯(lián)動,開發(fā)者不用關(guān)心具體是怎么聯(lián)動的辰企,這一點(diǎn)很方便风纠。

第三種方案:其實(shí)就是對原始的NestedScrolling機(jī)制再次做了一層封裝。CoordinatorLayout默認(rèn)實(shí)現(xiàn)了NestedScrollingParent接口牢贸。第二種方案只能由子View通知父View竹观,但有時候除了需要通知父View,還需要通知兄弟View,這個時候就該是Behavior出場了潜索。

第一種方案:純事件攔截與派發(fā)方案

文章中有事件分發(fā)的相關(guān)內(nèi)容 View事件沖突和解決實(shí)例

第二種方案:NestingScroll機(jī)制

使用這種方式臭增,一般需要繼承NestedScrollingChild和NestedScrollingParent接口。同時NestedScrollingChildHelper和NestedScrollingScrollingParentHelper進(jìn)行輔助竹习。像RecyclerView誊抛,CoordinatorLayout等一些控件已經(jīng)實(shí)現(xiàn)NestedScrollingChild,NestedScrollingParent接口整陌。下面介紹一下接口中方法的作用拗窃。

NestedScrollingChild接口

public interface NestedScrollingChild {  
    /** 
     * 設(shè)置嵌套滑動是否能用
     *  @param enabled true to enable nested scrolling, false to disable
     */  
    public void setNestedScrollingEnabled(boolean enabled);  
    /** 
     * 判斷嵌套滑動是否可用 
     * @return true if nested scrolling is enabled
     */  
    public boolean isNestedScrollingEnabled();  
    /** 
     * 開始嵌套滑動
     * @param axes 表示方向軸,有橫向和豎向
     */  
    public boolean startNestedScroll(int axes);  
    /** 
     * 停止嵌套滑動 
     */  
    public void stopNestedScroll();  
    /** 
     * 判斷是否有父View 支持嵌套滑動 
     * @return whether this view has a nested scrolling parent
     */  
    public boolean hasNestedScrollingParent();  
    /** 
     * 在子View的onInterceptTouchEvent或者onTouch中泌辫,調(diào)用該方法通知父View滑動的距離
     * @param dx  x軸上滑動的距離
     * @param dy  y軸上滑動的距離
     * @param consumed 父view消費(fèi)掉的scroll長度
     * @param offsetInWindow   子View的窗體偏移量
     * @return 支持的嵌套的父View 是否處理了 滑動事件 
     */  
    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow);  
    /** 
     * 子view處理scroll后調(diào)用
     * @param dxConsumed x軸上被消費(fèi)的距離(橫向) 
     * @param dyConsumed y軸上被消費(fèi)的距離(豎向)
     * @param dxUnconsumed x軸上未被消費(fèi)的距離 
     * @param dyUnconsumed y軸上未被消費(fèi)的距離 
     * @param offsetInWindow 子View的窗體偏移量
     * @return  true if the event was dispatched, false if it could not be dispatched.
     */  
    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,  
          int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow);  
    /** 
     * 滑行時調(diào)用 
     * @param velocityX x 軸上的滑動速率
     * @param velocityY y 軸上的滑動速率
     * @param consumed 是否被消費(fèi) 
     * @return  true if the nested scrolling parent consumed or otherwise reacted to the fling
     */  
    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);  
    /** 
     * 進(jìn)行滑行前調(diào)用
     * @param velocityX x 軸上的滑動速率
     * @param velocityY y 軸上的滑動速率 
     * @return true if a nested scrolling parent consumed the fling
     */  
    public boolean dispatchNestedPreFling(float velocityX, float velocityY);  
}

NestedScrollingParent接口

public interface NestedScrollingParent {
    /**
     * 調(diào)用child的startNestedScroll()來發(fā)起嵌套滑動流程(實(shí)質(zhì)上是尋找能夠配合child進(jìn)行嵌套滾動的parent)随夸。
     * parent的onStartNestedScroll()會被調(diào)用,若此方法返回true震放,則OnNestScrollAccepted()也會被調(diào)用逃魄。
     * */
    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes);

    public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes);

    public void onStopNestedScroll(View target);
    /**
     * 后于child滾動
     * @param target
     * @param dxConsumed
     * @param dyConsumed
     * @param dxUnconsumed
     * @param dyUnconsumed
     */
    public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
            int dxUnconsumed, int dyUnconsumed);
    /**
     * 先于child滾動
     * 前3個為輸入?yún)?shù),最后一個是輸出參數(shù)
     * @param target
     * @param dx
     * @param dy  向上是正的澜搅,向下是負(fù)的 是差值
     * @param consumed
     */
    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed);

    public boolean onNestedFling(View target, float velocityX, 
                                                      float velocityY,boolean consumed);

    public boolean onNestedPreFling(View target, float velocityX, float velocityY);

    public int getNestedScrollAxes();
}

當(dāng) NestedScrollingChild(下文用Child代替) 要開始滑動的時候會調(diào)用 onStartNestedScroll ,然后交給代理類NestedScrollingChildHelper(下文ChildHelper代替)的onStartNestedScroll請求給最近的NestedScrollingParent(下文Parent代替).
當(dāng)ChildHelper的onStartNestedScroll方法 返回 true 表示同意一起處理 Scroll 事件的時候時候,ChildHelper會通知Parent回調(diào)onNestedScrollAccepted 做一些準(zhǔn)備動作
當(dāng)Child 要開始滑動的時候,會先發(fā)送onNestedPreScroll,交給ChildHelper的onNestedPreScroll 請求給Parent ,告訴它我現(xiàn)在要滑動多少距離,你覺得行不行,這時候Parent 根據(jù)實(shí)際情況告訴Child 現(xiàn)在只允許你滑動多少距離.然后 ChildHelper根據(jù) onNestedPreScroll 中回調(diào)回來的信息對滑動距離做相對應(yīng)的調(diào)整.
在滑動的過程中 Child 會發(fā)送onNestedScroll通知ChildeHelpaer的onNestedScroll告知Parent 當(dāng)前 Child 的滑動情況.
當(dāng)要進(jìn)行滑行的時候,會先發(fā)送onNestedFling 請求給Parent,告訴它 我現(xiàn)在要滑行了,你說行不行, 這時候Parent會根據(jù)情況告訴 Child 你是否可以滑行.
Child 通過onNestedFling 返回的 Boolean 值來覺得是否進(jìn)行滑行.如果要滑行的話,會在滑行的時候發(fā)送onNestedFling 通知告知 Parent 滑行情況.
當(dāng)滑動事件結(jié)束就會child發(fā)送onStopNestedScroll通知 Parent 去做相關(guān)操作.

NestedScroll嵌套滑動事件流程圖

NestedScroll嵌套滑動事件.png

最后來總結(jié)一下整個流程伍俘,分為四個步驟:

  • 步驟一:子View的ACTION_DOWN調(diào)用startNestedScroll---->父View的onStartNestedScroll判斷是否要一起滑動,父ViewonNestedScrollAccepted同意協(xié)同滑動
  • 步驟二:子View的ACTION_MOVE調(diào)用dispatchNestedPreScroll---->父View的onNestedPreScroll在子View滑動之前先進(jìn)行滑動并消耗需要的距離---->父View完成該次滑動之后返回消耗的距離勉躺,子View在剩下的距離中再完成自己需要的滑動
  • 步驟三:子View滑動完成之后調(diào)用dispatchNestedScroll---->父View的onNestedScroll處理父View和子View之前滑動剩余的距離
  • 步驟四:子View的ACTION_UP調(diào)用stopNestedScroll---->父View的onStopNestedScroll完成滑動收尾工作

這樣癌瘾,子View和父View的一系列嵌套滑動就完成了,可以看出來整個嵌套滑動還是靠子View來推動父View進(jìn)行滑動的饵溅,這也解決了在傳統(tǒng)的滑動事件中一旦事件被子View處理了就很難再分享給父View共同處理的問題妨退,這也是嵌套滑動的一個特點(diǎn)。
NestedScrolling 機(jī)制能夠讓父 View 和子 View 在滾動式進(jìn)行配合蜕企,而要實(shí)現(xiàn)這樣的交互機(jī)制咬荷,首先父 view 要實(shí)現(xiàn) NestedScrollingParent 接口,而子 View 需要實(shí)現(xiàn) NestedScrollingChild 接口轻掩,在這套機(jī)制中子 View是發(fā)起者幸乒,父 view 是接受回調(diào)并做出響應(yīng)的。

自定義MyNestedScrollingParent實(shí)現(xiàn)下面效果

NestedScroll.gif
布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.example.chenpeng.julyapplication.NestedScrolling.MyNestedScrollParent
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:src="@mipmap/ic_launcher"/>
        <View
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:background="#009987"/>
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </android.support.v7.widget.RecyclerView>
    </com.example.chenpeng.julyapplication.NestedScrolling.MyNestedScrollParent>

</LinearLayout>

自定義MyNestedScrollingParent實(shí)現(xiàn)NestedScrollingParent接口

在源碼中已經(jīng)相關(guān)解釋唇牧。主要講一個方法ViewCompat.canScrollVertically(target, -1)罕扎,判斷target控件是否可以上滑聚唐。

在APi14之后,官方提供了canScrollVertically(int direction)方法腔召,所以API14之后判斷非常方便杆查,官方文檔的解釋如下:
image.png

翻譯下來就是:當(dāng)direction>0時,判斷是否可以下滑臀蛛,當(dāng)direction<0時亲桦,判斷是否可以上滑

public class MyNestedScrollParent extends LinearLayout implements NestedScrollingParent {

    private ImageView mImageView;
    private RecyclerView mRecyclerView;
    private int mImageViewHeight;
    private NestedScrollingParentHelper mNestedScrollingParentHelper;
    private OverScroller mScroller;
    private static final String TAG = "MyNestedScrollParent";

    public MyNestedScrollParent(Context context) {
        this(context,null);
        Log.i(TAG, "MyNestedScrollParent: 1");
    }

    public MyNestedScrollParent(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
        Log.i(TAG, "MyNestedScrollParent: 2");
    }

    public MyNestedScrollParent(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mNestedScrollingParentHelper = new NestedScrollingParentHelper(this);
        mScroller = new OverScroller(context);
        Log.i(TAG, "MyNestedScrollParent: 3");
    }


    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mImageView = (ImageView) getChildAt(0);
        mRecyclerView = (RecyclerView) getChildAt(2);
        mImageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mImageViewHeight = mImageView.getMeasuredHeight();
                Log.i(TAG, "onGlobalLayout: getMeasuredHeight = " + mImageViewHeight + " , getHeight = " + mImageView.getHeight());
            }
        });
    }

    /**
     * 調(diào)用child的startNestedScroll()來發(fā)起嵌套滑動流程(實(shí)質(zhì)上是尋找能夠配合child進(jìn)行嵌套滾動的parent)。
     * parent的onStartNestedScroll()會被調(diào)用浊仆,若此方法返回true客峭,則OnNestScrollAccepted()也會被調(diào)用。
     * */
    @Override
    public boolean onStartNestedScroll(@NonNull View child, @NonNull View target, int axes) {
        //在此可以判斷參數(shù)target是哪一個子view以及滾動的方向氧卧,然后決定是否要配合其進(jìn)行嵌套滾動
        Log.i(TAG, "onStartNestedScroll: ");
        //垂直滑動返回true
        return (axes & SCROLL_AXIS_VERTICAL) != 0;
    }

    @Override
    public void onNestedScrollAccepted(@NonNull View child, @NonNull View target, int axes) {
        mNestedScrollingParentHelper.onNestedScrollAccepted(child,target,axes);
        Log.i(TAG, "onNestedScrollAccepted: ");
    }

    @Override
    public void onStopNestedScroll(@NonNull View target) {
        mNestedScrollingParentHelper.onStopNestedScroll(target);
        Log.i(TAG, "onStopNestedScroll: ");
    }

    /**
     * 后于child滾動
     * @param target
     * @param dxConsumed
     * @param dyConsumed
     * @param dxUnconsumed
     * @param dyUnconsumed
     */
    @Override
    public void onNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {

    }

    /**
     * 先于child滾動
     * 前3個為輸入?yún)?shù)桃笙,最后一個是輸出參數(shù)
     * @param target
     * @param dx
     * @param dy  向上是正的氏堤,向下是負(fù)的 是差值
     * @param consumed
     */
    @Override
    public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed) {
        Log.i(TAG, "onNestedPreScroll: dy = " + dy + " , getScrollY() = " + getScrollY() + ", mRecyclerView.getChildAt(0).getTop() = "+ mRecyclerView.getChildAt(0).getTop());
        if((dy>0 && getScrollY() < mImageViewHeight ||
                (dy < 0 && getScrollY() > 0 && (!ViewCompat.canScrollVertically(target, -1))))){//!ViewCompat.canScrollVertically(target, -1)可以判斷是否可繼續(xù)下滑
            scrollBy(0,dy);
            consumed[1] = dy;//告訴child我消費(fèi)了多少
        }
    }



    /**
     *scrollBy內(nèi)部會調(diào)用scrollTo , 限制滾動范圍
     */
    @Override
    public void scrollTo(int x, int y) {
        if (y < 0) {
            y = 0;
        }
        if (y > mImageViewHeight) {
            y = mImageViewHeight;
        }

        super.scrollTo(x, y);
    }

    @Override
    public boolean onNestedFling(@NonNull View target, float velocityX, float velocityY, boolean consumed) {
        //是否消費(fèi)了fling
        if (getScrollY() >= mImageViewHeight)
            return false;
        fling((int) velocityY);
        return true;
    }

    @Override
    public boolean onNestedPreFling(@NonNull View target, float velocityX, float velocityY) {
        return false;
    }

    public void fling(int velocityY)
    {
        mScroller.fling(0, getScrollY(), 0, velocityY, 0, 0, 0, mImageViewHeight);
        invalidate();
    }

    @Override
    public void computeScroll()
    {
        if (mScroller.computeScrollOffset())
        {
            scrollTo(0, mScroller.getCurrY());
            invalidate();
        }
    }


    @Override
    public int getNestedScrollAxes() {
        return mNestedScrollingParentHelper.getNestedScrollAxes();
    }
}

第三種方案:基于CoordinatorLayout與Behavior的實(shí)現(xiàn)方案

通過依賴compile'com.android.support:design:26.1.0'沙绝,中的CoordinatorLayout,AppBarLayout鼠锈,CollapsingToolbarLayout闪檬,F(xiàn)loatingActionButton中控件實(shí)現(xiàn)下面的例子。


CoordinatorLayout.gif
AppBarLayou:

1.AppbarLayout:繼承了LinearLayout(默認(rèn)的AppBarLayout是垂直方向)购笆,它是為了Material Design設(shè)計的App Bar粗悯,它的作用是把AppBarLayout包裹的內(nèi)容都作為AppBar。說白了它的出現(xiàn)就是為了和CoordinatorLayout搭配使用同欠,實(shí)現(xiàn)一些炫酷的效果的样傍。沒有CoordinatorLayout,它和Linearlayout沒區(qū)別铺遂。

2.app:layout_scrollFlags=”scroll|enterAlways”
AppBarLayout的直接子控件可以設(shè)置的屬性:layout_scrollFlags

  • scroll|exitUntilCollapsed 如果AppBarLayout的直接子控件設(shè)置該屬性,該子控件可以滾動,向上滾動NestedScrollView出父布局(一般為CoordinatorLayout)時,會折疊到頂端,向下滾動時NestedScrollView必須滾動到最上面的時候才能拉出該布局
  • scroll|enterAlways:只要向下滾動該布局就會顯示出來,只要向上滑動該布局就會向上收縮
  • scroll|enterAlwaysCollapsed:向下滾動NestedScrollView到最底端時該布局才會顯示出來
    如果不設(shè)置改屬性,則改布局不能滑動

3.細(xì)心的朋友可能在NestedScrollView中發(fā)現(xiàn)這么一條屬性

app:layout_behavior="@string/appbar_scrolling_view_behavior"

它的核心就在于Behavior類衫哥。我們給CoordinatorLayout的子View設(shè)置一個Behavior,就可以接管該View自身的一些事件與其他的View之間的交互事件襟锐。包括 touch,measure,layout等事件撤逢。我們在NestedScrollView設(shè)定的Android提供的Behavior,app:layout_behavior="@string/appbar_scrolling_view_behavior">,其中的string是Behavior的絕對路徑。
CoordinatorLayout中Behavior介紹與簡單使用

CollapsingToolbarLayout

我們在AppBarLayout中添加CollapsingToolbarLayout粮坞。Collapsing是折疊的意思蚊荣。見名知意,CollapsingToolbarLayout的作用是提供了一個可以折疊的Toolbar莫杈,它繼承至FrameLayout互例。
1.大家一定要弄清楚,它們之間的包含關(guān)系:
AppBarLayout >CollapsingToolbarLayout>Toolbar

2.CollapsingToolbarLayout作為AppBarLayout的直接子控件筝闹,也要設(shè)置app:layout_scrollFlags屬性

3.app:layout_collapseMode屬性是折疊模式敲霍,它是CollapsingToolbarLayout的直接子控件需要設(shè)置的,它的取值如下:

  • pin:在滑動過程中,此自布局會固定在它所在的位置不動,直到CollapsingToolbarLayout全部折疊或者全部展開
  • parallax:視察效果,在滑動過程中,不管上滑還是下滑都會有視察效果,不知道什么事視察效果自己看gif圖(layout_collapseParallaxMultiplier視差因子 0~1之間取值,當(dāng)設(shè)置了parallax時可以配合這個屬性使用,調(diào)節(jié)自己想要的視差效果)
  • 不設(shè)置:跟隨NestedScrollView的滑動一起滑動,NestedScrollView滑動多少距離他就會跟著走多少距離
contentScrim折疊后的顏色也是展開時的漸變顏色,效果超贊. 
title標(biāo)題,如果設(shè)置在折疊時會動畫的顯示到折疊后的部分上面,拉開時會展開,很好玩的 
expandedTitleMargin當(dāng)title文字展開時文字的margin,當(dāng)然還有marginTop等屬性,腦補(bǔ)吧 
app:collapsedTitleTextAppearance=”@style/Text”折疊時title的樣式里面可以定義字體大小顏色等 
app:collapsedTitleTextAppearance=”@style/Text1”折疊時title的樣式里面可以定義字體大小顏色等 
當(dāng)然還有一些,自己試試吧,現(xiàn)在的這些已經(jīng)完全夠用了
FloatingActionButton
app:layout_anchor="@id/app_bar" //在哪個控件上
app:layout_anchorGravity="bottom|right" //具體位置
實(shí)現(xiàn)上面效果的布局文件
<?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:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="170dp"
            app:contentScrim="#ff2077ff"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@mipmap/bg"/>

            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="parallax"
                app:title="Title"/>
        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>
    <android.support.v4.widget.NestedScrollView
        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="match_parent"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)1"
                android:textSize="20sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)2"
                android:textSize="20sp" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)1"
                android:textSize="20sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)2"
                android:textSize="20sp" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)1"
                android:textSize="20sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)2"
                android:textSize="20sp" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)1"
                android:textSize="20sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)2"
                android:textSize="20sp" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)1"
                android:textSize="20sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)2"
                android:textSize="20sp" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)1"
                android:textSize="20sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="測試數(shù)據(jù)2"
                android:textSize="20sp" />
        </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"
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="bottom|right"
        app:srcCompat="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末俊马,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子肩杈,更是在濱河造成了極大的恐慌柴我,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扩然,死亡現(xiàn)場離奇詭異艘儒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)夫偶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門界睁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兵拢,你說我怎么就攤上這事翻斟。” “怎么了说铃?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵访惜,是天一觀的道長。 經(jīng)常有香客問我腻扇,道長债热,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任幼苛,我火速辦了婚禮窒篱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舶沿。我一直安慰自己墙杯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布括荡。 她就那樣靜靜地躺著高镐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪一汽。 梳的紋絲不亂的頭發(fā)上避消,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音召夹,去河邊找鬼岩喷。 笑死,一個胖子當(dāng)著我的面吹牛监憎,可吹牛的內(nèi)容都是我干的纱意。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鲸阔,長吁一口氣:“原來是場噩夢啊……” “哼偷霉!你這毒婦竟也來了迄委?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤类少,失蹤者是張志新(化名)和其女友劉穎叙身,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硫狞,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡信轿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了残吩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片财忽。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖泣侮,靈堂內(nèi)的尸體忽然破棺而出即彪,到底是詐尸還是另有隱情,我是刑警寧澤活尊,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布隶校,位于F島的核電站,受9級特大地震影響酬凳,放射性物質(zhì)發(fā)生泄漏惠况。R本人自食惡果不足惜遭庶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一宁仔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧峦睡,春花似錦翎苫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至龙屉,卻和暖如春呐粘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背转捕。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工作岖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人五芝。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓痘儡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親枢步。 傳聞我的和親對象是個殘疾皇子沉删,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容