AndroidStudio插件開發(fā)(進(jìn)階篇之Action機(jī)制)

轉(zhuǎn)載請(qǐng)注明出處:【huachao1001的簡(jiǎn)書:http://www.reibang.com/users/0a7e42698e4b/latest_articles】

從上一篇《AndroidStudio插件開發(fā)(Hello World篇)》中我們已經(jīng)大致了解了Action挥吵,這篇文章繼續(xù)深入探究IntelliJ IDEA插件開發(fā)中的Action機(jī)制逝淹。一個(gè)Action本質(zhì)上來(lái)說(shuō)就是一個(gè)Java類俗批,并且這個(gè)類需要繼承AnAction莺债。而一個(gè)Action對(duì)應(yīng)于一個(gè)菜單項(xiàng),每一次點(diǎn)擊這個(gè)菜單項(xiàng)就回調(diào)這個(gè)Action的actionPerformed(AnActionEvent event)函數(shù)闲询,因此我們定義的Action在繼承AnAction時(shí)竿拆,需要重寫actionPerformed函數(shù)鳖藕。定義好Action類后,我們需要注冊(cè)Action孝情,即在plugin.xml文件中添加Action對(duì)應(yīng)的標(biāo)簽鱼蝉,在這個(gè)標(biāo)簽中定義了Action應(yīng)放置在界面的的哪個(gè)位置,作為哪個(gè)菜單項(xiàng)的子項(xiàng)等箫荡。接下來(lái)我們對(duì)Action機(jī)制進(jìn)行深入魁亦。

1. 定義Action(繼承AnAction)

定義Action只需簡(jiǎn)單地定義一個(gè)繼承AnAction的子類即可,子類中羔挡,最重要的就是actionPerformed函數(shù)和update函數(shù)洁奈。

1.1 重寫actionPerformed函數(shù)

我們知道,每次在菜單項(xiàng)中點(diǎn)擊我們自定義的Action時(shí)绞灼,對(duì)應(yīng)會(huì)執(zhí)行AnAction的actionPerformed函數(shù)利术。對(duì)應(yīng)actionPerformed函數(shù)的理解,只需記住低矮,當(dāng)回調(diào)actionPerformed函數(shù)函數(shù)時(shí)印叁,就意味著當(dāng)前Action被點(diǎn)擊了一次。重寫actionPerformed函數(shù)非常簡(jiǎn)單军掂,這里簡(jiǎn)單彈出一個(gè)Hello World轮蜕。

package com.huachao.plugin;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;

/**
 * Created by huachao on 2016/12/26.
 */
public class MyAction extends AnAction {
    @Override
    public void actionPerformed(AnActionEvent event) {
        Project project = event.getData(PlatformDataKeys.PROJECT);
        Messages.showMessageDialog(project, "Hello World!", "Information", Messages.getInformationIcon());
    }
}

1.2 重寫update函數(shù)

我們知道,為了響應(yīng)用戶的點(diǎn)擊操作良姆,我們重寫了actionPerformed函數(shù)肠虽。在actionPerformed函數(shù)中執(zhí)行一些邏輯,比如彈出對(duì)話框玛追,在打開文件中自動(dòng)生成代碼等等操作税课。這些邏輯在actionPerformed函數(shù)中完成就好闲延,但是,有時(shí)候我們定義的插件只在某些場(chǎng)景中使用韩玩。比如說(shuō)垒玲,當(dāng)我們編寫自動(dòng)生成代碼的插件時(shí),只有當(dāng)有文件打開時(shí)才可以正常執(zhí)行找颓。因此合愈,當(dāng)我們不希望用戶點(diǎn)擊我們定義的插件時(shí),我們可以將插件隱藏击狮,讓用戶無(wú)法看到插件佛析,只有當(dāng)符合插件執(zhí)行的環(huán)境時(shí),才讓插件在菜單中顯示彪蓬。

為了能在用戶點(diǎn)擊自定義插件對(duì)應(yīng)的菜單項(xiàng)之前動(dòng)態(tài)判斷是否將插件項(xiàng)顯示寸莫,只需重寫update函數(shù)。

update函數(shù)在Action狀態(tài)發(fā)生更新時(shí)被回調(diào)档冬,當(dāng)Action狀態(tài)刷新時(shí)膘茎,update函數(shù)被IDEA回調(diào),并且傳遞AnActionEvent對(duì)象酷誓,AnAction對(duì)象中封裝了當(dāng)前Action對(duì)應(yīng)的環(huán)境披坏。

如何理解上面這段話呢?我們知道盐数,我們定義的每個(gè)Action都在菜單中對(duì)應(yīng)一個(gè)子選項(xiàng)(為了方便描述棒拂,本文稱之為Action菜單項(xiàng)),當(dāng)Action菜單項(xiàng)被點(diǎn)擊或者是Action的父菜單(包含Action菜單項(xiàng)的菜單)被點(diǎn)擊使得Action菜單項(xiàng)被顯示出來(lái)時(shí)玫氢,就會(huì)回調(diào)update函數(shù)着茸。在update被回調(diào)時(shí),傳入AnActionEvent對(duì)象琐旁,通過AnActionEvent對(duì)象我們可以判斷當(dāng)前編輯框是否已經(jīng)打開等實(shí)時(shí)IDEA環(huán)境狀況涮阔。

注意:先執(zhí)行update函數(shù),再執(zhí)行actionPerformed函數(shù)灰殴。換言之敬特,update發(fā)生在actionPerformed之前。

比如牺陶,我們想要實(shí)現(xiàn):當(dāng)編輯框被打開時(shí)顯示自定義的Action菜單項(xiàng)伟阔,否則,將Action菜單項(xiàng)設(shè)置為灰色掰伸。

@Override
public void update(AnActionEvent e) {
    Editor editor = e.getData(PlatformDataKeys.EDITOR);

    if (editor != null)
        e.getPresentation().setEnabled(true);
    else
        e.getPresentation().setEnabled(false);

}

代碼中皱炉,如果editor!=null即編輯框已打開,將Action菜單項(xiàng)設(shè)置為可用狀態(tài)(即正常顏色狮鸭,黑色)合搅,否則設(shè)置為不可用狀態(tài)(即灰色)多搀。當(dāng)然了,你也可以通過e.getPresentation().setVisible(false);將Action菜單項(xiàng)設(shè)置為不可見灾部,這樣Action菜單項(xiàng)就不會(huì)出現(xiàn)在菜單中康铭。

另外,不要忘記在plugin.xml中將MyAction注冊(cè)赌髓,具體注冊(cè)方法可以參考上一篇文章《AndroidStudio插件開發(fā)(Hello World篇)》或者后一節(jié)的詳細(xì)介紹从藤。

當(dāng)編輯框被打開時(shí)(即有文件打開時(shí)),可以看到我們自定義的插件是正常锁蠕。

這里寫圖片描述

當(dāng)編輯框被關(guān)閉時(shí)(即沒有文件被打開時(shí))夷野,可以看到我們自定義的插件是灰色。

這里寫圖片描述

注意:Action菜單項(xiàng)為灰色并不意味著被點(diǎn)擊時(shí)actionPerformed不會(huì)被調(diào)用荣倾,相反扫责,只要Action菜單項(xiàng)被點(diǎn)擊,actionPerformed函數(shù)就會(huì)被調(diào)用逃呼。因此如果希望點(diǎn)擊Action菜單項(xiàng)時(shí)不做響應(yīng),需要在actionPerformed函數(shù)里面再次做具體判斷者娱。

1.3 關(guān)于AnActionEvent

前面我們多次用到了AnActionEvent 對(duì)象抡笼,AnActionEvent 函數(shù)和update函數(shù)的形參都包含AnActionEvent對(duì)象。AnActionEvent對(duì)象是我們與IntelliJ IDEA交互的橋梁黄鳍,我們可以通過AnActionEvent對(duì)象獲取當(dāng)前IntelliJ IDEA的各個(gè)模塊對(duì)象推姻,如編輯框窗口對(duì)象、項(xiàng)目窗口對(duì)象等框沟,獲取到這些對(duì)象我們就可以做一些定制的效果藏古。

1.3.1 getData函數(shù)

通過AnActionEvent對(duì)象的getData函數(shù)可以得到IDEA界面各個(gè)窗口對(duì)象以及各個(gè)窗口為實(shí)現(xiàn)某些特定功能的對(duì)象。getData函數(shù)需要傳入DataKey<T>對(duì)象忍燥,用于指明想要獲取的IDEA中的哪個(gè)對(duì)象拧晕。在CommonDataKeys已經(jīng)定義好各個(gè)IDEA對(duì)象對(duì)應(yīng)的DataKey<T>對(duì)象。

CommonDataKeys.java定義的DataKey<T>對(duì)象如下:

public static final DataKey<Project> PROJECT = DataKey.create("project");
public static final DataKey<Editor> EDITOR = DataKey.create("editor");
public static final DataKey<Editor> HOST_EDITOR = DataKey.create("host.editor");
public static final DataKey<Caret> CARET = DataKey.create("caret");
public static final DataKey<Editor> EDITOR_EVEN_IF_INACTIVE = DataKey.create("editor.even.if.inactive");
public static final DataKey<Navigatable> NAVIGATABLE = DataKey.create("Navigatable");
public static final DataKey<Navigatable[]> NAVIGATABLE_ARRAY = DataKey.create("NavigatableArray");
public static final DataKey<VirtualFile> VIRTUAL_FILE = DataKey.create("virtualFile");
public static final DataKey<VirtualFile[]> VIRTUAL_FILE_ARRAY = DataKey.create("virtualFileArray");
public static final DataKey<PsiElement> PSI_ELEMENT = DataKey.create("psi.Element");
public static final DataKey<PsiFile> PSI_FILE = DataKey.create("psi.File");
public static final DataKey<Boolean> EDITOR_VIRTUAL_SPACE = DataKey.create("editor.virtual.space");

不僅僅CommonDataKeys中定義了DataKey<T>對(duì)象梅垄,為了添加更多的DataKey<T>對(duì)象并且兼容等厂捞,又提供了PlatformDataKeys類,PlatformDataKeys類是CommonDataKeys子類队丝,也就是說(shuō)靡馁,只要是CommonDataKeys有的,PlatformDataKeys類都有机久。

PlatformDataKeys.java定義的DataKey<T>對(duì)象如下:

public static final DataKey<FileEditor> FILE_EDITOR = DataKey.create("fileEditor");
public static final DataKey<String> FILE_TEXT = DataKey.create("fileText");
public static final DataKey<Boolean> IS_MODAL_CONTEXT = DataKey.create("isModalContext");
public static final DataKey<DiffViewer> DIFF_VIEWER = DataKey.create("diffViewer");
public static final DataKey<DiffViewer> COMPOSITE_DIFF_VIEWER = DataKey.create("compositeDiffViewer");
public static final DataKey<String> HELP_ID = DataKey.create("helpId");
public static final DataKey<Project> PROJECT_CONTEXT = DataKey.create("context.Project");
public static final DataKey<Component> CONTEXT_COMPONENT = DataKey.create("contextComponent");
public static final DataKey<CopyProvider> COPY_PROVIDER = DataKey.create("copyProvider");
public static final DataKey<CutProvider> CUT_PROVIDER = DataKey.create("cutProvider");
public static final DataKey<PasteProvider> PASTE_PROVIDER = DataKey.create("pasteProvider");
public static final DataKey<DeleteProvider> DELETE_ELEMENT_PROVIDER = DataKey.create("deleteElementProvider");
public static final DataKey<Object> SELECTED_ITEM = DataKey.create("selectedItem");
public static final DataKey<Object[]> SELECTED_ITEMS = DataKey.create("selectedItems");
public static final DataKey<Rectangle> DOMINANT_HINT_AREA_RECTANGLE = DataKey.create("dominant.hint.rectangle");
public static final DataKey<ContentManager> CONTENT_MANAGER = DataKey.create("contentManager");
public static final DataKey<ToolWindow> TOOL_WINDOW = DataKey.create("TOOL_WINDOW");
public static final DataKey<TreeExpander> TREE_EXPANDER = DataKey.create("treeExpander");
public static final DataKey<ExporterToTextFile> EXPORTER_TO_TEXT_FILE = DataKey.create("exporterToTextFile");
public static final DataKey<VirtualFile> PROJECT_FILE_DIRECTORY = DataKey.create("context.ProjectFileDirectory");
public static final DataKey<Disposable> UI_DISPOSABLE = DataKey.create("ui.disposable");
public static final DataKey<ContentManager> NONEMPTY_CONTENT_MANAGER = DataKey.create("nonemptyContentManager");
public static final DataKey<ModalityState> MODALITY_STATE = DataKey.create("ModalityState");
public static final DataKey<Boolean> SOURCE_NAVIGATION_LOCKED = DataKey.create("sourceNavigationLocked");
public static final DataKey<String> PREDEFINED_TEXT = DataKey.create("predefined.text.value");
public static final DataKey<String> SEARCH_INPUT_TEXT = DataKey.create("search.input.text.value");
public static final DataKey<Object> SPEED_SEARCH_COMPONENT = DataKey.create("speed.search.component.value");
public static final DataKey<Point> CONTEXT_MENU_POINT = DataKey.create("contextMenuPoint");

1.3.2 Presentation對(duì)象

一個(gè)Presentation對(duì)象表示一個(gè)Action在菜單中的外觀臭墨,通過Presentation可以獲取Action菜單項(xiàng)的各種屬性,如顯示的文本膘盖、描述胧弛、圖標(biāo)(Icon)等尤误。并且可以設(shè)置當(dāng)前Action菜單項(xiàng)的狀態(tài)、是否可見叶圃、顯示的文本等等袄膏。通過AnActionEvent對(duì)象的getPresentation()函數(shù)可以取得Presentation對(duì)象。

2. 注冊(cè)Action(修改plugin.xml)

注冊(cè)Action掺冠,我們可以手動(dòng)直接修改plugin.xml文件沉馆,也可由IDEA直接自動(dòng)幫我們生成,甚至是通過代碼動(dòng)態(tài)注冊(cè)德崭。其中斥黑,個(gè)人認(rèn)為必須把手動(dòng)注冊(cè)過程掌握透徹,這樣就能理解自動(dòng)注冊(cè)與代碼注冊(cè)的原理眉厨。

2.1 手動(dòng)注冊(cè)Action

2.1.1 單個(gè)Action

手動(dòng)注冊(cè)即我們直接修改plugin.xml文件锌奴,在plugin.xml文件(resoutces/META-INF/plugin.xml)中找到<actions>標(biāo)簽,并在<actions>標(biāo)簽中添加<action>標(biāo)簽憾股。<action>標(biāo)簽的屬性在上一篇文章中解釋過鹿蜀,這里再解釋一遍:

id:作為<action>標(biāo)簽的唯一標(biāo)識(shí)。一般以<項(xiàng)目名>.<類名>方式服球。
class:即我們自定義的AnAction類
text:顯示的文字茴恰,如我們自定義的插件放在菜單列表中,這個(gè)文字就是對(duì)應(yīng)的菜單項(xiàng)
description:對(duì)這個(gè)AnAction的描述

<add-to-group>標(biāo)簽用于描述當(dāng)前Action放入到那個(gè)菜單組中斩熊,<add-to-group>標(biāo)簽主要關(guān)注anchor屬性和relative-to-action屬性往枣。anchor屬性用于描述位置,主要有四個(gè)選項(xiàng):first粉渠、last分冈、before、after霸株。他們的含義如下:

first:放在所有子菜單的最前面
last:放在所有子菜單的最后
before:放在relative-to-action屬性指定的ID的子菜單的前面
after:放在relative-to-action屬性指定的ID的子菜單的后面

<keyboard-shortcut>標(biāo)簽用于描述快捷鍵雕沉,主要關(guān)注2個(gè)屬性:keymap和first-keystroke。keymap使用默認(rèn)值($default)就好去件,first-keystroke用于指定快捷鍵蘑秽。

將Action菜單項(xiàng)放入到Help菜單的最前面,示例如下:

<actions>
    <!-- Add your actions here -->
    <action class="com.huachao.plugin.MyAction" id="StudyAction.MyAction" text="Hello Action">
        <add-to-group group-id="HelpMenu" anchor="first"/>
        <keyboard-shortcut keymap="$default" first-keystroke="ctrl alt Q"/>
    </action>
</actions>
Action菜單項(xiàng)

2.1.2 Action組(Action Group)

前面我們都是將一個(gè)Action放入到已有的菜單中作為子選項(xiàng)◇锱剩現(xiàn)在我們定義一個(gè)跟Help同級(jí)的菜單肠牲,或者是定義包含多個(gè)子選項(xiàng)的菜單,這就是Action Group靴跛。使用Action Group非常簡(jiǎn)單缀雳,就是在<actions>標(biāo)簽中添加<group>子標(biāo)簽,<group>標(biāo)簽主要關(guān)注3個(gè)屬性:id梢睛、text肥印、popup识椰。id和text跟<action>標(biāo)簽意義一樣,不再解釋深碱,但需要注意腹鹉,text中如果需要首字母加下劃線,則開頭下“_”即可敷硅。popup屬性用于描述是否有子菜單彈出功咒,如果取值為true,則<group>標(biāo)簽的內(nèi)所有的<action>子標(biāo)簽作為<group>菜單的子選項(xiàng)绞蹦,否則力奋,<group>標(biāo)簽的內(nèi)所有的<action>子標(biāo)簽將替換<group>菜單項(xiàng)所在的位置,即沒有<group>這一層菜單幽七。下面通過一個(gè)例子進(jìn)行對(duì)比景殷。

<actions>
    <group id="StudyAction.MyGroup" text="_MyGroup" popup="true">
        <add-to-group group-id="HelpMenu" anchor="first"/>
        <action class="com.huachao.plugin.MyAction" id="StudyAction.MyAction" text="Hello Action">
            <keyboard-shortcut keymap="$default" first-keystroke="ctrl alt Q"/>
        </action>
        <action id="StudyAction.SecondAction" class="com.huachao.plugin.SecondAction" text="SecondAction"/>
    </group>

</actions>

運(yùn)行結(jié)果如下:


Action Group

將popup屬性改為false運(yùn)行結(jié)果如下:

Action Group

注意到,我們將<group><add-to-group>子標(biāo)簽的group-id屬性依然指定為Help菜單澡屡,現(xiàn)在我們換成與Help同級(jí)猿挚。將group-id屬性指定為MainMenu,運(yùn)行如下:

添加到MainMenu

可以看到,IDEA的所有的導(dǎo)航菜單都放在MainMenu中驶鹉,我們指定了anchor="first"绩蜻,因此被加入第一個(gè)位置。接下來(lái)我們?cè)倏纯磳roup加入到編輯框窗口右鍵菜單梁厉,只需將group-id屬性指定為EditorPopupMenu,運(yùn)行如下:

加入編輯框窗口右鍵菜單

修改為項(xiàng)目窗口右鍵菜單,修改group-id為:ProjectViewPopupMenu踏兜。運(yùn)行如下:

加入項(xiàng)目窗口右鍵菜單

2.2 IDEA自動(dòng)注冊(cè)Action

在我們熟悉了手動(dòng)修改plugin.xml后词顾,使用IDEA的方式就更簡(jiǎn)單了。直接點(diǎn)擊在包目錄上右擊>New>Action碱妆。彈出框?qū)?yīng)填寫屬性即可肉盹,這樣在自動(dòng)創(chuàng)建Action的同時(shí),完成了Action的注冊(cè)疹尾。

IDEA自動(dòng)注冊(cè)

2.3 代碼動(dòng)態(tài)注冊(cè)Action

代碼動(dòng)態(tài)注冊(cè)Action主要是以Action Group動(dòng)態(tài)添加和移除Action上忍。前面我們?cè)谑褂?code><group>標(biāo)簽時(shí),沒有使用到class屬性纳本,即我們沒有定義自己的Action Group窍蓝,而是使用默認(rèn)的Action Group(DefaultActionGroup)。為了定制自己的Action Group繁成,我們定義MyGroup類吓笙,使之繼承ActionGroup類,并在<group>標(biāo)簽的class屬性中指定com.huachao.plugin.MyGroup巾腕。

package com.huachao.plugin;

import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Created by huachao on 2016/12/26.
 */
public class MyGroup extends ActionGroup {


    @NotNull
    @Override
    public AnAction[] getChildren(@Nullable AnActionEvent anActionEvent) {
        return new AnAction[]{new CustomAction("first"),new CustomAction("second")};
    }


    class CustomAction extends AnAction {
        public CustomAction(String text) {
            super(text);
        }
        @Override
        public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
        }
    }
}

plugin.xml文件中對(duì)應(yīng)的<actions>標(biāo)簽如下:

<actions>
    <group id="StudyAction.MyGroup" class="com.huachao.plugin.MyGroup" text="_MyGroup" popup="true">
        <add-to-group group-id="MainMenu" anchor="last"/> 
    </group> 
</actions>

運(yùn)行結(jié)果如下:

代碼注冊(cè)

如果我們想在plugin.xml中注冊(cè)Action面睛,并且想修改Group的菜單屬性絮蒿。我們只需重寫DefaultActionGroup的update函數(shù),DefaultActionGroup的update函數(shù)與AnAction的update函數(shù)意義差不多叁鉴,前面解釋過AnAction的update函數(shù)土涝,這里就不再解釋。例如幌墓,我們將Group菜單添加一個(gè)圖標(biāo)但壮,代碼如下:

package com.huachao.plugin;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.editor.Editor;

/**
 * Created by huachao on 2016/12/26.
 */
public class MyGroup extends DefaultActionGroup {

    @Override
    public void update(AnActionEvent e) {
        Editor editor = e.getData(CommonDataKeys.EDITOR);
        e.getPresentation().setVisible(true);
        e.getPresentation().setEnabled(editor != null);
        e.getPresentation().setIcon(AllIcons.General.Error);
    }
}


運(yùn)行結(jié)果如下:

修改Action Group菜單項(xiàng)

3. 總結(jié)

定義一個(gè)AndroidStudio插件只需簡(jiǎn)單的2步:

  1. 定義Action
  • actionPerformed()
  • update()
  • AnActionEvent對(duì)象
  1. 注冊(cè)Action
  • 手動(dòng)修改plugin.xml
  • Action Group
  • IDEA自動(dòng)生成(New>Action>...)
  • 代碼注冊(cè)(通過Acton Group動(dòng)態(tài)添加)

相比上一篇文章,在本文中克锣,我們知其然更知其所以然茵肃。為后面定制AndroidStudio打下基礎(chǔ)。

參考資料

Action System相關(guān)類源碼(Github):《intellij-community》

官網(wǎng)資料:http://www.jetbrains.org/intellij/sdk/docs/tutorials/action_system.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末袭祟,一起剝皮案震驚了整個(gè)濱河市验残,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巾乳,老刑警劉巖您没,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異胆绊,居然都是意外死亡氨鹏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門压状,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)仆抵,“玉大人,你說(shuō)我怎么就攤上這事种冬×统螅” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵娱两,是天一觀的道長(zhǎng)莺匠。 經(jīng)常有香客問我,道長(zhǎng)十兢,這世上最難降的妖魔是什么趣竣? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮旱物,結(jié)果婚禮上遥缕,老公的妹妹穿的比我還像新娘。我一直安慰自己宵呛,他們只是感情好通砍,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般封孙。 火紅的嫁衣襯著肌膚如雪迹冤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天虎忌,我揣著相機(jī)與錄音泡徙,去河邊找鬼。 笑死膜蠢,一個(gè)胖子當(dāng)著我的面吹牛堪藐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挑围,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼礁竞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了杉辙?” 一聲冷哼從身側(cè)響起模捂,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜘矢,沒想到半個(gè)月后狂男,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡品腹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年岖食,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舞吭。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泡垃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出羡鸥,到底是詐尸還是另有隱情蔑穴,我是刑警寧澤,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布兄春,位于F島的核電站澎剥,受9級(jí)特大地震影響锡溯,放射性物質(zhì)發(fā)生泄漏赶舆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一祭饭、第九天 我趴在偏房一處隱蔽的房頂上張望芜茵。 院中可真熱鬧,春花似錦倡蝙、人聲如沸九串。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)猪钮。三九已至品山,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烤低,已是汗流浹背肘交。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扑馁,地道東北人涯呻。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像腻要,于是被迫代替她去往敵國(guó)和親复罐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

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