Android | 說(shuō)說(shuō)從 android:text 到 TextView 的過(guò)程

前言

  • 在 Android UI 開(kāi)發(fā)中,經(jīng)常需要用到 屬性,例如使用android:text設(shè)置文本框的文案爪瓜,使用android:src設(shè)置圖片。那么翁都,android:text是如何設(shè)置到 TextView 上的呢税娜?
  • 其實(shí)這個(gè)問(wèn)題主要還是考察應(yīng)試者對(duì)于源碼(包括:LayoutInflater 布局解析概行、Style/Theme 系統(tǒng) 等)的熟悉度,在這篇文章里堡称,我將跟你一起探討桐臊。另外巫俺,文末的應(yīng)試建議也不要錯(cuò)過(guò)哦却嗡,如果能幫上忙,請(qǐng)務(wù)必點(diǎn)贊加關(guān)注坪它,這真的對(duì)我非常重要否灾。

相關(guān)文章


目錄


1. 屬性概述

1.1 屬性的本質(zhì)

屬性 (View Attributes) 本質(zhì)上是一個(gè)鍵值對(duì)關(guān)系冬筒,即:屬性名 => 屬性值。

1.2 如何定義屬性?

定義屬性需要用到<declare-styleable>標(biāo)簽,需要定義 屬性名屬性值類型,格式上可以分為以下 2 種:

格式 1 :

1.1 先定義屬性名和屬性值類型
<attr name="textColor" format="reference|color"/>

<declare-styleable name="TextView">
    1.2 引用上面定義的屬性
    <attr name="textColor" />
</declare-styleable>

格式 2:

<declare-styleable name="TextView">
    一步到位
    <attr name="text" format="string" localization="suggested" />
</declare-styleable>
  • 格式 1:分為兩步,先定義屬性名和屬性值類型焕阿,然后在引用毅桃;
  • 格式 2:一步到位莺掠,直接指定屬性名和屬性值類型。

1.3 屬性的命名空間

使用屬性時(shí),需要指定屬性的命名空間,命名空間用于區(qū)分屬性定義的位置匙铡。目前一共有 4 種 命名空間:

  • 1具帮、工具 —— toolsxmlns:tools="http://schemas.android.com/tools"

只在 Android Studio 中生效匪凡,運(yùn)行時(shí)不生效。比如以下代碼,背景色在編輯器的預(yù)覽窗口顯示白色玉控,但是在運(yùn)行時(shí)顯示黑色:

tools:background="@android:color/white"
android:background="@android:color/black"
  • 2、原生 —— androidxmlns:android="http://schemas.android.com/apk/res/android"

原生框架中attrs定義的屬性,例如,我們找到 Android P 定義的屬性 attrs.xml,其中可以看到一些我們熟知的屬性:

<!-- 文本顏色 -->
<attr name="textColor" format="reference|color"/>
<!-- 高亮文本顏色 -->
<attr name="textColorHighlight" format="reference|color" />
<!-- 高亮文本顏色 -->
<attr name="textColorHint" format="reference|color" />

你也可以在 SDK 中找到這個(gè)文件,有兩種方法:

  • 文件夾:sdk/platform/android-28/data/res/values/attrs.xml

  • Android Studio(切換到 project 視圖):External Libraries/<Android API 28 Platform>/res/values/attrs.xml

(你在這里看到的版本號(hào)是在app/build.gradle中的compileSdkVersion設(shè)置的)

  • 3、AppCompat 兼容庫(kù) —— 無(wú)需命名空間

Support 庫(kù) 或 AndroidX 庫(kù)中定義的屬性,比如:

<attr format="color" name="colorAccent"/>

你也可以在 Android Studio 中找到這個(gè)文件:

  • Android Studio(切換到 project 視圖):External Libraries/Gradle:com.android.support:appcompat-v7:[版本號(hào)]@aar/res/values/values.xml
  • 4而叼、自定義 —— appxmlns:app="http://schemas.android.com/apk/res-auto"

用排除法液荸,剩下的屬性就是自定義屬性了绊困。包括 項(xiàng)目中自定義 的屬性與 依賴庫(kù)中自定義 的屬性,比如ConstraintLayout中自定義的屬性:

<attr format="reference|enum" name="layout_constraintBottom_toBottomOf">
      <enum name="parent" value="0"/>
</attr>

你也可以在 Android Studio 中找到這個(gè)文件:

  • Android Studio(切換到 project 視圖):External Libraries/Gradle:com.android.support:constraint:constraint-layout:[版本號(hào)]@aar/res/values/values.xml

2. 樣式概述

需要注意的是:雖然樣式和主題長(zhǎng)得很像然遏,雖然兩者截然不同姨裸!

2.1 樣式的本質(zhì)

樣式(Style)是一組鍵值對(duì)的集合,本質(zhì)上是一組可復(fù)用的 View 屬性集合,代表一種類型的 Widget揖闸。類似這樣:

<style name="BaseTextViewStyle">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:includeFontPadding">false</item>
</style>

2.2 樣式的作用

使用樣式可以 復(fù)用屬性值贮泞,避免定義重復(fù)的屬性值,便于項(xiàng)目維護(hù)

隨著業(yè)務(wù)功能的疊加俯萎,項(xiàng)目中肯定會(huì)存在一些通用的,可以復(fù)用的樣式虱咧。例如在很多位置會(huì)出現(xiàn)的標(biāo)簽樣式:

觀察可以發(fā)現(xiàn)绘沉,這些標(biāo)簽雖然顏色不一樣喻喳,但是也是有共同之處:圓角谦去、邊線寬度翔怎、字體大小、內(nèi)邊距。如果不使用樣式,那么這些相同的屬性都需要在每處標(biāo)簽重復(fù)聲明。

此時(shí),假設(shè) UI 需要修改全部標(biāo)簽的內(nèi)邊距兼都,那么就需要修改每一處便簽的屬性值瓦胎,那就很繁瑣了芬萍。而使用樣式的話,就可以將重復(fù)的屬性 收攏 到一份樣式上搔啊,當(dāng)需要修改樣式時(shí)柬祠,只需要修改一個(gè)文件负芋,類似這樣:

<style name="smallTagStyle" parent="BaseTextViewStyle">
    <item name="android:paddingTop">3dp</item>
    <item name="android:paddingBottom">3dp</item>
    <item name="android:paddingLeft">4dp</item>
    <item name="android:paddingRight">4dp</item>
    <item name="android:textSize">10sp</item>
    <item name="android:maxLines">1</item>
    <item name="android:ellipsize">end</item>
</style>

2.3 在 xml 中使用樣式

使用樣式時(shí)漫蛔,需要用到style="",類似這樣:

<TextView
    android:text="標(biāo)簽"
    style="@style/smallTagStyle"/>

關(guān)于這兩句屬性是如何生效的旧蛾,我后文再說(shuō)莽龟。

2.4 樣式的注意事項(xiàng)

  • 樣式不在多層級(jí)傳遞

樣式只有在使用它的 View 上才起作用,而在它的子 View 上樣式是無(wú)效的锨天。舉個(gè)例子毯盈,假設(shè) ViewGroup 有三個(gè)按鈕,若設(shè)置 MyStyle 樣式到此 ViewGroup 上病袄,此時(shí)搂赋,僅這個(gè) ViewGroup 有效,而對(duì)三個(gè)按鈕來(lái)說(shuō)是無(wú)效的益缠。


3. 主題概述

3.1 主題的本質(zhì)

與樣式相同的是脑奠,主題(Theme)也是一組鍵值對(duì)的集合,但是它們的本質(zhì)截然不同幅慌。樣式的本質(zhì)是一組可復(fù)用的 View 屬性集合宋欺,而主題是 一組可引用的命名資源集合。類似這樣:

<style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="dialogTheme">@style/customDialog</item>
</style>

3.2 主題的作用

主題背景定義了一組可以在多處引用的資源集合胰伍,這些資源可以在樣式齿诞、布局文件、代碼等位置使用骂租。使用主題掌挚,可以方便全局替換屬性的值。

舉個(gè)例子菩咨,首先你可以定義一套深色主題和一套淺色主題:

<style name="BlackTheme" parent="AppBaseTheme">
    <item name="colorPrimary">@color/black</item>
</style>

<style name="WhiteTheme" parent="AppBaseTheme">
    <item name="colorPrimary">@color/white</item>
</style>

然后,你在需要主題化的地方引用它,類似這樣:

<ViewGroup …
    android:background="?attr/colorPrimary">

此時(shí)抽米,如果應(yīng)用了 BlackTheme 特占,那么 ViewGroup 的背景就是黑色;反之云茸,如果引用了 WhiteTheme是目,那么 ViewGroup 的背景就是白色。

在 xml 中使用主題屬性标捺,需要用到?懊纳,表示獲得此主題中的語(yǔ)義屬性代表的值。我把所有格式都總結(jié)在這里:

格式 描述
android:background="?attr/colorAccent" /
android:background="?colorAccent" ("?attr/colorAccent" 的縮寫(xiě))
android:background="?android:attr/colorAccent" (屬性的命名空間為 android)
android:background="?android:colorAccent" ("?android:attr/colorAccent")

3.3 在 xml 中使用主題

在 xml 中使用主題亡容,需要用到android:theme嗤疯,類似這樣:

1. 應(yīng)用層
<application …
    android:theme="@style/BlackTheme ">

2. Activity 層
<activity …
    android:theme="@style/BlackTheme "/>

3. View 層
<ConstraintLayout …
    android:theme="@style/BlackTheme ">

需要注意的是,android:theme本質(zhì)上也是用到 ContextThemeWrapper 來(lái)使用主題的闺兢,這在我之前寫(xiě)過(guò)的兩篇文章里說(shuō)過(guò):《Android | View & Fragment & Window 的 getContext() 一定返回 Activity 嗎茂缚?》《Android | 帶你探究 LayoutInflater 布局解析原理》屋谭。這里我簡(jiǎn)單復(fù)述一下:

LayoutInflater.java

private static final int[] ATTRS_THEME = new int[] {
    com.android.internal.R.attr.theme
};

final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
final int themeResId = ta.getResourceId(0, 0);
if (themeResId != 0) {
    構(gòu)造 ContextThemeWrapper
    context = new ContextThemeWrapper(context, themeResId);
}
  • 1脚囊、LayoutInflater 在進(jìn)行布局解析時(shí),需要根據(jù) xml 實(shí)例化 View桐磁;
  • 2悔耘、在解析流程中,會(huì)判斷 View 是否使用了android:theme我擂;
  • 3衬以、如果使用,則使用 ContextThemeWrapper 包裝 Context扶踊,并將包裝類用于子 View 的實(shí)例化過(guò)程泄鹏。

3.4 在代碼中使用主題

在代碼中使用主題,需要用到ContextThemeWrapper & Theme秧耗,它們都提供了設(shè)置主題資源的方法:

ContextThemeWrapper.java

@Override
public void setTheme(int resid) {
    if (mThemeResource != resid) {
        mThemeResource = resid;
        最終調(diào)用的是 Theme#applyStyle(...)
        initializeTheme();
    }
}

Theme.java

public void applyStyle(int resId, boolean force) {
    mThemeImpl.applyStyle(resId, force);
}

當(dāng)構(gòu)造新的 ContextThemeWrapper 之后备籽,它會(huì)分配新的主題 (Theme) 和資源 (Resources) 實(shí)例。那么分井,最終主題是在哪里生效的呢车猬,我在 第 4 節(jié) 說(shuō)。

3.5 主題的注意事項(xiàng)

  • 主題會(huì)在多層級(jí)傳遞

與樣式不同的是尺锚,主題對(duì)于更低層級(jí)也是有效的珠闰。舉個(gè)例子,假設(shè) Activity 設(shè)置 BlackTheme瘫辩,那么對(duì)于 Activity 上的所有 View 是有效的伏嗜。此時(shí)坛悉,如果其中 View 單獨(dú)指定了 android:theme,那么此 View 將單獨(dú)使用新的主題承绸。

  • 勿使用 Application Context 加載資源

Application 是 ContextWrapper 的子類裸影,因此Application Context 不保留任何主題相關(guān)信息,在 manifest 中設(shè)置的主題僅用作未明確設(shè)置主題背景的 Activity 的默認(rèn)選擇军熏。切勿使用 Application Context 加載可使用的資源轩猩。


4. 問(wèn)題回歸

現(xiàn)在,我們回過(guò)頭來(lái)討論 從 android:text 到 TextView 的過(guò)程荡澎。其實(shí)均践,這說(shuō)的是如何將android:text屬性值解析到 TextView 上。這個(gè)過(guò)程就是 LayoutInflater 布局解析的過(guò)程摩幔,我之前專門寫(xiě)過(guò)一篇文章探討布局解析的核心過(guò)程:《Android | 帶你探究 LayoutInflater 布局解析原理》彤委,核心過(guò)程如下圖:

4.1 AttributeSet

在前面的文章里,我們已經(jīng)知道 LayoutInflater 通過(guò)反射的方式實(shí)例化 View热鞍。其中的參數(shù)args分別是 Context & AttributeSet:

  • Context:上下文葫慎,有可能是包裝類 ContextThemeWrapper
  • AttributeSet:屬性列表,xml 中 View聲明的屬性都會(huì)解析到這個(gè)對(duì)象上薇宠。

LayoutInflater.java

final View view = constructor.newInstance(args);

舉個(gè)例子偷办,假設(shè)有布局文件,我們嘗試輸出 LayoutInflater 實(shí)例化 View 時(shí)傳入的 AttributeSet:

<...MyTextView
    android:text="標(biāo)簽"
    android:theme="@style/BlackTheme"
    android:textColor="?colorPrimary"
    style="@style/smallTagStyle"/>

MyTextView.java

public MyTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    總共有 4 個(gè)屬性
    for (int index = 0; index < attrs.getAttributeCount(); index++) {
        System.out.println(attrs.getAttributeName(index) + " = " + attrs.getAttributeValue(index));
    }
}

AttributeSet.java

返回屬性名稱字符串(不包括命名空間)
public String getAttributeValue(int index);

返回屬性值字符串
public String getAttributeValue(int index);

輸出如下:

theme = @2131558563
textColor = ?2130837590
text = 標(biāo)簽
style = @2131558752

可以看到澄港,AttributeSet 里只包含了在 xml 中直接聲明的屬性椒涯,對(duì)于引用類型的屬性,AttributeSet 只是記錄了資源 ID回梧,并不會(huì)把它拆解開(kāi)來(lái)废岂。

4.2 TypedArray

想要取到真實(shí)的屬性值,需要用到 TypeArray狱意,另外還需要一個(gè) int 數(shù)組(其中湖苞,int 值是屬性 ID)。類似這樣:

private static final int[] mAttr = {android.R.attr.textColor, android.R.attr.layout_width};

private static final int ATTR_ANDROID_TEXTCOLOR = 0;
private static final int ATTR_ANDROID_LAYOUT_WIDTH = 1;

1. 從 AttributeSet 中加載屬性
TypedArray a = context.obtainStyledAttributes(attrs, mAttr);
for (int index = 0; index < a.getIndexCount(); index++) {
    2. 解析每個(gè)屬性
    switch (index) {
        case ATTR_ANDROID_TEXTCOLOR:
            System.out.println("attributes : " + a.getColor(index, Color.RED));
        break;
        case ATTR_ANDROID_LAYOUT_WIDTH:
            System.out.println("attributes : " + a.getInt(index, 0));
        break;
    }
}

在這里详囤,mAttr 數(shù)組是兩個(gè) int 值财骨,分別是android.R.attr.textColorandroid.R.attr.layout_width,表示我們感興趣的屬性藏姐。當(dāng)我們將 mAttr 用于Context#obtainStyledAttributes()隆箩,則只會(huì)解析出我們感興趣的屬性來(lái)。

輸出:

-16777216 羔杨,即:Color.BLACK => 這個(gè)值來(lái)自于 ?attr/colorPrimary 引用的主題屬性
-2 捌臊,即:WRAP_CONTENT => 這個(gè)值來(lái)自于 @style/smallTagStyle 中引用的樣式屬性

需要注意的是,大多數(shù)情況下并不需要在代碼中硬編碼兜材,而是使用<declare-styleable>標(biāo)簽理澎。編譯器會(huì)自動(dòng)在R.java中為我們聲明相同的數(shù)組逞力,類似這樣:

<declare-styleable name="MyTextView">
    <attr name="android:textColor" />
    <attr name="android:layout_width" />
</declare-styleable>

R.java

public static final int[] MyTextView={ 相當(dāng)于 mAttr
    0x01010098, 0x010100f4
};
public static final int MyTextView_android_textColor=0; 相當(dāng)于 ATTR_ANDROID_TEXTCOLOR 
public static final int MyTextView_android_layout_width=1; 相當(dāng)于 ATTR_ANDROID_LAYOUT_WIDTH 

提示: 使用R.styleable.設(shè)計(jì)的優(yōu)點(diǎn)是:避免解析不需要的屬性。

4.3 Context#obtainStyledAttributes() 取值順序

現(xiàn)在矾端,我們來(lái)討論obtainStyledAttributes()解析屬性值的優(yōu)先級(jí)順序掏击,總共分為以下幾個(gè)順序。當(dāng)在越優(yōu)先的級(jí)別找到屬性時(shí)秩铆,優(yōu)先返回該處的屬性值:View > Style > Default Style > Theme

  • View

指 xml 直接指定的屬性灯变,類似這樣:

<TextView
    ...
    android:textColor="@color/black"/>
  • Style

指 xml 在樣式中指定的屬性殴玛,類似這樣:

<TextView
    ...
    android:textColor="@style/colorTag"/>

<style name="colorTag">
    <item name="android:textColor">@color/black</item>
  • Default Style

指在 View 構(gòu)造函數(shù)中指定的樣式,它是構(gòu)造方法的第 3 個(gè)參數(shù)添祸,類似于 TextView 這樣:

public AppCompatTextView(Context context, AttributeSet attrs) {
    this(context, attrs, android.R.attr.textViewStyle);
}

public AppCompatTextView(Context context, AttributeSet attrs, @AttrRes int defStyleAttr) {
    super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
    ...
}

其中滚粟,android.R.attr.textViewStyle表示引用主題中的textViewStyle屬性,這個(gè)值在主題資源中指定的是一個(gè)樣式資源:

<item name="android:textViewStyle">@style/Widget.AppCompat.TextView</item>

提示:@AttrRes可以看出刃泌,defStyleAttr 一定要引用主題屬性凡壤。

  • Default Style Resource

指在 View 構(gòu)造函數(shù)中指定的樣式資源耙替,它是構(gòu)造方法的第 3 個(gè)參數(shù):

public View(Context context, AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
}

提示:@StyleRes可以看出俗扇,defStyleRes 一定要引用樣式資源滞谢。

  • Theme

如果以上層級(jí)全部無(wú)法匹配到屬性到忽,那么就會(huì)使用主題中的主題屬性滓走,類似這樣:

<style name="AppTheme" parent="...">
    ...
    <item name="android:textColor">@color/black</item>
</style>

5. 屬性值類型

前文提到,定義屬性需要指定:屬性名屬性值類型涛漂,屬性值類型可以分為資源類與特殊類

5.1 資源類

屬性值類型 描述 TypedArray
fraction 百分?jǐn)?shù) getFraction(...)
float 浮點(diǎn)數(shù) getFloat(...)
boolean 布爾值 getBoolean(...)
color 顏色值 getColor(...)
string 字符串 getString(...)
dimension 尺寸值 getDimensionPixelOffset(…)
getDimensionPixelSize(...)
getDimension(...)
integer 整數(shù)值 getInt(...)
getInteger(...)

5.2 特殊類

屬性值類型 描述 TypedArray
flag 標(biāo)志位 getInt(...)
enum 枚舉值 getInt(…)等
reference 資源引用 getDrawable(...)等

fraction 比較難理解,這里舉例解釋下:

  • 1音比、屬性定義
<declare-styleable name="RotateDrawable">
    // ...
    <attr name="pivotX" format="float|fraction" />
    <attr name="pivotY" format="float|fraction" />
    <attr name="drawable" />
</declare-styleable>
  • 設(shè)置屬性值
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
   android:pivotX="50%"
   android:pivotY="50%"
   android:drawable="@drawable/fifth">
</animated-rotate>
if (a.hasValue(R.styleable.RotateDrawable_pivotX)) {
    // 取出對(duì)應(yīng)的TypedValue
    final TypedValue tv = a.peekValue(R.styleable.RotateDrawable_pivotX);
    // 判斷屬性值是float還是fraction
    state.mPivotXRel = tv.type == TypedValue.TYPE_FRACTION;
    // 取出最終的值
    state.mPivotX = state.mPivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
}

可以看到俱笛,pivotX 支持 float 和 fraction 兩種類型,因此需要通過(guò)TypedValue#type判斷屬性值的類型贩幻,分別調(diào)用TypedValue#getFraction()TypedValue#getFloat()坎穿。

getFraction(float base,float pbase)的兩個(gè)參數(shù)為基數(shù)玷犹,最終的返回值是 基數(shù)*百分?jǐn)?shù)幻妓。舉個(gè)例子,當(dāng)設(shè)置的屬性值為 50% 時(shí),返回值為 base50%* ;當(dāng)設(shè)置的屬性值為 50%p 時(shí),返回值為 pbase*50%眶诈。


6. 總結(jié)

  • 應(yīng)試建議
    • 應(yīng)理解樣式和主題的區(qū)別氧敢,兩者截然不同:樣式是一組可復(fù)用的 View 屬性集合梅掠,而主題是一組命名的資源集合。
    • 應(yīng)掌握屬性來(lái)源優(yōu)先級(jí)順序:View > Style > Default Style > Theme

參考資料

推薦閱讀

感謝喜歡!你的點(diǎn)贊是對(duì)我最大的鼓勵(lì)璧南!歡迎關(guān)注彭旭銳的GitHub掌逛!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市司倚,隨后出現(xiàn)的幾起案子豆混,更是在濱河造成了極大的恐慌篓像,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崖叫,死亡現(xiàn)場(chǎng)離奇詭異遗淳,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)心傀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門屈暗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人脂男,你說(shuō)我怎么就攤上這事养叛。” “怎么了宰翅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵弃甥,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我汁讼,道長(zhǎng)淆攻,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任嘿架,我火速辦了婚禮瓶珊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘耸彪。我一直安慰自己伞芹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布蝉娜。 她就那樣靜靜地躺著唱较,像睡著了一般。 火紅的嫁衣襯著肌膚如雪召川。 梳的紋絲不亂的頭發(fā)上南缓,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音荧呐,去河邊找鬼汉形。 笑死,一個(gè)胖子當(dāng)著我的面吹牛坛增,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播薄腻,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼收捣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了庵楷?” 一聲冷哼從身側(cè)響起罢艾,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤楣颠,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后咐蚯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體童漩,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年春锋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了矫膨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡期奔,死狀恐怖侧馅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呐萌,我是刑警寧澤馁痴,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站肺孤,受9級(jí)特大地震影響罗晕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赠堵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一小渊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧顾腊,春花似錦粤铭、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至吗垮,卻和暖如春垛吗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烁登。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工怯屉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人饵沧。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓锨络,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親狼牺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子羡儿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348