Md系列3、CoordinatorLayout 里 Toobar和TabLayout等發(fā)生的一系列故事

本文出自 “阿敏其人” 簡書博客,轉(zhuǎn)載或引用請注明出處。

本文主要涉及android里面md設(shè)計的幾個控件
CoordinatorLayout
AppBarLayout
CollapsingToolbarLayout
TabLayout

一、看,看出陌生

本文假設(shè)是讀者還沒使用過adnroid support md的控件,先來看一下圖片:

海賊王演示.gif

我們看到,標題欄可以伸縮,而且頂部狀態(tài)欄是沉浸的,顏色沉浸,圖片沉浸。

噢,那看看是怎么實現(xiàn)的吧。打開布局文件發(fā)現(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:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">  

        <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/ivImage"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:transitionName="transition_book_img"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7" />

            <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>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.design.widget.TabLayout
            android:id="@+id/sliding_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabGravity="fill"
            app:tabMode="fixed" />

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
    
</android.support.design.widget.CoordinatorLayout>

一看,瓦擦,好多沒見過

CoordinatorLayout 
AppBarLayout
CollapsingToolbarLayout
TabLayout

android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:transitionName="transition_book_img"
app:layout_collapseParallaxMultiplier="0.7" 
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
app:tabGravity="fill" 
app:tabMode="fixed"

好多東西,都是什么鬼。不過還好,拋去屬性,控件不認識的也就4個。
他們的包含關(guān)系大概如下:

Paste_Image.png

嗯,那就先看看這幾個控件吧,熟悉一下。

二、CoordinatorLayout

Android dev CoordinatorLayout官網(wǎng)學習資料

人家Google這么說

CoordinatorLayout is a super-powered FrameLayout.

CoordinatorLayout is intended for two primary use cases:

As a top-level application decor or chrome layout
As a container for a specific interaction with one or more child views
By specifying Behaviors for child views of a CoordinatorLayout you can provide many different interactions within a single parent and those views can also interact with one another. View classes can specify a default behavior when used as a child of a CoordinatorLayout using the DefaultBehavior annotation.

Behaviors may be used to implement a variety of interactions and additional layout modifications ranging from sliding drawers and panels to swipe-dismissable elements and buttons that stick to other elements as they move and animate.

Children of a CoordinatorLayout may have an anchor. This view id must correspond to an arbitrary descendant of the CoordinatorLayout, but it may not be the anchored child itself or a descendant of the anchored child. This can be used to place floating views relative to other arbitrary content panes.

大概也就是這么說:

CoordinatorLayout 是一個加強版的FrameLayout。(繼承自ViewGroup)

主要有兩個用途:
1、作為頂層應(yīng)用的裝飾或者chrome布局
2、作為一個容器來協(xié)調(diào)一個或多個子views

CoordinatorLayout,Coordinator有協(xié)調(diào)的意思。它是一個可以組織眾多子view之間互相協(xié)作的一個ViewGroup

CoordinatorLayout 有一個Behavior,這個對象可以說讓子view直接知道了彼此的存在,通過不同的狀態(tài)監(jiān)聽控制其他子View的移動或者隱藏與顯示等。

簡單使用

1、使用之前引入

compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'

2、布局文件

<?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.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        android:src="@mipmap/ic_launcher" />

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

3、Activity

public class CoordinatorLayoutActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_coordinator);
        findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Snackbar.make(view,"FAB",Snackbar.LENGTH_LONG)
                        .setAction("cancel", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                //這里的單擊事件代表點擊消除Action后的響應(yīng)事件
                            }
                        })
                        .show();
            }
        });
    }
}

4、效果:

應(yīng)用.gif
  • 亮點在哪里?
    當我們按下Snackbar的時候彈出來提示的時候,按鈕的會做一個上移的動畫,而我們的代碼卻不需要做什么。

至于為什么會這么動,那是因為FloatingActionButton默認使用FloatingActionButton.Behavior。
關(guān)于Behavior,后面在說。

  • 什么是Snackbar?
    簡單來說可以這么說,在Md的世界里 Snackbar 是 作為代替 Toast 而存在的好東西。

當然如果你不信這個動畫是因為CoordinatorLayout才形成的,那么好,我們把代碼改一下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        android:src="@mipmap/ic_launcher" />

</RelativeLayout>

效果就變成這樣子了

按鈕無動畫.gif

在里面CoordinatorLayout的世界里,Behavior占據(jù)了一個特別重要的地位。
然后在上面Snackbar的小示例里面,因為系統(tǒng)默認的關(guān)系我們連Behavior的身影都看到。那么下面還是來弄一個小demo,關(guān)于Behavior。

CoordinatorLayout里面的直接子View一般是:AppBarLayout+NestedScrollView。
又涉及到了新東西,NestedScrollView還好,簡單認為一個是md涉及里面的ScrollView。
至于AppBarLayout,還是可以掰扯的,另起一點,開講。

深入理解Android開發(fā)中的CoordinatorLayout Behavior

二、伸縮 —— CoordinatorLayout + AppBarLayout + NestedScrollView

CoordinatorLayout里面的直接子View一般是:AppBarLayout+NestedScrollView。

NestedScrollView

Google NestedScrollView文檔

NestedScrollView is just like ScrollView, 
but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. 
Nested scrolling is enabled by default.

AppBarLayout 是什么?

一起來看看Google給我們的AppBarLayout 說明書吧:

AppBarLayout is a vertical LinearLayout which implements many of the features of material designs app bar concept, namely scrolling gestures.

Children should provide their desired scrolling behavior through setScrollFlags(int) and the associated layout xml attribute: app:layout_scrollFlags.

This view depends heavily on being used as a direct child within a CoordinatorLayout. If you use AppBarLayout within a different ViewGroup, most of it's functionality will not work.

AppBarLayout also requires a separate scrolling sibling in order to know when to scroll. The binding is done through the AppBarLayout.ScrollingViewBehavior behavior class, meaning that you should set your scrolling view's behavior to be an instance of AppBarLayout.ScrollingViewBehavior. A string resource containing the full class name is available.

Google大概就是說:

AppBarLayout是一個實現(xiàn)了很多material designs特性的垂直的LinearLayout,它能響應(yīng)滑動事件。

  • 1、AppBarLayout最好是CoordinatorLayout的直接子view

  • 2、AppBarLayout的子view
    需要設(shè)置app:layout_scrollFlags ,或者是在代碼中調(diào)用setScrollFlags()設(shè)置這個屬性。

  • 3、AppBarLayout的兄弟節(jié)點(或兄弟節(jié)點的子view可以滾動):
    需要指定behavior屬性為AppBarLayout.ScrollingViewBehavior(可以使用一個內(nèi)置的string表示這個默認的實例@string/appbar_scrolling_view_behavior.),才能發(fā)揮它的最大的作用

瓦擦,看文字費勁,那么看Google的示例偽代碼吧,感覺世界瞬間清爽很多

 <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">
    <!-- 3、指定behavior屬性為AppBarLayout.ScrollingViewBehavior -->
     <android.support.v4.widget.NestedScrollView
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             app:layout_behavior="@string/appbar_scrolling_view_behavior">

         <!-- Your scrolling content -->

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

     <!--1、AppBarLayout最好是CoordinatorLayout的直接子view -->
     <android.support.design.widget.AppBarLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent">
        <!--2 、AppBarLayout的子view:需要設(shè)置app:layout_scrollFlags-->
         <android.support.v7.widget.Toolbar
                 ...
                 app:layout_scrollFlags="scroll|enterAlways"/>

         <android.support.design.widget.TabLayout
                 ...
                 app:layout_scrollFlags="scroll|enterAlways"/>

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

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

.
.

好像是那么回事了,來吧,

來一個demo吧

1、布局文件

<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">

    <!--1、AppBarLayout最好是CoordinatorLayout的直接子view -->
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <!--2 、AppBarLayout的子view:需要設(shè)置app:layout_scrollFlags-->
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:title="Title"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <ImageView
            android:id="@+id/mIv"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:scaleType="centerCrop"
            android:background="@mipmap/lf"
            />

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

    <!-- 3、指定behavior屬性為AppBarLayout.ScrollingViewBehavior -->
    <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="180dp"
                android:layout_margin="10dp"
                android:background="#6660c6df"
                android:gravity="center"
                android:text="折"
                android:textSize="26dp"
                android:transitionName="zi" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="180dp"
                android:layout_margin="10dp"
                android:background="#6660c6df"
                android:gravity="center"
                android:text="折疊"
                android:textSize="26dp"
                android:transitionName="zi" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="180dp"
                android:layout_margin="10dp"
                android:background="#6660c6df"
                android:gravity="center"
                android:text="折疊示"
                android:textSize="26dp"
                android:transitionName="zi" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="180dp"
                android:layout_margin="10dp"
                android:background="#6660c6df"
                android:gravity="center"
                android:text="折疊示例"
                android:textSize="26dp"
                android:transitionName="zi" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

2、Activity

public class CoorSimpleActivity extends AppCompatActivity {

    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_coor_simple);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle("Title");
        setSupportActionBar(toolbar);
    }
}

3、sytle

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowTranslucentStatus">true</item> <!--重要-->
    </style>

</resources>

4、效果圖

TabLayout.gif

利用我們說的三點,我們在xml里面都做了。效果也實現(xiàn)了。

那么問題來了,ayout_scrollFlags這些值是個什么意思:

scroll:所有想滾動出屏幕的view都需要設(shè)置這個flag, 沒有設(shè)置這個flag的view將被固定在屏幕頂部。

enterAlways:這個flag讓任意向下的滾動都會導(dǎo)致該view變?yōu)榭梢姡瑔⒂每焖佟胺祷啬J健薄?/p>

enterAlwaysCollapsed:當你的視圖已經(jīng)設(shè)置minHeight屬性又使用此標志時,你的視圖只能已最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度。

exitUntilCollapsed:滾動退出屏幕,最后折疊在頂端。

注意:
scroll、enterAlways兩種模式基本是需要一起使用的
enterAlways、enterAlwaysCollapsed兩種模式基本只有在CollapsingToolbarLayout才有用
也就是說,這些flag的使用場景,基本已經(jīng)固定了。

PS : 所有使用scroll flag的view都必須定義在沒有使用scroll flag的view的前面,這樣才能確保所有的view從頂部退出,留下固定的元素。

三、AppBarLayout + CollapsingToolbarLayout

在說CollapsingToolbarLayout之前,我們想一想md對于Toolbar我們都經(jīng)歷了什么。
1、你說ActionBar不好,要換成Toolbar,好,我換,從此我有了規(guī)范的標題欄。
2、你說利用CoordinatorLayout 可以協(xié)調(diào)子View,做隱藏或者顯示,嗯好,我把最外層換成CoordinatorLayout 。
3、你說AppBarLayout是一個實現(xiàn)了很多material designs特性的垂直的LinearLayout,它能響應(yīng)滑動事件。好,哥們在Toolbar外面加一層AppBarLayout
4、現(xiàn)在,你說垂直的東西還不夠自然,有一個android自己支持的叫做 CollapsingToolbarLayout 可折疊伸縮的Toolbar。好,哥們?yōu)榱藰祟}欄,為了md,再折騰。

吃完辣條,趕緊翻翻CollapsingToolbarLayout說明書

CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar. It is designed to be used as a direct child of a AppBarLayout. CollapsingToolbarLayout contains the following features:

Collapsing title
A title which is larger when the layout is fully visible but collapses and becomes smaller as the layout is scrolled off screen. You can set the title to display via setTitle(CharSequence). The title appearance can be tweaked via the collapsedTextAppearance and expandedTextAppearance attributes.
Content scrim
A full-bleed scrim which is show or hidden when the scroll position has hit a certain threshold. You can change this via setContentScrim(Drawable).
Status bar scrim
A scrim which is show or hidden behind the status bar when the scroll position has hit a certain threshold. You can change this via setStatusBarScrim(Drawable). This only works on LOLLIPOP devices when we set to fit system windows.
Parallax scrolling children
Child views can opt to be scrolled within this layout in a parallax fashion. See COLLAPSE_MODE_PARALLAX and setParallaxMultiplier(float).
Pinned position children
Child views can opt to be pinned in space globally. This is useful when implementing a collapsing as it allows the Toolbar to be fixed in place even though this layout is moving. See COLLAPSE_MODE_PIN.
Do not manually add views to the Toolbar at run time. We will add a 'dummy view' to the Toolbar which allows us to work out the available space for the title. This can interfere with any views which you add.

谷歌大概這么說:

CollapsingToolbarLayout作用是提供了一個可以折疊的Toolbar
(CollapsingToolbarLayout是一個實現(xiàn)了折疊工具欄效果Toolbar的包裝器,它被設(shè)計為AppBarLayout的直接子View。)

  • 1、 折疊標題 Collapsing title
    當布局完全顯示時,標題會變大;當布局滑出屏幕時,標題會變小。你可以通過setTitle()來設(shè)置標題,標題的外觀可以通過collapsedTextAppearance()和expandedTextAppearance()方法來調(diào)整屬性。
collapsingToolbarLayout.setTitle("蒙奇-D-路飛");
collapsingToolbarLayout.setExpandedTitleColor(Color.YELLOW); // 標題展示時顏色
collapsingToolbarLayout.setCollapsedTitleTextColor(Color.WHITE); // 標題收縮時的顏色
  • 2、沉浸式內(nèi)容 Content scrim
    ToolBar被折疊到頂部固定時候的背景,你可以調(diào)用setContentScrim(Drawable)方法改變背景或者 在屬性中使用 app:contentScrim=”?attr/colorPrimary”來改變背景。
  • 3、沉浸式狀態(tài)欄 Status bar scrim
    當滾動到一定值時顯示或者隱藏在狀態(tài)欄后面的沉浸式效果,可以通過setStatusBarScrim()
    方法來設(shè)置,僅在Android5.0并且設(shè)置了適應(yīng)窗口(fitsSystemWindows="true"
    )時有用。
  • 4、視差滾動 Parallax scrolling children
    該布局中的子View可以選擇視察滾動的方式來滾動,詳見LayoutParams#COLLAPSE_MODE_PARALLAX
    和LayoutParams#setParallaxMultiplier()。
    CollapsingToolbarLayout滑動時,子視圖的視覺差,可以通過屬性app:layout_collapseParallaxMultiplier=”0.x”改變。
    設(shè)置視差的系數(shù),介于0.0-1.0之間。
  • 5、 頂部懸浮 CollapseMode
    子視圖的折疊模式,有兩種 “pin” 和 “parallax”.
    • “pin”:固定模式,在折疊的時候最后固定在頂端;
    • “parallax”:視差模式,在折疊的時候會有個視差折疊的效果。
      我們可以在布局中使用屬性app:layout_collapseMode=”parallax”來改變。

嗯,大概就是這樣,好像很6的樣子,看代碼吧。

來一份demo

1、布局文件

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
>

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <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/ivImage"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:transitionName="transition_book_img"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
        </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="180dp"
                android:layout_margin="10dp"
                android:background="#6660c6df"
                android:gravity="center"
                android:text="折"
                android:textSize="26dp"
                android:transitionName="zi" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="180dp"
                android:layout_margin="10dp"
                android:background="#6660c6df"
                android:gravity="center"
                android:text="折疊"
                android:textSize="26dp"
                android:transitionName="zi" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="180dp"
                android:layout_margin="10dp"
                android:background="#6660c6df"
                android:gravity="center"
                android:text="折疊示"
                android:textSize="26dp"
                android:transitionName="zi" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="180dp"
                android:layout_margin="10dp"
                android:background="#6660c6df"
                android:gravity="center"
                android:text="折疊示例"
                android:textSize="26dp"
                android:transitionName="zi" />


        </LinearLayout>

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

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

2、Activity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView imageView = (ImageView) findViewById(R.id.ivImage);
        imageView.setImageResource(R.mipmap.show_op);
        Toolbar toolbar= (Toolbar) findViewById(R.id.toolbar);

        setSupportActionBar(toolbar);

        //設(shè)置工具欄標題
        CollapsingToolbarLayout collapsingToolbarLayout= (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        collapsingToolbarLayout.setTitle("蒙奇-D-路飛");
    }
}

3、效果圖:

CollapsingToolbarLayout.gif

代碼和圖都看完了。

下面再折騰一下

所謂 沉浸式內(nèi)容 Content scrim

//設(shè)置工具欄標題
        CollapsingToolbarLayout collapsingToolbarLayout= (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        collapsingToolbarLayout.setTitle("蒙奇-D-路飛");
        collapsingToolbarLayout.setExpandedTitleColor(Color.YELLOW);
        collapsingToolbarLayout.setCollapsedTitleTextColor(Color.WHITE);
        collapsingToolbarLayout.setContentScrim(getDrawable(R.mipmap.lf)); // 沉浸內(nèi)容
沉浸內(nèi)容.gif

.
.
所謂 沉浸狀態(tài)欄 Status bar scrim

        //設(shè)置工具欄標題
        CollapsingToolbarLayout collapsingToolbarLayout= (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        collapsingToolbarLayout.setTitle("蒙奇-D-路飛");
        collapsingToolbarLayout.setExpandedTitleColor(Color.YELLOW); 
        collapsingToolbarLayout.setCollapsedTitleTextColor(Color.WHITE); 
        collapsingToolbarLayout.setStatusBarScrim(getDrawable(R.mipmap.lf));  // 沉浸狀態(tài)欄
沉浸狀態(tài)欄.gif

.
.
頂部懸浮 CollapseMode
pin和parallax看起來差不多。。

四、TabLayout

回望開頭,我們展示的是一張海賊王的 Tab 動態(tài)圖,在md之前,我們常常可以使用三方開源的PagerSlidingTabStrip去實現(xiàn),或者viewpagerindicator,現(xiàn)在我們可以使用Design support library庫的TabLayout去實現(xiàn)。

同樣,我們先翻翻 google TabLayout司機手冊

手冊這么說

TabLayout 基本描述

TabLayout provides a horizontal layout to display tabs.

Population of the tabs to display is done through TabLayout.Tab instances. You create tabs via newTab(). From there you can change the tab's label or icon via setText(int) and setIcon(int) respectively. To display the tab, you need to add it to the layout via one of the addTab(Tab) methods. 

TabLayout提供了一個水平的布局用來展示Tabs。
TabLayout通過 newTab() 可以創(chuàng)建多個tab標簽。
可以通過setText()和setIcon分別設(shè)置文本和icon,最后通過addTab將newTab處的選項卡添加上去即可 。
但是這個是單一的選項卡使用 一般使用選項卡我們都是和viewpager相結(jié)合使用的。

google參考代碼:

 TabLayout tabLayout = ...;
 tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
 tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
 tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));

除了代碼添加tabs,也可以布局添加tabs

 <android.support.design.widget.TabLayout
         android:layout_height="wrap_content"
         android:layout_width="match_parent">

     <android.support.design.widget.TabItem
             android:text="@string/tab_text"/>

     <android.support.design.widget.TabItem
             android:icon="@drawable/ic_android"/>

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

TabLayout 監(jiān)聽

可以通過 setOnTabSelectedListener(OnTabSelectedListener) 設(shè)置tab狀態(tài)的改變

TabLayout 、ViewPager 一體化

如果你打算將TabLayout和ViewPager一起使用,那么可以通過setupWithViewPager(ViewPager)方法將兩者綁定在一起。這種布局將從PagerAdapter自動填充標題。

 <android.support.v4.view.ViewPager
     android:layout_width="match_parent"
     android:layout_height="match_parent">

     <android.support.design.widget.TabLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="top" />

 </android.support.v4.view.ViewPager>

來一個demo

1、布局文件
tablayout

<?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:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <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/ivImage"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                android:transitionName="transition_book_img"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7" />

            <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>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <android.support.design.widget.TabLayout
                android:id="@+id/sliding_tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabGravity="fill"
                app:tabMode="fixed">
            </android.support.design.widget.TabLayout>
        </android.support.v4.view.ViewPager>
    </LinearLayout>
</android.support.design.widget.CoordinatorLayout>

fragment 布局

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

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tvInfo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textColor="#212121"
            android:textSize="16sp" />
    </LinearLayout>

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

2、Activity和Fragment
Activity

public class TabLayoutActivity extends AppCompatActivity {

    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tablayout);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onBackPressed();
            }
        });


        CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        collapsingToolbar.setTitle("海賊王");
        collapsingToolbar.setExpandedTitleColor(Color.YELLOW);
        collapsingToolbar.setCollapsedTitleTextColor(Color.WHITE);

        ImageView ivImage = (ImageView)findViewById(R.id.ivImage);
        ivImage.setImageResource(R.mipmap.show_op);

        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(mViewPager);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
        tabLayout.addTab(tabLayout.newTab().setText("基本資料"));
        tabLayout.addTab(tabLayout.newTab().setText("身世"));
        tabLayout.addTab(tabLayout.newTab().setText("性格"));
        tabLayout.addTab(tabLayout.newTab().setText("家譜"));
        tabLayout.addTab(tabLayout.newTab().setText("海賊團"));
        tabLayout.setupWithViewPager(mViewPager);
    }

    private void setupViewPager(ViewPager mViewPager) {
        MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(DetailFragment.newInstance(getAsset("book_content.txt")), "基本資料");
        adapter.addFragment(DetailFragment.newInstance(getAsset("book_author.txt")), "身世");
        adapter.addFragment(DetailFragment.newInstance(getAsset("book_menu.txt")), "性格");
        adapter.addFragment(DetailFragment.newInstance(getAsset("lufei_home.txt")), "家譜");
        adapter.addFragment(DetailFragment.newInstance(getAsset("lufei_friend.txt")), "海賊團");
        mViewPager.setAdapter(adapter);
    }

    private String getAsset(String fileName) {
        AssetManager am = getResources().getAssets();
        InputStream is = null;
        try {
            is = am.open(fileName, AssetManager.ACCESS_BUFFER);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new Scanner(is).useDelimiter("\\Z").next();
    }


    static class MyPagerAdapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragments = new ArrayList<>();
        private final List<String> mFragmentTitles = new ArrayList<>();

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        public void addFragment(Fragment fragment, String title) {
            mFragments.add(fragment);
            mFragmentTitles.add(title);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }

        @Override
        public int getCount() {
            return mFragments.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitles.get(position);
        }
    }
}

Fragment

public class DetailFragment extends Fragment {

    public static DetailFragment newInstance(String info) {
        Bundle args = new Bundle();
        DetailFragment fragment = new DetailFragment();
        args.putString("info", info);
        fragment.setArguments(args);
        return fragment;
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_detail, null);
        TextView tvInfo = (TextView) view.findViewById(R.id.tvInfo);
        tvInfo.setText(getArguments().getString("info"));

        return view;
    }
}

3、assets文件

Paste_Image.png

4、效果

海賊王演示.gif

來一個底部Tab的demo

布局:
1、主布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    </android.support.design.widget.AppBarLayout>



    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/appbar"
        android:orientation="vertical">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1.0"
            android:scrollbars="none" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            app:tabIndicatorColor="?attr/colorAccent"
            app:tabIndicatorHeight="0dp"
            app:tabPaddingStart="12dp"
            app:tabPaddingEnd="12dp"
            app:tabBackground="@color/cardview_light_background"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>

</RelativeLayout>

2、tab 按鈕 布局

<?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:gravity="center"
    android:layout_height="match_parent">

    <ImageView
        android:layout_marginTop="2dp"
        android:id="@+id/imageView"
        android:src="@mipmap/ic_launcher"
        android:layout_width="25dp"
        android:layout_height="25dp" />

    <TextView
        android:id="@+id/news_title"
        android:layout_marginTop="2dp"
        android:textSize="14sp"
        android:textColor="@drawable/selector_text_color"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

3、fragment_page

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center" />

2、Activity和其他

Activity

public class BottomTabActivity extends AppCompatActivity {

    private ViewPager viewPager;
    private TabLayout tabLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bottom_tab);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle("底部Tab");
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onBackPressed();
            }
        });

        viewPager = (ViewPager) findViewById(R.id.viewPager);
        tabLayout = (TabLayout) findViewById(R.id.tabLayout);

        SampleFragmentPagerAdapter pagerAdapter =
                new SampleFragmentPagerAdapter(getSupportFragmentManager(), this);

        viewPager.setAdapter(pagerAdapter);


        tabLayout.setupWithViewPager(viewPager);
        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);
            if (tab != null) {
                tab.setCustomView(pagerAdapter.getTabView(i));
            }
        }

//        viewPager.setCurrentItem(1);
        tabLayout.getTabAt(0).getCustomView().setSelected(true);
    }


    public class SampleFragmentPagerAdapter extends FragmentPagerAdapter {
        final int PAGE_COUNT = 3;
        private String tabTitles[] = new String[]{"TAB1", "TAB2", "TAB3"};
        private Context context;


        public View getTabView(int position) {
            View v = LayoutInflater.from(context).inflate(R.layout.custom_tab, null);
            TextView tv = (TextView) v.findViewById(R.id.news_title);
            tv.setText(tabTitles[position]);
            ImageView img = (ImageView) v.findViewById(R.id.imageView);
            //img.setImageResource(imageResId[position]);
            return v;
        }

        public SampleFragmentPagerAdapter(FragmentManager fm, Context context) {
            super(fm);
            this.context = context;
        }

        @Override
        public int getCount() {
            return PAGE_COUNT;
        }

        @Override
        public Fragment getItem(int position) {
            return PageFragment.newInstance(position + 1);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return tabTitles[position];
        }
    }

    public static class PageFragment extends Fragment {
        public static final String ARG_PAGE = "ARG_PAGE";

        private int mPage;

        public static PageFragment newInstance(int page) {
            Bundle args = new Bundle();
            args.putInt(ARG_PAGE, page);
            PageFragment fragment = new PageFragment();
            fragment.setArguments(args);
            return fragment;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mPage = getArguments().getInt(ARG_PAGE);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_page, container, false);
            TextView textView = (TextView) view;
            textView.setText("Fragment   " + mPage);
            return view;
        }
    }
}

selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:color="@color/colorAccent" android:state_pressed="true" />
    <!-- pressed -->
    <item android:color="@color/colorAccent" android:state_selected="true" />
    <!-- focused -->
    <item android:color="@color/cardview_dark_background" />
    <!-- default -->

</selector>
底部Tab.gif

至此,把控件的東西說完了,但是還有屬性的問題呢。

demo

五、md控件屬性參考

屬性的好說,下面附上一個比較完整的md控件屬性參考

android:fitsSystemWindows="true"
是一個boolean值的內(nèi)部屬性,讓view可以根據(jù)系統(tǒng)窗口(如status bar)來調(diào)整自己的布局,如果值為true,就會調(diào)整view的paingding屬性來給system windows留出空間...
用于實現(xiàn)狀態(tài)欄,即 沉浸式狀態(tài)欄!

Toolbar

  • android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
  • app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
  • app:layout_scrollFlags="scroll|enterAlways" (CoordinatorLayout屬性,子布局通過設(shè)置該屬性確定是否可滑動)

說明:
app:popupTheme,這個屬性就是用來自定義我們彈出的菜單的樣式,在之前的Actionbar的溢出菜單,我們是不能自定義他的樣式的,只能根據(jù)你的theme來選擇黑白兩種,不能自己定義,現(xiàn)在我們可以定義彈出菜單的樣式。

CoordinatorLayout

  • app:layout_scrollFlags (子布局設(shè)置是否可滑動)
  • android:layout_gravity 屬性控制組件在布局中的位置
  • app:layout_behavior="@string/appbar_scrolling_view_behavior" 通知布局中包含滑動組件!

子布局通過app:layout_scrollFlags確定是否可滑動.給需要滑動的組件設(shè)置 app:layout_scrollFlags="scroll|enterAlways" 屬性。
設(shè)置的layout_scrollFlags有如下幾種選項:
scroll: 所有想滾動出屏幕的view都需要設(shè)置這個flag- 沒有設(shè)置這個flag的view將被固定在屏幕頂部。
enterAlways: 這個flag讓任意向下的滾動都會導(dǎo)致該view變?yōu)榭梢姡瑔⒂每焖佟胺祷啬J健薄?br> enterAlwaysCollapsed: 當你的視圖已經(jīng)設(shè)置minHeight屬性又使用此標志時,你的視圖只能已最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度。
exitUntilCollapsed: 滾動退出屏幕,最后折疊在頂端。

CollapsingToolbarLayout

  • app:collapsedTitleGravity 指定折疊狀態(tài)的標題如何放置,可選值:top、bottom等
  • app:collapsedTitleTextAppearance="@style/TextAppearance.CollapsedTitle"指定折疊狀態(tài)標題文字的樣貌
  • app:expandedTitleTextAppearance="@style/TextAppearance.ExpandedTitle"指定展開狀態(tài)標題文字的樣貌
  • app:contentScrim="?attr/colorPrimaryDark"指定CollapsingToolbarLayout完全被滾出到屏幕外時的ColorDrawableapp:expandedTitleGravity 展開狀態(tài)的標題如何放置
  • app:titleEnabled指定是否顯示標題文本
  • app:toolbarId指定與之關(guān)聯(lián)的ToolBar,如果未指定則默認使用第一個被發(fā)現(xiàn)的ToolBar子View
  • app:expandedTitleMarginStart="10dp"
  • app:expandedTitleMargin
  • app:expandedTitleMarginBottom
  • app:expandedTitleMarginEnd 展開狀態(tài)改變標題文字的位置,通過margin設(shè)置
  • app:layout_collapseParallaxMultiplier="0.7" 設(shè)置視差的系數(shù),介于0.0-1.0之間。
  • app:layout_collapseMode="pin"(子布局設(shè)置折疊模式)有兩種“pin”:固定模式,在折疊的時候最后固定在頂端;“parallax”:視差模式,在折疊的時候會有個視差折疊的效果。

CollapsingToolbarLayout主要是提供一個可折疊的Toolbar容器,對容器中的不同View設(shè)置layout_collapseMode折疊模式,來達到不同的折疊效果。

Floating Action Button (FAB)

  • app:fabSize="normal" 是用來定義 FAB 的大小的,normal 的意思是在大多數(shù)情況下標準尺寸為 56dp 的按鈕,但是萬一你想使用較小的一個, mini 是另一個選擇,它的大小將變成 40dp。
  • app:elevation   為空閑狀態(tài)下的陰影深度,
  • app:pressedTranslationZ   為按下狀態(tài)的。
  • app:backgroundTint   是指定默認的背景顏色
  • app:rippleColor   是指定點擊時的背景顏色
  • app:border    Width  border的寬度
  • app:fabSize   是指FloatingActionButton的大小,可選normal|mini
  • app:pressedTranslationZ   按下去時的z軸的便宜

TabLayout

  • app:tabIndicatorColor   tab的指示符顏色
  • app:tabSelectedTextColor   選擇tab的文本顏色
  • app:tabTextColor   普通tab字體顏色
  • app:tabMode   模式,可選fixed和scrollable fixed是指固定個數(shù),scrollable是可以橫行滾動
  • app:tabGravity 對齊方式,可選fill和center

MD系列1、RecyclerView良好參考
MD系列2、ToolBar+DrawerLayout + NavigationView

六、參考

參考:
ANDROIID-M
JuheNews系列之二 · ToolBar+AppBarLayout+CoordinatorLayout+CollapsingToolbarLayout
android CoordinatorLayout使用
[Android Material Design 控件常用的屬性]
md控件屬性參考
使用TabLayout實現(xiàn)底部Tab布局

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

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