Android進階設計 | 使用揭露動畫(Reveal Effect)做一個絲滑的Activity轉場動畫

提筆之際(附總體思路)


最近跟幾個小伙伴在實踐一個項目,考慮到界面效果,我們決定使用揭露動畫作為Activity的轉場動畫虐急。


這里主要是我負責這部分的實現(xiàn)。
話說之前是沒接觸過的滔迈,關于具體的實現(xiàn)跟大體的思路都不太清楚止吁。于是最先啃官方API被辑,有點難看懂,然后下載了官方的demo敬惦,直接看代碼盼理,還是有問題,畢竟它規(guī)模略大俄删,集成了好多動畫效果宏怔;
接著就找了很多博文,發(fā)現(xiàn)網上真的水文忒多了哎畴椰。臊诊。

最后找到了這三篇,算是解答了我的疑問:

  1. http://www.reibang.com/p/b75548e488df
    這篇思路很好斜脂,寫得也很走心抓艳,啟發(fā)了我設計的思路跟注意到的一些問題,像揭露動畫的邏輯放在哪里之類的帚戳;正當我要下載demo的時候發(fā)現(xiàn)他代碼是kotlin來的玷或,好吧,再繼續(xù)找博文销斟;

  2. https://blog.csdn.net/shedoor/article/details/81251849#5
    這篇就講得更加詳盡庐椒,這還看不懂那就有點說不過去了。一開始覺得揭露動畫還是挺高大上的樣子蚂踊,結果此博文文首便說很簡單约谈,那就很簡單吧,后來理解透了之后發(fā)覺確實也不難犁钟,畢竟只有一個靜態(tài)方法而已棱诱;
    https://github.com/OCNYang/Android-Animation-Set/tree/master/reveal-animation
    這個點進去是他的GitHub,demo下下來涝动,代碼看一下迈勋,自己寫個小demo(我是先在一個activity里面跑通揭露動畫,再進一步將揭露動畫實現(xiàn)成跳轉動畫)醋粟,再加入自己的邏輯靡菇,一步一步來算是沒有問題了。
    到這里就跑通了一個活動中的Activity了米愿;

  1. https://github.com/whyalwaysmea/AndroidDemos
    接下來就進入本文主題了厦凤,使用揭露動畫作為Activity的轉場動畫;
    這篇文檔跟代碼算是幫上大忙了育苟,有較大的參考價值较鼓;
    不同的是作者的思路是在跳轉的目標活動中,啟動做揭露動畫的收挽,收挽結束后再finish()博烂;
    我這里根據情況修改為跳轉的目標活動中按下返回鍵即finish()香椎,完了之后原始活動中的onReStart()中做揭露動畫的收挽;另外我在在跳轉的目標活動中完成揭露動畫展開的時候禽篱,添加了一個AlphaAnimation畜伐;
    這邊的起始活動用的是button的onClick觸發(fā)的方式,以及這里對兩個活動各自的控件的visible做了細節(jié)的把控谆级;

最終效果圖
GitHub中附方法詳解圖




引子


使用揭露動畫做一個絲滑的Activity轉場動畫,
關于這個需求烤礁,可能不同的同學,會有不同的問題肥照,
我這里把可能遇到的問題跟我在完成這個demo的過程中遇到的問題做一個總結脚仔,
然后附上總體的思路,大家可以交流一下~

  1. 什么是揭露動畫舆绎?
    Material-Animations; 官網有詳細的介紹鲤脏,
    揭露動畫具有相當絲滑的效果,
    常陈蓝洌可以用與基于一個Activity的碎片切換或者View猎醇、控件的切換覆蓋鋪張,如本文第一個demo努溃;
    或者直接作為兩個Activity之間的轉場動畫硫嘶,如本文第二個demo;

  2. 揭露動畫怎么用梧税?
    官方API封裝好了沦疾,
    一個類一個靜態(tài)方法——ViewAnimationUtils.createCircularReveal(),
    傳進五個參數第队,返回一個Animator對象哮塞。根據具體情況調用即可。

    詳細可見參考文檔凳谦;

  3. “絲滑”之解
    這個轉場動畫要實現(xiàn)得絲滑忆畅,需要注意幾個細節(jié):
    活動A跳轉到活動B的情況下,
    a.在A點擊觸發(fā)跳轉時刻尸执,揭露動畫要放在哪個活動展開家凯;
    b.在B按下返回鍵之后,揭露動畫又要放在哪個活動收挽如失;
    c.揭露動畫的展開和收挽绊诲,createCircularReveal()分別以誰為操作對象;
    d.這里A通過FloatingActionButton出發(fā)岖常,那揭露層View跟FloatingActionButton的visible跟invisible設置的順序;
    e.關閉android默認的activity轉場動畫(不然就相當不絲滑了hhh)葫督;

相關解答詳解下方第二個demo的思路總結竭鞍,請移步到正文中的第二個demo板惑;

了解本文的兩個demo之后,我相信以這個兩個demo為模板偎快,結合筆者之前關于Material Design做的諸多筆記冯乘,應該是可以做出不少很有趣的東西來的~

再附上在做本demo的過程中一些debugExperience:




正文


1.先在一個activity里面跑通揭露動畫

首先新建一個空項目,接著走三步即可:

1)更改styles.xml晒夹,改成NoActionBar裆馒,去掉標題欄,待會兒調試可以觀察:

2)書寫activity_main.xml:

  • 這里對子空間的布局范圍要求并不多丐怯,直接簡單用FrameLayout即可喷好;
  • 然后是Textview放在最前面,最先渲染读跷,以為至底層梗搅;
  • 接著我們這里使用一個View原生控件來作為揭露動畫的操作對象,即通過對View控件的顯示和隱藏以及動畫操作來具體實現(xiàn)揭露動畫效览;
  • 最后放置一個懸浮按鈕无切,用于啟動點擊事件,這里響應的事件是啟動揭露動畫:

另外說一下丐枉,關于FloatingActionButton哆键,
android:backgroundTint可以設置其背景色,
android:src則給按鈕設置圖標瘦锹,
這里用的圖標資源來自于阿里的矢量圖標庫籍嘹。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    tools:context="com.lwp.justtest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:layout_gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/view_puppet"
        android:background="@color/colorPrimaryDark"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:backgroundTint="@color/colorPrimary"
        android:src="@drawable/map"
        app:pressedTranslationZ="10dp" />

</FrameLayout>

3)書寫MainActivity.java:

  • 實例化各個組件之后,實現(xiàn)FloatingActionButton的onClick()沼本,
  • onClick()中我們調用一個自定義方法噩峦,在里面啟動揭露動畫;
  • 這里通過變量flag實現(xiàn)點擊按鈕時揭露動畫的交替開啟顯示以及關閉隱藏抽兆,效果圖在下方代碼之后识补;
  • 關于揭露動畫的邏輯以及具體實現(xiàn)的語法,
    其實核心就是ViewAnimationUtils.createCircularReveal()這個方法以及其五個參數的意義,
    詳細地可以參考前面提到的參考文章鏈接:
package com.lwp.justtest;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewAnimationUtils;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    boolean flag = false;
    FloatingActionButton fab;
    private View mPuppet;

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

        mPuppet = findViewById(R.id.view_puppet);
        fab = (FloatingActionButton)findViewById(R.id.fab);
        fab.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        doRevealAnimation();
    }

    private void doRevealAnimation() {
        int[] vLocation = new int[2];
        fab.getLocationInWindow(vLocation);
        int centerX = vLocation[0] + fab.getMeasuredWidth() / 2;
        int centerY = vLocation[1] + fab.getMeasuredHeight() / 2;

        int height = mPuppet.getHeight();
        int width = mPuppet.getWidth();
        int maxRradius = (int) Math.hypot(height, width);
        Log.e("hei", maxRradius + "");

        if (flag) {
            Animator animator = ViewAnimationUtils.createCircularReveal(mPuppet, centerX, centerY, maxRradius, 0);
            animator.setDuration(1000);
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    mPuppet.setVisibility(View.GONE);
                }
            });
            animator.start();
            flag = false;
        } else {
            Animator animator = ViewAnimationUtils.createCircularReveal(mPuppet, centerX, centerY, 0, maxRradius);
            animator.setDuration(1000);
            animator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
                    mPuppet.setVisibility(View.VISIBLE);
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });
            animator.start();
            flag = true;
        }
    }

}

上面三步走完怕轿,即可運行程序拍冠,揭露動畫隨即實現(xiàn),效果如下:


接著后面就進入本文主題了切油;



2.使用揭露動畫作為Activity的轉場動畫

思路總結:

1. MainActivity.java:
    1.1.   實例化、聲明各種對象名惩,注意:
            根布局對象(用來控制整個布局)澎胡,
            揭露層對象指的是用于作揭露操作的純色的match_parent的View控件;

    1.2.  onCreate():完成findViewById()以及intent的構建,F(xiàn)loatingActionButton的setOnClickListener攻谁;

    1.3.  onClick():計算fab的中心坐標稚伍,用于作為揭露動畫的圓心;同時把這對坐標put進intent中戚宦,然后startActivity(intent);跳轉到下一個活動个曙,同時把坐標對傳過去;

    1.4. createRevealAnimator():計算startRadius受楼、endRadius垦搬,調用核心方法createCircularReveal()構建出animator并做相關配置后return之;
          注意:
            這里的createCircularReveal()操作對象用的是揭露層純色View對象mPuppet0艳汽;
            以及配置中用了animator.addListener(animatorListener0);添加一個動畫監(jiān)聽器猴贰;--->> 1.5.

    1.5.  Animator.AnimatorListener animatorListener0 

 注意這里的思路:
          !IЬ摹糟趾!
          onAnimationStart():收挽揭露動畫開啟時,揭露層setVisibility(View.VISIBLE);fab.setVisibility(View.INVISIBLE);
          onAnimationEnd():收挽版揭露動畫結束時甚牲,mPuppet0.setVisibility(View.INVISIBLE);fab.setVisibility(View.VISIBLE);
          R逯!!丈钙!
    
    1.6. onRestart():回調方法非驮,計算fab的中心坐標,用于作為揭露動畫的圓心雏赦;
         調用createRevealAnimator()創(chuàng)建并配置一個animator(--->> 1.4.)劫笙,
         然后開啟收挽版揭露動畫,即animator.start();

2. next.java:
    2.1.   實例化星岗、聲明各種對象填大,注意:
            根布局對象(用來控制整個布局),
            揭露層對象指的是用于作揭露操作的純色的match_parent的View控件俏橘;

    2.2.  onCreate():完成findViewById()允华,
        這里注意:
            動畫需要依賴于某個視圖才可啟動,這里依賴于根布局對象并且開辟一個子線程寥掐,
            在子線程中get坐標對靴寂,調用createRevealAnimator()創(chuàng)建并配置一個animator;--->> 2.3.
            然后開啟展開版揭露動畫,即animator.start();
    2.3. createRevealAnimator():計算startRadius召耘、endRadius百炬,調用核心方法createCircularReveal()構建出animator并做相關配置后return之;

          注意這里的思路:

            N鬯F视弧庶弃!這里的createCircularReveal()操作對象用的是根布局對象content;

            5鲁骸3婀 !F匝椤!
            (即先加載好整個布局缝呕,再把整個布局作為揭露對象從0徑到屏幕對角線徑揭露展開澳窑,
              展開過程中揭露層純色view在最頂層,所以感覺是View在做展開而已供常,
              而實際上并不是摊聋;展開完畢后,再把view層去掉栈暇,去掉之后下層的活動內容自然就顯示出來了麻裁。)
            !T雌怼<逶础!香缺!

            以及配置中用了animator.addListener(animatorListener0);添加一個動畫監(jiān)聽器手销;--->> 2.4.
    2.4. Animator.AnimatorListener animatorListener1 

          注意這里的思路:
          !M颊拧锋拖!
          onAnimationEnd():展開版揭露動畫結束時,            
            mPuppet.startAnimation(createAlphaAnimation());//調用透明度動畫祸轮,絲滑效果-->>2.5.
            mPuppet.setVisibility(View.INVISIBLE);//動畫結束時兽埃,揭露動畫設置為不可見
          !J释唷柄错!

    2.5. createAlphaAnimation():定義透明度動畫,返回一個AlphaAnimation對象痪蝇;

    3. 兩個布局xml沒什么特別需要說的地方鄙陡,
        注意第一個xml的view要android:visibility="gone",以及按照渲染先后層次關系按序書寫控件即是躏啰;

    4. styles.xml:android:windowAnimationStyle屬性置為null趁矾,取消掉Android默認的轉場動畫
    <style name="noAnimTheme" parent="AppTheme">
        <item name="android:windowAnimationStyle">@null</item>
    </style>
    
    5. AndroidManifest.xml:為參與的活動添加剛剛設置好的主題;
      <activity
            android:name=".MainActivity"
            android:theme="@style/noAnimTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".next"
            android:theme="@style/noAnimTheme">
        </activity>

最后上代碼了给僵,不同的功能基本上都放在了不同的方法內實現(xiàn)毫捣,結合注釋應該不難理解了~

MainActivity.java:

package com.lwp.justtest;

import ...

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    FloatingActionButton fab;
    Intent intent;
    private View content;//根布局對象(用來控制整個布局)
    private View mPuppet0;//揭露層對象
    private int centerX;
    private int centerY;

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

        content = findViewById(R.id.reveal_content0);
        mPuppet0 = findViewById(R.id.view_puppet);
        intent = new Intent(MainActivity.this, next.class);
        fab = (FloatingActionButton)findViewById(R.id.fab);
        fab.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        int[] vLocation = new int[2];
        fab.getLocationInWindow(vLocation);
        centerX = vLocation[0] + fab.getMeasuredWidth() / 2;
        centerY = vLocation[1] + fab.getMeasuredHeight() / 2;
        intent.putExtra("cx",centerX);
        intent.putExtra("cy",centerY);
        startActivity(intent);
    }

    private Animator createRevealAnimator(int x, int y) {
        float startRadius = (float) Math.hypot(content.getHeight(), content.getWidth());
        float endRadius = fab.getMeasuredWidth() / 2 ;

        //注意揭露動畫開啟時是用根布局作為操作對象详拙,關閉時用揭露層作為操作對象
        Animator animator = ViewAnimationUtils.createCircularReveal(
                mPuppet0, x, y,
                startRadius,
                endRadius);
        animator.setDuration(500);
        animator.setInterpolator(new AccelerateDecelerateInterpolator());//設置插值器
        animator.addListener(animatorListener0);
        return animator;
    }

    //定義動畫狀態(tài)監(jiān)聽器_按下返回鍵版
    private Animator.AnimatorListener animatorListener0 = new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
            mPuppet0.setVisibility(View.VISIBLE);//按下返回鍵時,動畫開啟蔓同,揭露層設置為可見
            fab.setVisibility(View.INVISIBLE);
        }
        @Override
        public void onAnimationEnd(Animator animation) {
            mPuppet0.setVisibility(View.INVISIBLE);
            fab.setVisibility(View.VISIBLE);
        }
        @Override
        public void onAnimationCancel(Animator animation) {
        }
        @Override
        public void onAnimationRepeat(Animator animation) {
        }
    };

    //第二個活動退回來時饶辙,回調本方法
    @Override
    protected void onRestart() {
        super.onRestart();

        //動畫需要依賴于某個視圖才可啟動,
        // 這里依賴于根布局對象斑粱,并且開辟一個子線程弃揽,充分利用資源
        content.post(new Runnable() {
            @Override
            public void run() {
                int[] vLocation = new int[2];
                fab.getLocationInWindow(vLocation);
                centerX = vLocation[0] + fab.getMeasuredWidth() / 2;
                centerY = vLocation[1] + fab.getMeasuredHeight() / 2;
                Animator animator = createRevealAnimator(centerX, centerY);
                animator.start();
            }
        });
    }
}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="@+id/reveal_content0"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.lwp.justtest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Here is First Activity!"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="30sp"
        android:layout_gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/view_puppet"
        android:background="@color/colorPrimaryDark"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:backgroundTint="@color/colorPrimary"
        android:src="@drawable/map"
        app:pressedTranslationZ="10dp" />

</FrameLayout>

next.java:

package com.lwp.justtest;

import ...

public class next extends AppCompatActivity {

    private View content;//根布局對象(用來控制整個布局)
    private View mPuppet;//揭露層對象
    private int mX ;
    private int mY ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_next);//先加載好整個布局,后面再用整個布局作為揭露動畫的操作對象则北,揭露完畢后再去掉揭露層
        content = findViewById(R.id.reveal_content);
        mPuppet = findViewById(R.id.view_puppet);

        //動畫需要依賴于某個視圖才可啟動矿微,
        // 這里依賴于根布局對象,并且開辟一個子線程尚揣,充分利用資源
        content.post(new Runnable() {
            @Override
            public void run() {
                mX = getIntent().getIntExtra("cx", 0);
                mY = getIntent().getIntExtra("cy", 0);
                Animator animator = createRevealAnimator(mX, mY);
                animator.start();
            }
        });
    }

    private Animator createRevealAnimator(int x, int y) {
        float startRadius = 0;
        float endRadius = (float) Math.hypot(content.getHeight(), content.getWidth());

        Animator animator = ViewAnimationUtils.createCircularReveal(
                content, x, y,
                startRadius,
                endRadius);
        animator.setDuration(660);
        animator.setInterpolator(new AccelerateDecelerateInterpolator());
        //判斷標志位reversed涌矢,true則為添加返回鍵版動畫監(jiān)聽器,false則為跳轉動畫開啟版
        // if (!reversed)
           animator.addListener(animatorListener1);
        return animator;
    }

    //定義動畫狀態(tài)監(jiān)聽器_跳轉動畫開啟版
    private Animator.AnimatorListener animatorListener1 = new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
//            content.setVisibility(View.VISIBLE);//跳轉進來時快骗,(因為finish之前會將之設置為不可見娜庇,)
                                                 // 根布局要設置為可見,與finish部分的不可見相對應
//            mPuppet.setAlpha(1);
        }
        @Override
        public void onAnimationEnd(Animator animation) {
            mPuppet.startAnimation(createAlphaAnimation());
            mPuppet.setVisibility(View.INVISIBLE);//動畫結束時方篮,揭露動畫設置為不可見
        }
        @Override
        public void onAnimationCancel(Animator animation) {
        }
        @Override
        public void onAnimationRepeat(Animator animation) {
        }
    };

    private AlphaAnimation createAlphaAnimation() {
        AlphaAnimation aa = new AlphaAnimation(1,0);
        aa.setDuration(400);
        aa.setInterpolator(new AccelerateDecelerateInterpolator());//設置插值器
        return aa;
    }
}

next.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="@+id/reveal_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.lwp.justtest.next">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Here is Second Activity!"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="30sp"
        android:layout_gravity="center"/>

    <View
        android:id="@+id/view_puppet"
        android:background="@color/colorPrimaryDark"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


</FrameLayout>

res/values/styles.xml:

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

    <style name="noAnimTheme" parent="AppTheme">
        <item name="android:windowAnimationStyle">@null</item>
    </style>

</resources>

AndroidManifest.xml:

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:theme="@style/noAnimTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".next"
            android:theme="@style/noAnimTheme">
        </activity>
    </application>

最終效果圖:

本文的兩個demo就到此為止了名秀,我相信以這個兩個demo為模板,結合筆者之前關于Material Design做的諸多筆記藕溅,應該是可以做出不少很有趣的東西來的~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末泰偿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蜈垮,更是在濱河造成了極大的恐慌耗跛,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攒发,死亡現(xiàn)場離奇詭異调塌,居然都是意外死亡,警方通過查閱死者的電腦和手機惠猿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門羔砾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人偶妖,你說我怎么就攤上這事姜凄。” “怎么了趾访?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵态秧,是天一觀的道長。 經常有香客問我扼鞋,道長申鱼,這世上最難降的妖魔是什么愤诱? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮捐友,結果婚禮上淫半,老公的妹妹穿的比我還像新娘。我一直安慰自己匣砖,他們只是感情好科吭,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著猴鲫,像睡著了一般砌溺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上变隔,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音蟹倾,去河邊找鬼匣缘。 笑死,一個胖子當著我的面吹牛鲜棠,可吹牛的內容都是我干的肌厨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼豁陆,長吁一口氣:“原來是場噩夢啊……” “哼柑爸!你這毒婦竟也來了?” 一聲冷哼從身側響起盒音,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤表鳍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后祥诽,有當地人在樹林里發(fā)現(xiàn)了一具尸體譬圣,經...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年雄坪,在試婚紗的時候發(fā)現(xiàn)自己被綠了厘熟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡维哈,死狀恐怖绳姨,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情阔挠,我是刑警寧澤飘庄,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站购撼,受9級特大地震影響竭宰,放射性物質發(fā)生泄漏空郊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一切揭、第九天 我趴在偏房一處隱蔽的房頂上張望狞甚。 院中可真熱鬧,春花似錦廓旬、人聲如沸哼审。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涩盾。三九已至,卻和暖如春励背,著一層夾襖步出監(jiān)牢的瞬間春霍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工叶眉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留址儒,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓衅疙,卻偏偏與公主長得像莲趣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子饱溢,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內容

  • 用兩張圖告訴你喧伞,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,732評論 2 59
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,180評論 25 707
  • 1绩郎、通過CocoaPods安裝項目名稱項目信息 AFNetworking網絡請求組件 FMDB本地數據庫組件 SD...
    陽明先生_X自主閱讀 15,982評論 3 119
  • 昨夜狂風攜雨的潘鲫,很晚才入睡。 今早五點就自然醒了肋杖,如果在黃羊河的家里次舌,這個點我是絕對醒不來的∈薹撸看來...
    有書薰衣草閱讀 590評論 2 34
  • 1 每天回來android 一集彼念; 2. GUI Servlet Jsp JDBC SSH 以后要讓所有學生...
    雷一凡閱讀 269評論 0 0