Android 動畫小結 (ViewAnimation-> Tween Animation,Frame Animation ;property Animator-> ValueAnimator...

Android 動畫 小結

a.視圖動畫(ViewAnimation)= Tween Animation(補間動畫)+ Frame Animation(逐幀動畫)
b.屬性動畫(property Animator)=ValueAnimator + ObjectAnimator

為什么要使用Property Animator(和view動畫的不同)

1.為了實現view animation 無法實現的效果(view 動畫對派生于view的控件的指定屬性)
2.View Animation僅能對指定的控件做動畫,而Property Animator是通過改變控件某一屬性值來做動畫的。

3.補間動畫雖能對控件做動畫,但并沒有改變控件內部的屬性值。而Property Animator則是恰恰相反,Property Animator是通過改變控件內部的屬性值來達到動畫效果的

一.view動畫的使用:

1.1、XML配置文件中

alpha
漸變透明度動畫效果
scale
漸變尺寸伸縮動畫效果
translate
畫面轉換位置移動動畫效果
rotate
畫面轉移旋轉動畫效果

xml動畫定義
Animation animation =AnimationUtils. loadAnimation(context ,R.anim.xxx);
view.startAnimation(animation);

  Animation outAnim = AnimationUtils.loadAnimation(mContext, 
  R.anim.custom_dialog_disappear);
    outAnim.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
        //todo
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            //todo
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
           //todo
        }
    });
  
      view.startAnimation(outAnim);
1.2.代碼使用
            final TranslateAnimation animation = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 400,  
                    Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 400);  
            animation.setFillAfter(true);  
            animation.setDuration(1000);  
            tv.startAnimation(animation);  
1.3.AnimationSet

構造方法

/**
 * Constructor to use when building an AnimationSet from code
 *
 * @param shareInterpolator Pass true if all of the animations in this set
 *        should use the interpolator associated with this AnimationSet.
 *        Pass false if each animation should use its own interpolator.
 */
public AnimationSet(boolean shareInterpolator) {
    setFlag(PROPERTY_SHARE_INTERPOLATOR_MASK, shareInterpolator);
    init();
}

--

/* 
 *  將四種動畫效果放入同一個AnimationSet中 
 */  
animationSet.addAnimation(alphaAnimation);  
animationSet.addAnimation(rotateAnimation);  
animationSet.addAnimation(scaleAnimation);  
animationSet.addAnimation(translateAnimation);  

/* 
 *  同時執行多個動畫效果 
 */  
view.startAnimation(animationSet); 

二.property animator

常用

  • ofxxx
  • ofObject
  • ofPropertyValuesHolder
2.1.value animator

offxxx

ValueAnimator animator = ValueAnimator.ofFloat(startY, endY);
    animator.setDuration(300);
    animator.setInterpolator(new DecelerateInterpolator());
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {

            float animatedFraction = animation.getAnimatedFraction();
         float y = (float) animation.getAnimatedValue();
         
                xxx.setY(y);
                xxx.setAlpha(animatedFraction);

        }
    });

    animator.start();

ofObject

/**
 * Constructs and returns a ValueAnimator that animates between Object values. A single
 * value implies that that value is the one being animated to. However, this is not typically
 * useful in a ValueAnimator object because there is no way for the object to determine the
 * starting value for the animation (unlike ObjectAnimator, which can derive that value
 * from the target object and property being animated). Therefore, there should typically
 * be two or more values.
 *
 * <p><strong>Note:</strong> The Object values are stored as references to the original
 * objects, which means that changes to those objects after this method is called will
 * affect the values on the animator. If the objects will be mutated externally after
 * this method is called, callers should pass a copy of those objects instead.
 *
 * <p>Since ValueAnimator does not know how to animate between arbitrary Objects, this
 * factory method also takes a TypeEvaluator object that the ValueAnimator will use
 * to perform that interpolation.
 *
 * @param evaluator A TypeEvaluator that will be called on each animation frame to
 * provide the ncessry interpolation between the Object values to derive the animated
 * value.
 * @param values A set of values that the animation will animate between over time.
 * @return A ValueAnimator object that is set up to animate between the given values.
 */
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
    ValueAnimator anim = new ValueAnimator();
    anim.setObjectValues(values);
    anim.setEvaluator(evaluator);
    return anim;
}

.

public class CharEvaluator implements TypeEvaluator<Character> {  
@Override  
public Character evaluate(float fraction, Character startValue, Character endValue) {  
    int startInt  = (int)startValue;  
    int endInt = (int)endValue;  
    int curInt = (int)(startInt + fraction *(endInt - startInt));  
    char result = (char)curInt;  
    return result;  
   }  
} 

--

  ValueAnimator animator = ValueAnimator.ofObject(new CharEvaluator(),new Character('A'),new Character('Z'));  
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
    @Override  
    public void onAnimationUpdate(ValueAnimator animation) {  
        char text = (char)animation.getAnimatedValue();  
        tv.setText(String.valueOf(text));  
    }  
});  
animator.setDuration(10000);  
animator.setInterpolator(new AccelerateInterpolator());  
animator.start();  
2.2.object Animator

縮放操作,比如說將TextView在垂直方向上放大3倍再還原,就可以這樣寫:

ObjectAnimator = ObjectAnimator.ofFloat(targetView, "scaleY", 1f, 3f, 1f);  
animator.setDuration(5000);  
animator.start();
2.3.animatorSet

AnimatorSet set=new AnimatorSet();
合并播放
源碼

 public void playTogether(Animator... items) {
    if (items != null) {
        Builder builder = play(items[0]);
        for (int i = 1; i < items.length; ++i) {
            builder.with(items[i]);
        }
    }
}

set.playTogether(animator1,animator2)

================

ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);  
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);  
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);  
AnimatorSet animSet = new AnimatorSet();  
animSet.play(rotate).with(fadeInOut).after(moveIn);  
animSet.setDuration(5000);  
animSet.start();  
2.4.xml編寫屬性動畫

首先要在res目錄下面新建一個animator文件夾
<animator> 對應代碼中的ValueAnimator
<objectAnimator> 對應代碼中的ObjectAnimator
<set> 對應代碼中的AnimatorSet

    <objectAnimator  
        android:duration="2000"  
        android:propertyName="translationX"  
        android:valueFrom="-500"  
        android:valueTo="0"  
        android:valueType="floatType" >  
    </objectAnimator>  
  
    <set android:ordering="together" >  
        <objectAnimator  
            android:duration="3000"  
            android:propertyName="rotation"  
            android:valueFrom="0"  
            android:valueTo="360"  
            android:valueType="floatType" >  
        </objectAnimator>  
  
        <set android:ordering="sequentially" >  
            <objectAnimator  
                android:duration="1500"  
                android:propertyName="alpha"  
                android:valueFrom="1"  
                android:valueTo="0"  
                android:valueType="floatType" >  
            </objectAnimator>  
            <objectAnimator  
                android:duration="1500"  
                android:propertyName="alpha"  
                android:valueFrom="0"  
                android:valueTo="1"  
                android:valueType="floatType" >  
            </objectAnimator>  
        </set>  
    </set>    
</set>  

--

Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);  
animator.setTarget(view);  
animator.start();  
2.5 PropertyValuesHolder(ObjectAnimator.ofPropertyValuesHolder)

This class holds information about a property and the values that that property
should take on during an animation. PropertyValuesHolder objects can be used to create
animations with ValueAnimator or ObjectAnimator that operate on several different properties in parallel.

PropertyValuesHolder這個類可以先將動畫屬性和值暫時的存儲起來,后一起執行,在有些時候可以使用替換掉AnimatorSet

PropertyValuesHolder.png
2.5.1 PropertyValuesHolder.ofKeyframe

public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)

  • propertyName:*動畫所要操作的屬性名
  • values:Keyframe的列表,PropertyValuesHolder會根據每個Keyframe的設定,定時將指定的值輸出給動畫。

所以完整的KeyFrame的使用代碼應該是這樣的:

1.  Keyframe frame0 = Keyframe.ofFloat(0f, 0);  
2.  Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);  
3.  Keyframe frame2 = Keyframe.ofFloat(1, 0);  
4.  PropertyValuesHolder frameHolder =  ' PropertyValuesHolder.ofKeyframe ' ("rotation",frame0,frame1,frame2);  
5.  Animator animator =' ObjectAnimator.ofPropertyValuesHolder ' (mImage,frameHolder);  
6.  animator.setDuration(1000);  
7.  animator.start();
2.5.2 PropertyValuesHolder.ofXXX

ObjectAnimator.ofFloat中只比PropertyValuesHolder的ofFloat多了一個target,其它都是完全一樣的

2.5.3 PropertyValuesHolder.ofObject
  PropertyValuesHolder charHolder =     
  PropertyValuesHolder.ofObject("CharText",new CharEvaluator(),new 
  Character('A'),new Character('Z'));  
  ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mTextView, 
 charHolder);  
  animator.setDuration(3000);  
  animator.setInterpolator(new AccelerateInterpolator());  
  animator.start(); 
2.5.4 ObjectAnimator. ofPropertyValuesHolder(view, PropertyValuesHolder_1, PropertyValuesHolder_2 ....)
//keyframe
    Keyframe keyframe1 = Keyframe.ofFloat(0.0f,0);
    Keyframe keyframe2 = Keyframe.ofFloat(0.25f,-30);
    Keyframe keyframe3 = Keyframe.ofFloat(0.5f,0);
    Keyframe keyframe4 = Keyframe.ofFloat(0.75f, 30);
    Keyframe keyframe5 = Keyframe.ofFloat(1.0f,0);
    PropertyValuesHolder rotation = PropertyValuesHolder.ofKeyframe("rotation", keyframe1, keyframe2, keyframe3, keyframe4,keyframe5);




PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha",1.0f,0.2f,1.0f);
    PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX",1.0f,0.2f,1.0f);
    PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY",1.0f,0.2f,1.0f);
    PropertyValuesHolder color = PropertyValuesHolder.ofInt("BackgroundColor", 0XFFFFFF00, 0XFF0000FF);

    ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mButton, alpha, scaleX, scaleY,color,rotation);
    animator.setInterpolator(new OvershootInterpolator());
    animator.setDuration(5000).start();

   int riseDelta = ScreenUtil.dp2px(220);
    view.setVisibility(View.VISIBLE);
    PropertyValuesHolder riseKeyboard = PropertyValuesHolder.ofKeyframe(View.TRANSLATION_Y,
            Keyframe.ofFloat(0f, riseDelta),
            Keyframe.ofFloat(0.1f, riseDelta * 0.9f),
            Keyframe.ofFloat(0.2f, riseDelta * 0.8f),
            Keyframe.ofFloat(0.3f, riseDelta * 0.7f),
            Keyframe.ofFloat(0.4f, riseDelta * 0.6f),
            Keyframe.ofFloat(0.5f, riseDelta * 0.5f),
            Keyframe.ofFloat(0.6f, riseDelta * 0.4f),
            Keyframe.ofFloat(0.7f, riseDelta * 0.3f),
            Keyframe.ofFloat(0.8f, riseDelta * 0.2f),
            Keyframe.ofFloat(0.9f, riseDelta * 0.1f),
            Keyframe.ofFloat(1f, 0f)
    );

    ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, riseKeyboard).
            setDuration(300);
    animator.setInterpolator(new DecelerateInterpolator());

demo02

PropertyValuesHolder rotationHolder = PropertyValuesHolder.ofFloat("Rotation", 
60f, -60f, 40f, -40f, -20f, 20f, 10f, -10f, 0f);  
PropertyValuesHolder colorHolder = 
PropertyValuesHolder.ofInt("BackgroundColor", 0xffffffff, 0xffff00ff, 0xffffff00, 
0xffffffff);  
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mTextView, 
rotationHolder, colorHolder);  
animator.setDuration(3000);  
animator.setInterpolator(new AccelerateInterpolator());  
animator.start();
2.6.新api ViewPropertianimator
ViewPropertyAnimator animate = mViewById.animate();

            Runnable mStartRun = new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(), "動畫開始", Toast.LENGTH_SHORT).show();
                }
            };


            Runnable endRun = new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(), "動畫完成", Toast.LENGTH_SHORT).show();
                }
            };

            animate.alpha(0.5f)
                    .translationX(100)
                    .rotationBy(90)
                    .withStartAction(mStartRun)
                    .withEndAction(endRun)
                    .setInterpolator(new OvershootInterpolator())
                    .start();
        }

郭霖的專欄

Android屬性動畫完全解析(上),初識屬性動畫的基本用法

三 . ViewGroup Animation

3.1. LayoutAnimation

  • LayoutAnimationController
  • GridLayoutAnimationController
3.1.1 LayoutAnimationController
xml 實現

這部分,我們就來看看layoutAnimation標簽的用法,要使用layoutAnimation只需要兩步:
第一:定義一個layoutAnimation的animation文件,如:(anim/layout_animation.xml)

  <?xml version="1.0" encoding="utf-8"?>
  <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
             android:delay="1"
             android:animationOrder="normal"
             android:animation="@anim/slide_in_left"/>

其中的@anim/slide_in_left對應代碼為:

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android" 
            android:duration="1000">
    <translate android:fromXDelta="-50%p" android:toXDelta="0"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"/>
    </set>

第二步:在viewGroup類型的控件中,添加android:layoutAnimation=”@anim/layout_animation”,如:

   <ListView
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layoutAnimation="@anim/layout_animation"
    />
代碼實現 LayoutAnimationController

/**

  • A layout animation controller is used to animated a layout's, or a view
  • group's, children. Each child uses the same animation but for every one of
  • them, the animation starts at a different time. A layout animation controller
  • is used by {@link android.view.ViewGroup} to compute the delay by which each
  • child's animation start must be offset. The delay is computed by using
  • characteristics of each child, like its index in the view group.
  • This standard implementation computes the delay by multiplying a fixed
  • amount of miliseconds by the index of the child in its parent view group.
  • Subclasses are supposed to override
  • {@link #getDelayForView(android.view.View)} to implement a different way
  • of computing the delay. For instance, a
  • {@link android.view.animation.GridLayoutAnimationController} will compute the
  • delay based on the column and row indices of the child in its parent view
  • group.
  • Information used to compute the animation delay of each child are stored
  • in an instance of
  • {@link android.view.animation.LayoutAnimationController.AnimationParameters},
  • itself stored in the {@link android.view.ViewGroup.LayoutParams} of the view.
  • @attr ref android.R.styleable#LayoutAnimation_delay
  • @attr ref android.R.styleable#LayoutAnimation_animationOrder
  • @attr ref android.R.styleable#LayoutAnimation_interpolator
  • @attr ref android.R.styleable#LayoutAnimation_animation
    */
    public class LayoutAnimationController { .... }

布局與xml的實現方式一樣,唯一不同的是Listview中沒有定義android:layoutAnimation=”@anim/layout_animation”

  //代碼設置通過加載XML動畫設置文件來創建一個Animation對象;
    Animation animation= AnimationUtils.loadAnimation(this,R.anim.slide_in_left);         
   //得到一個 'LayoutAnimationController' 對象;
    LayoutAnimationController controller = new  LayoutAnimationController(animation);  
  
     //設置控件顯示的順序;
    controller.setOrder(LayoutAnimationController.ORDER_REVERSE);  
   //設置控件顯示間隔時間;
    controller.setDelay(0.3f);   //為ListView設置LayoutAnimationController屬性;
    mListView.setLayoutAnimation(controller);
    mListView.startLayoutAnimation();

3.1.2 gridLayoutAnimation

3.1.2.1xml

1)、首先是gride_animation.xml

  <?xml version="1.0" encoding="utf-8"?>
  <gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                 android:rowDelay="75%"
                 android:columnDelay="60%"
                 android:directionPriority="none"
                 android:animation="@anim/slide_in_left"/>

這里沒有設置android:direction屬性,采用默認值:left_to_right|top_to_bottom;然后是對應的animation動畫slide_in_left.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000">
<translate android:fromXDelta="-50%p" android:toXDelta="0"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" />
</set>

與LayoutAnimation所使用的動畫一樣,也是從左側50%的位置移動到初始位置,同時透明度從0變到1;

<GridView
        android:id="@+id/grid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnWidth="60dp"
        android:gravity="center"
        android:horizontalSpacing="10dp"

        android:layoutAnimation="@anim/gride_animation"

        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dp"/>

3.1.2.2 代碼使用

     GridView grid = (GridView) findViewById(R.id.grid);
    mDatas.addAll(getData());
    mGrideAdapter = new GridAdapter();
    grid.setAdapter(mGrideAdapter);

    Animation animation = AnimationUtils.loadAnimation(MyActivity.this,R.anim.slide_in_left);
    GridLayoutAnimationController controller = new GridLayoutAnimationController(animation);
    controller.setColumnDelay(0.75f);
    controller.setRowDelay(0.5f);
    controller.setDirection(GridLayoutAnimationController.DIRECTION_BOTTOM_TO_TOP|GridLayoutAnimationController.DIRECTION_LEFT_TO_RIGHT);
    controller.setDirectionPriority(GridLayoutAnimationController.PRIORITY_NONE);
    grid.setLayoutAnimation(controller);
    grid.startLayoutAnimation();

3.1.2.3 gridLayoutAnimation標簽屬性
directionPriority指gridview動畫優先級,取值有row,column,none.意義分別為行優先,列優先,和無優先級(同時進行)

direction表示gridview的各個item的動畫方向,取值如下,可以通過“|”連接多個屬性值。
取值有四個:

  • left_to_right:列,從左向右開始動畫
  • right_to_left :列,從右向左開始動畫
  • top_to_bottom:行,從上向下開始動畫
  • bottom_to_top:行,從下向上開始動畫

3.2 LayoutTransaction

上面雖然在ViewGroup類控件XML中僅添加一行android:animateLayoutChanges=[true]即可實現內部控件添加刪除時都加上動畫效果。但卻只能使用默認動畫效果,而無法自定義動畫。
為了能讓我們自定義動畫,谷歌在API 11時,同時為我們引入了一個類LayoutTransaction。
要使用LayoutTransaction是非常容易的,只需要三步:
a 創建實例

LayoutTransaction transitioner = new LayoutTransition();

b 創建設置動畫

ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);
transitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut);

c 將LayoutTransaction設置進ViewGroup

linearLayout.setLayoutTransition(mTransitioner);

   layoutTransitionGroup = (LinearLayout) findViewById(R.id.layoutTransitionGroup);  
    findViewById(R.id.add_btn).setOnClickListener(this);  
    findViewById(R.id.remove_btn).setOnClickListener(this);  

    mTransitioner = new LayoutTransition();  
    //入場動畫:view在這個容器中消失時觸發的動畫  
    ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f,0f);  
    mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn);  

    //出場動畫:view顯示時的動畫  
    ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);  
    mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut);  
3.3 listView 動畫

思路 convertView 添加動畫
http://blog.csdn.net/harvic880925/article/details/50988685

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

推薦閱讀更多精彩內容