Android动画——Vector解析

参考:http://www.jianshu.com/p/e3614e7abc03, eclipse_xu

对于图像数据来说,可以分为矢量和栅格数据,矢量数据是记录绘制图形的方式,栅格数据是以像素点为组织形式拼接成一个图形。从这也能看出矢量和栅格数据的各个优缺点:

  1. 矢量数据:占用内存小,图像清晰度不受影响。但是绘制图形效率较低,通过CPU绘制。
  2. 栅格数据:占用内存大,图像清晰度会受图像拉伸而改变。但是通过GPU绘制,效率较高。

对于Android系统,在5.0版本时Google推出了Vector来使用矢量数据。下面简单介绍一下在Android中Vector的用法和注意事项。

1. Vecotr简介

1.1 SVG与Vector差异

SVG -- 前端中使用,是一套语法规范;

SVG实例

vector -- 在Android中使用,vector只实现了SVG语法的path标签,为了提高解析效率。

1.2 Vector常用语法

M = moveto(M X,Y):将画笔移动到指定的坐标位置
L= lineto(L X, Y):画直线到指定的坐标位置
Z = closepath():关闭路径
H = horizontal lineto(H X): 画水平线到指定的X坐标位置
V = vertical lineto(V Y):画垂直线到指定的Y坐标位置

实例——画一个矩形

1.3 常用工具

SVG编辑器

SVG转换成vector

阿里巴巴矢量图标库

1.4 PNG、SVG、Vector效果对比

svg、Vector的优点:体积小,支持按比例缩放


PNG、SVG、Vector效果对比

2. Vector使用

在下面的介绍使用方法时,是基于sdk6.0的,对于兼容性问题在2.4章节由所介绍。

2.1 添加Vector

在AndroidStudio中,有两种方式直接添加转换成Vector
右键drawable文件夹,选择new,选择Vector assert,



其中一种是通过使用系统库的icon图标转换成Vector,一种是导入本地的SVG文件转换成Vector

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z"/>
</vector>

除了自动转换,还可以手动编写一个Vector。在drawable文件夹中新建一个xml文件,然后使用vector和内部的path进行绘制。其中pathData的内容是一个矩形的路径。

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="100.0"
        android:viewportHeight="100.0">
    <path
        android:name="square"
        android:fillColor="#FF000000"
        android:pathData="M0,0 L100,0 L100,100 L0, 100 z"/>
</vector>

2.2 使用静态Vector

添加完Vector文件之后,在layout布局文件添加一个ImageView来展示这个Vector,使用的是app:srcCompat来引用资源文件。

<ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/ic_android_black_24dp" />

我们尝试在Button上设置上面的Vector资源,会发现无法设置。

<Button
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/ic_android_black_24dp"/>

可以看到,在Button上用Vector是不生效的,原因是Google工程师对Vector的兼容性做出的妥协,因为Button是带有状态的控件,无法直接使用Vector。解决的办法就是使用selector插值器来配合使用。

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

    <item android:drawable="@drawable/ic_android_black_24dp" android:state_pressed="true"/>
</selector>

然后在Button控件中使用background属性

        <Button
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="@drawable/bg_btn"/>

如果想要将图形增大,无需修改pathData属性,只修改android:viewportWidth和android:viewportHeight属性就可以了。

2.3 使用动态Vector

之前提到过Vector与其他栅格图像的区别,内存小、不失真,但这些并不是使用Vector的理由,其实使用Vector就是为了能够方便动态地添加动画效果。下面就以几个典型的例子来分析如何添加动态地Vector。

2.3.1 直线运动动画

1.gif

实现如图所示的动画效果。

首先在drawable文件夹下创建图片的Vector资源文件:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <group android:name="left">
        <path
            android:fillColor="#FF000000"
            android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3z" />
    </group>
    <group android:name="right">
        <path
            android:fillColor="#FF000000"
            android:pathData="M14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z" />
    </group>
</vector>

此处由于是需要两个箭头的同时动画,这就需要为两个箭头添加不同的属性动画,所以,用group的方式进行组织,并且添加了name字段来标明。

添加完代码,可以看到是一个静态的双箭头图片。


arrow

接下来,创建两个属性动画文件,分别对应向左和向右的动画效果。

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="translateX"
    android:interpolator="@android:interpolator/overshoot"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom="0"
    android:valueTo="10"
    android:valueType="floatType">
</objectAnimator>

简单说明一下,android:propertyName="translateX"意味着在X轴方向上运动, android:interpolator被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。"@android:interpolator/overshoot"指的是向前甩一定值后再回到原来位置。android:valueFrom="0"和android:valueTo="10"表示着效果的变化范围,对应来说是x轴上的移动位置变化,这段代码展示的是左面的箭头向右移动,相对应的右面的箭头向左移动就是android:valueFrom="0"和android:valueTo="-10"。android:valueType="floatType"指明了是运行距离的floatType类型。

然后在drawable文件夹下创建Vector动画的“粘合剂”——</animated-vector>:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_arrow_back_black_24dp">
    <target
        android:animation="@animator/anim_left"
        android:name="left"/>
    <target
        android:animation="@animator/anim_right"
        android:name="right"/>
</animated-vector>

此处首先指明了 android:drawable代表图片的Vector的资源,然后在target标签下对每一个动画进行绑定,其中的name是之前的Vector图片资源文件里面的group的name属性。

最后,在粘合剂绑定完成后,用ImageView来承载这个粘合剂:

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:srcCompat="@drawable/arrow_anim"
            android:onClick="anim" />

在Activity中实现这个点击事件,让动画启动:

    public void anim(View view) {
        ImageView imageView = (ImageView) view;
        Drawable drawable = imageView.getDrawable();
        if (drawable instanceof Animatable) {
            ((Animatable) drawable).start();
        }
    }

这样就能显示出我们想要的动画效果了。

2.3.2 颜色渐变动画


接下来介绍一下颜色渐变动画的实现。

与上面的流程类似,首先创建Vector图片资源文件:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="100.0"
        android:viewportHeight="100.0">
    <path
        android:name="square"
        android:fillColor="#FF000000"
        android:pathData="M0,0 L100,0 L100,100 L0, 100 z"/>
</vector>

是一个静态的矩形


矩形

然后在animator文件下创建对应的属性动画文件anim_square.xml:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:interpolator="@android:interpolator/overshoot"
    android:propertyName="fillColor"
    android:valueFrom="@android:color/holo_red_dark"
    android:valueTo="@android:color/darker_gray"
    android:valueType="intType">
</objectAnimator>

此处android:propertyName="fillColor"指的是动画效果是填充颜色, android:valueFrom="@android:color/holo_red_dark"和android:valueTo="@android:color/darker_gray"指的是颜色的变化范围,并且值的类型是int。

然后是创建粘合剂square_anim.xml:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/square">
    <target
        android:animation="@animator/anim_square"
        android:name="square"/>
</animated-vector>

最后在ImageView上承载即可,就不多介绍了。

2.3.3 轨迹动画

主要介绍两种实现,一种是通过android:propertyName="trimPathStart",取值从0到1,表示路径从哪里开始绘制。0~trimPathStart区间的路径不会被绘制出来。一种是通过android:propertyName="pathData"定义路径的数据,路径由多条命令组成,格式与SVG标准的path data的d属性完全相同,路径命令的参数定义在viewport视图的坐标系,也就是说需要编写SVG格式的路径语句。

首先介绍第一种,看如下动画显示:


1.gif

2.gif

(1)搜索框动画
首先同样地创建Vector资源图片searchbar.xml:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="150dp"
    android:height="24dp"
    android:viewportHeight="24"
    android:viewportWidth="150">
    <path
        android:name="search"
        android:pathData="M141,17 A9,9 0 1,1 142,16 L149,23"
        android:strokeAlpha="0.8"
        android:strokeColor="#000000"
        android:strokeLineCap="round"
        android:strokeWidth="2"/>
    <path
        android:name="bar"
        android:pathData="M0,23 L149,23"
        android:strokeAlpha="0.8"
        android:strokeColor="#000000"
        android:strokeLineCap="square"
        android:strokeWidth="2"/>
</vector>

分为放大镜图标和下划线图标。

接下来就是重点的显示动画
anim_search.xml:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="trimPathStart"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType">
</objectAnimator>

anim_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="trimPathStart"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom="0"
    android:valueTo="1"
    android:valueType="floatType">
</objectAnimator>

根据上面的定义介绍,anim_search.xml表示的是动画效果是绘制路径从有到无的变化过程,anim_bar.xml表示的是动画效果是绘制路径从无到有的变化过程。

同样地,创建粘合剂searchbar_anim.xml:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/seachbar">
    <target
        android:animation="@animator/anim_search"
        android:name="search"/>
    <target
        android:animation="@animator/anim_bar"
        android:name="bar"/>
</animated-vector>

最后在ImageView中承载就可以实现上面的动画效果。

(2)星图标动画
这个动画包含两个属性动画,一个是颜色的渐变,一个是路径的变化。

Vector资源文件:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="200dp"
    android:height="200dp"
    android:viewportHeight="500"
    android:viewportWidth="500">
    <group
        android:scaleX="5.0"
        android:scaleY="5.0">
        <path
            android:name="star"
            android:pathData="M 50.0,90.0 L 82.9193546357,27.2774101308 L 12.5993502926,35.8158045183 L 59.5726265715,88.837672697 L 76.5249063296,20.0595700732 L 10.2916450361,45.1785327898 L 68.5889268818,85.4182410261 L 68.5889268818,14.5817589739 L 10.2916450361,54.8214672102 L 76.5249063296,79.9404299268 L 59.5726265715,11.162327303 L 12.5993502926,64.1841954817 L 82.9193546357,72.7225898692 L 50.0,10.0 L 17.0806453643,72.7225898692 L 87.4006497074,64.1841954817 L 40.4273734285,11.162327303 L 23.4750936704,79.9404299268 L 89.7083549639,54.8214672102 L 31.4110731182,14.5817589739 L 31.4110731182,85.4182410261 L 89.7083549639,45.1785327898 L 23.4750936704,20.0595700732 L 40.4273734285,88.837672697 L 87.4006497074,35.8158045183 L 17.0806453643,27.2774101308 L 50.0,90.0Z"
            android:strokeColor="#000000"
            android:strokeWidth="2"/>
    </group>
</vector>
path

重点是动画文件
anim_path.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="10000"
        android:propertyName="trimPathStart"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:valueFrom="1"
        android:valueTo="0"
        android:valueType="floatType">
    </objectAnimator>

    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="10000"
        android:propertyName="strokeColor"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:valueFrom="@android:color/holo_red_dark"
        android:valueTo="@android:color/darker_gray"
        android:valueType="intType">
    </objectAnimator>
</set>

通过set标签包含两个objectAnimator,两个动画同时展示出来。

最后是粘合剂path_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/path">
    <target
        android:animation="@animator/anim_path"
        android:name="star"/>
</animated-vector>

第二种,通过指定SVG路径语句


5.gif

Vector资源图片fivestar.xml:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="120dp"
    android:height="120dp"
    android:viewportHeight="64"
    android:viewportWidth="64">
    <group>
        <path
            android:name="star"
            android:fillColor="#22e171"
            android:pathData="M 48,54 L 31,42 15,54 21,35 6,23 25,23 32,4 40,23 58,23 42,35 z"
            android:strokeColor="#000000"
            android:strokeWidth="1"/>
    </group>
</vector>
fivestar

重点是动画文件anim_fivestar.xml:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:propertyName="pathData"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom="M 48,54 L 31,42 15,54 21,35 6,23 25,23 32,4 40,23 58,23 42,35 z"
    android:valueTo="M 48,54 L 31,54 15,54 10,35 6,23 25,10 32,4 40,10 58,23 54,35 z"
    android:valueType="pathType">
</objectAnimator>

着重解释一下,选用的是android:propertyName="pathData"属性,意味着需要添加图形的SVG格式运动轨迹,其中android:valueFrom是五角星,android:valueTo是五边形,所以运动轨迹就是从五角星到五边形的过程。

粘合剂代码fivestar_anim.xml:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/fivestar">
    <target
        android:animation="@animator/anim_fivestar"
        android:name="star"/>
</animated-vector>

最后添加ImageView来承载粘合剂即可。

2.3.4 总结

  1. 创建Vector图片资源文件,这个文件可能是UI设计师提供的,也可以在阿里矢量素材库等网站上获取的;
  2. 确定想要的动画效果,添加属性动画;
  3. 创建粘合剂,绑定动画和Vector资源;
  4. 用ImageView、ImageButton等控件承载粘合剂;
  5. 在Activity中启动动画。

2.4 Vector兼容性问题

Vector默认支持5.0以上版本,在AppCompat23.2以上版本支持向下兼容:
静态Vector支持Android2.1以上
动态Vector支持Android3.0以上
几乎可以兼容大部分使用场景

2.4.1 Button兼容

在上面讲到过,在Button上使用Vector必须通过Selector来完成的,在向下兼容时,需要在Activity的前面加上:

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

为了向下兼容,影响了类似DrawableContainers(DrawableContainers which reference other drawables resources which contain only a vector resource)这样的类。它的一个典型,就是Selector(StateListDrawable也是),这个属于Google工程师对于向下兼容的无奈之举吧。

2.4.2 动态兼容

(1)向下兼容
Path Morphing,即路径变换动画,(举例来说,圆形变矩形,五角星变五边形)在Android pre-L版本下是无法使用的。目前此问题是动态兼容上最大的问题。
Path Interpolation,即路径插值器,在Android pre-L版本只能使用系统的插值器,不能自定义。
Path Animation,即路径动画,这个一般使用贝塞尔曲线来代替,所以没有太大影响。
(2)向上兼容
因为考虑到兼容性的问题,会使用AppCompat库做兼容性工作。
例如,继承了AppCompatActivity,在布局文件中又指定了ImageView的srcCompat,但是AnimatedVectorDrawableCompat是不支持Path Morphing动画的。解决的方法是,判断当前设备版本号,如果是L版本以下提示不支持此动画,如果在L版本以上修改为如下代码:

ImageView imageView = (ImageView) view;
AnimatedVectorDrawable drawable= (AnimatedVectorDrawable) getDrawable(R.drawable.xxx);
imageView.setImageDrawable(drawable);
if (drawable!= null) {
    drawable.start();
}

(3)String.xml问题
不支持将Vector的PathData的数据,添加到String.xml中。

2.5 Vector属性介绍

2.5.1 Vector内部标签属性

属性 解析
android:name 定义该drawable的名字
android:width 定义该 drawable 的内部(intrinsic)宽度,支持所有 Android 系统支持的尺寸,通常使用 dp
android:height 定义该 drawable 的内部(intrinsic)高度,支持所有 Android 系统支持的尺寸,通常使用 dp
android:viewportWidth 定义矢量图视图的宽度,视图就是矢量图 path 路径数据所绘制的虚拟画布
android:viewportHeight 定义矢量图视图的高度,视图就是矢量图 path 路径数据所绘制的虚拟画布
android:tint 定义该 drawable 的 tint 颜色。默认是没有 tint 颜色的
android:tintMode 定义 tint 颜色的 Porter-Duff blending 模式,默认值为 src_in
android:autoMirrored 设置当系统为 RTL (right-to-left) 布局的时候,是否自动镜像该图片。比如 阿拉伯语。
android:alpha 该图片的透明度属性

2.5.2 path标签属性

属性 解析
android:name 定义该 path 的名字,这样在其他地方可以通过名字来引用这个路径
android:pathData 和 SVG 中 d 元素一样的路径信息。
android:fillColor 定义填充路径的颜色,如果没有定义则不填充路径
android:strokeColor 定义如何绘制路径边框,如果没有定义则不显示边框
android:strokeWidth 定义路径边框的粗细尺寸
android:strokeAlpha 定义路径边框的透明度
android:fillAlpha 定义填充路径颜色的透明度
android:trimPathStart 从路径起始位置截断路径的比率,取值范围从 0 到1
android:trimPathEnd 从路径结束位置截断路径的比率,取值范围从 0 到1
android:trimPathOffset 设置路径截取的范围 Shift trim region (allows showed region to include the start and end), in the range from 0 to 1.
android:strokeLineCap 设置路径线帽的形状,取值为 butt, round, square.
android:strokeLineJoin 设置路径交界处的连接方式,取值为 miter,round,bevel.
android:strokeMiterLimit 设置斜角的上限,Sets the Miter limit for a stroked path.

3. VectorDrawable使用场景

    1. Bitmap的绘制效率并不一定会比Vector高,它们有一定的平衡点,当Vector比较简单时,其效率是一定比Bitmap高的。所以,为了保证Vector的高效率,Vector需要更加简单,PathData更加标准、精简,当Vector图像变得非常复杂时,就需要使用Bitmap来代替。
    1. Vector适用于ICON、Button、ImageView的图标等小的ICON,或者是需要的动画效果。由于Bitmap在CPU中有缓存功能,而Vector并没有,所以Vector图像不能做频繁的重绘。
    1. Vector图像过于复杂时,不仅仅要注意绘制效率,初始化效率也是需要考虑的重要因素
    1. SVG加载速度会快于PNG,但渲染速度会慢于PNG,毕竟PNG有硬件加速,但平均下来,加载速度的提升弥补了绘制的速度缺陷。

总结来说,Vector更适用于小的控件,Button,ImageView等,有更加炫的动画效果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,044评论 25 707
  • Android Vector曲折的兼容之路 两年前写书的时候,就在研究Android L提出的Vector,可研究...
    eclipse_xu阅读 34,898评论 30 263
  • 今天我在看某脑SVG视频和网上查资料时,发现了和某位大佬的写文章的某种巧合(报以微妙的笑容)。因为强迫症,所以我想...
    仁昌居士阅读 4,599评论 0 11
  • 每个他,都有他的际遇 或许不是美好的,或许还是杯具的 正因为有他,你才觉得自己是幸福的 或许有些幸福确实来得比较晚...
    女孩的日常流水阅读 205评论 0 0
  • 文/墨歌 我喜欢听雨胜过听音乐 最是喜欢那树叶上、瓦房上的雨声 仿佛可以消除一天的疲惫 我喜欢看雨胜过看风景 最是...
    胡涂的诗阅读 102评论 2 3