Android開源框架PowerfulViewLibrary——PowerfulEditText的介紹和源碼解析

Android開源框架PowerfulViewLibrary——PowerfulEditText的介紹###

??很高興自己寫的前兩篇博客都得到了郭霖(人稱郭神)的認可浸锨,答應幫我發(fā)布在他的微信公眾號上膏燃,這讓我更有決心寫好博客卖氨。我寧愿一個月一更,也不愿濫竽充數(shù)弦疮,寫博客一方面是為了分享自己的技術(shù)和經(jīng)驗,另一方面是為了可以互相學習、交流和進步昂拂。最近決定開發(fā)一個開源框架,叫做PowerfulViewLibrary,也就是功能強大的View庫抛猖,主要是為了方便開發(fā)格侯,封裝一些常用的控件,下面是相關(guān)介紹和使用财著。

PowerfulEditText具有的功能###

1.自帶清除文本功能

??PowerfulEditText自帶清除文本功能联四,只需在布局文件該View屬性中添加funcType,指定為canClear,就可以自帶清除文本功能,使用如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
>

    <com.chaychan.viewlib.PowerfulEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:funcType="canClear"
        />

</LinearLayout>

運行后撑教,效果如下:

??上圖所示的刪除圖標是默認的朝墩,當然也可以指定右側(cè)刪除按鈕的圖標,只需添加多drawableRight屬性驮履,這里建議使用一個selector鱼辙,分別為普通狀態(tài)和按壓狀態(tài)設置一張圖片,這樣當按壓圖標的時候玫镐,會有一種按壓的狀態(tài)倒戏,selector的編寫如下:

<?xml version="1.0" encoding="utf-8"?>
<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="按壓后的圖標" />
    <item android:drawable="普通狀態(tài)的圖標" />
</selector>

源碼分析:

public class PowerfulEditText extends EditText {

    /**普通類型*/
    private static final int TYPE_NORMAL = -1;
    /**自帶清除功能的類型*/
    private static final int TYPE_CAN_CLEAR = 0;
    /**自帶密碼查看功能的類型*/
    private static final int TYPE_CAN_WATCH_PWD = 1;

     public PowerfulEditText(Context context) {
        this(context, null);
     }

     public PowerfulEditText(Context context, AttributeSet attrs) {
        //這里構(gòu)造方法也很重要,不加這個很多屬性不能在XML里面定義  
        this(context, attrs, android.R.attr.editTextStyle);
     }

     public PowerfulEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        ta = context.obtainStyledAttributes(attrs, R.styleable.PowerfulEditText);

        funcType = ta.getInt(R.styleable.PowerfulEditText_funcType, TYPE_NORMAL);

        ...

        init();
     }

}

??PowerfulEditText繼承于EditText,這里定義了三種類型恐似,分別是普通類型杜跷、自帶清除功能類型以及自帶查看密碼的功能,其中第二個構(gòu)造方法,也就是只有兩個參數(shù)的構(gòu)造方法葛闷,里面調(diào)用該類的第三個構(gòu)造方法(帶三個參數(shù)的構(gòu)造方法)憋槐,需要傳多一個int類型的參數(shù),這里不能像以前定義其他View的時候那樣直接傳一個0淑趾,而是要傳android.R.attr.editTextStyle阳仔,否則很多屬性不能在XML里面定義。自己的邏輯操作init()方法扣泊,在第三個構(gòu)造方法調(diào)用即可近范。

private void init() {
        //獲取EditText的DrawableRight,假如沒有設置我們就使用默認的圖片,左上右下
        mRightDrawable = getCompoundDrawables()[2];
        
        if (mRightDrawable == null) {
            //如果右側(cè)沒有圖標
            if (funcType == TYPE_CAN_CLEAR) {
                //有清除功能,設置默認叉號選擇器
                mRightDrawable = getResources().getDrawable(R.drawable.delete_selector);
            } 
        }

        //如果是清除功能延蟹,則一開始隱藏右側(cè)默認圖標评矩,否則不隱藏右側(cè)默認圖標
        setRightIconVisible(funcType == 0 ? false : true);
         //設置輸入框里面內(nèi)容發(fā)生改變的監(jiān)聽
        addTextChangedListener(new TextWatcher() {
            /**
             * 當輸入框里面內(nèi)容發(fā)生變化的時候回調(diào)的方法
             */
            @Override
            public void onTextChanged(CharSequence s, int start, int count,
                                      int after) {
        //如果是帶有清除功能的類型,當文本內(nèi)容發(fā)生變化的時候阱飘,根據(jù)內(nèi)容的長度是否為0進行隱藏或顯示
                if (funcType == 0) {
                    setRightIconVisible(s.length() > 0);
                }

                if (textListener != null) {
                    textListener.onTextChanged(s, start, count, after);
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {
                if (textListener != null) {
                    textListener.beforeTextChanged(s, start, count, after);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (textListener != null) {
                    textListener.afterTextChanged(s);
                }
            }

        });
    }


    /**
     * 設置右側(cè)圖標的顯示與隱藏斥杜,調(diào)用setCompoundDrawables為EditText繪制上去
     *
     * @param visible
     */
    protected void setRightIconVisible(boolean visible) {
        Drawable right = visible ? mRightDrawable : null;
        setCompoundDrawables(getCompoundDrawables()[0],
                getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
    }

 
   /**
     * 輸入框文本變化的回調(diào),如果需要進行多一些操作判斷沥匈,則設置此listen替代*TextWatcher
     */
    public interface TextListener {

        void onTextChanged(CharSequence s, int start, int count, int after);

        void beforeTextChanged(CharSequence s, int start, int count, int after);

        void afterTextChanged(Editable s);
    }

??在init()方法中蔗喂,我們首先獲取到輸入框右側(cè)的Drawable對象,通過getCompoundDrawables()[2]獲取咐熙,getCompoundDrawables()方法是用于獲取輸入框四個方向圖標的方法弱恒,返回的類型是一個Drawable數(shù)組,數(shù)組的元素排序分別是左(0)上(1)右(2)下(3)四個Drawable,這里我們需要獲取右側(cè)的圖標對象棋恼,對應的下標為2返弹。先判斷右側(cè)圖標mRightDrawable是否為空,如果為空爪飘,并且當前的功能類型為自帶清除功能,則使用默認的清除圖標义起,通過調(diào)用getResources().getDrawable()加載對應的selector。

??通過判斷功能類型是否屬于帶有清除功能的類型师崎,設置右側(cè)圖標初始化的時候是否顯示默终,接著設置文本內(nèi)容變化的監(jiān)聽,通過監(jiān)聽文本內(nèi)容的變化犁罩,判斷右側(cè)圖標是否要顯示齐蔽。由于此處已經(jīng)設置TextWatcher進行文本的監(jiān)聽,并且在onTextChanged()方法中進行了操作床估,所以在使用PowfulEditText的時候含滴,如果需要在文本內(nèi)容監(jiān)聽中做相應操作,則需要使用自己定義的TextListener來進行回調(diào)丐巫,而不是使用TextWatcher谈况。

??關(guān)于輸入框右側(cè)圖標點擊事件的處理勺美,所采用的方法是重寫onTouchEvent()方法,對觸摸響應進行處理碑韵,判斷觸摸的位置是否落在右側(cè)圖標的范圍內(nèi)赡茸,如果是,則認為是點擊了該圖標祝闻。

    /**
     * 因為我們不能直接給EditText設置點擊事件占卧,所以我們用記住我們按下的位置來模擬點擊事件
     * 當我們按下的位置 在  EditText的寬度 - 圖標到控件右邊的間距 - 圖標的寬度  和
     * EditText的寬度 - 圖標到控件右邊的間距之間我們就算點擊了圖標,豎直方向就沒有考慮
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (getCompoundDrawables()[2] != null) {

                boolean isTouched = event.getX() > (getWidth() - getTotalPaddingRight())
                        && (event.getX() < ((getWidth() - getPaddingRight())));

                if (isTouched) {

                    if (onRightClickListener == null) {
                        if (funcType == TYPE_CAN_CLEAR) {
                            //如果沒有設置右邊圖標的點擊事件联喘,并且?guī)в星宄δ芴胨ǎJ清除文本
                            this.setText("");
                        } else if (funcType == TYPE_CAN_WATCH_PWD) {
                            //如果沒有設置右邊圖標的點擊事件,并且?guī)в胁榭疵艽a功能耸袜,點擊切換密碼查看方式
                            ...
                        }
                    } else {
                        //如果有則回調(diào)
                        ...
                    }
                }
            }
        }

        return super.onTouchEvent(event);
    }

??當按下的x值在EditText的寬度 - (圖標到控件右邊的間距 + 圖標的寬度)(getTotalPaddingRight()) 和 EditText的寬度 - 圖標到控件右邊的間距之間,則認為是點擊了圖標(如果為了精確計算牲平,可以考慮y值方向的判斷)然后進行相應的操作堤框,如果沒有設置右側(cè)圖標的點擊事件,并且當前屬于帶有清除功能類型纵柿,則默認清除文本蜈抓。

2.自帶密碼輸入框切換明文密文格式的功能

??PowerfulEditText自帶密碼輸入框切換明文密文格式的功能,目前大多數(shù)App密碼輸入欄一般支持密碼明文昂儒、密文的顯示沟使,如果需要用到該功能,可以將funcType中指定為canWatchPwd,就可以輕松使用這種功能渊跋,使用如下:

<com.chaychan.viewlib.PowerfulEditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:funcType="canWatchPwd"
    android:inputType="textPassword"
    />

運行后腊嗡,效果如下:

源碼解析:

??同樣也是在onTouchEvent()方法中做處理,如果當前的功能類型屬于查看密碼功能類型拾酝,則根據(jù)eyeOpen這個標識進行判斷燕少,判斷當前是否是明文,如果是蒿囤,點擊后則變成密文客们,否則變成明文。

 /**
     * 因為我們不能直接給EditText設置點擊事件材诽,所以我們用記住我們按下的位置來模擬點擊事件
     * 當我們按下的位置 在  EditText的寬度 - 圖標到控件右邊的間距 - 圖標的寬度  和
     * EditText的寬度 - 圖標到控件右邊的間距之間我們就算點擊了圖標底挫,豎直方向就沒有考慮
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (getCompoundDrawables()[2] != null) {

                boolean isTouched = event.getX() > (getWidth() - getTotalPaddingRight())
                        && (event.getX() < ((getWidth() - getPaddingRight())));

                if (isTouched) {

                    if (onRightClickListener == null) {
                        if (funcType == TYPE_CAN_CLEAR) {
                            //如果沒有設置右邊圖標的點擊事件,并且?guī)в星宄δ芰辰模J清除文本
                            ...
                        } else if (funcType == TYPE_CAN_WATCH_PWD) {
                            //如果沒有設置右邊圖標的點擊事件建邓,并且?guī)в胁榭疵艽a功能,點擊切換密碼查看方式
                            if (eyeOpen) {
                                //變?yōu)槊芪?
                                this.setTransformationMethod(PasswordTransformationMethod.getInstance());
                                eyeOpen = false;
                            } else {
                                //變?yōu)槊魑?                                this.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
                                eyeOpen = true;
                            }
                            switchWatchPwdIcon();//切換圖標
                        }
                    } else {
                        //如果有則回調(diào)
                        ...
                    }
                }
            }
        }

        return super.onTouchEvent(event);
    }


    /**
     * 切換查看密碼的圖標
     */
    private void switchWatchPwdIcon() {
        if (eyeOpen) {
            //開啟查看
            setCompoundDrawables(getCompoundDrawables()[0],
                    getCompoundDrawables()[1], mEyeOpenDrawable, getCompoundDrawables()[3]);
        } else {
            //關(guān)閉查看
            setCompoundDrawables(getCompoundDrawables()[0],
                    getCompoundDrawables()[1], mRightDrawable, getCompoundDrawables()[3]);
        }
    }

關(guān)于輸入框明文和密文切換的設置有兩種方法湿痢。

方法一:

setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);//密文密碼
setInputType(EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD); //明文密碼

方法二:

setTransformationMethod(PasswordTransformationMethod.getInstance());//密文密碼
setTransformationMethod(HideReturnsTransformationMethod.getInstance());//明文密碼

??上述兩種方法都可以實現(xiàn)明文密文的切換涝缝,但是方法一切換后EditText的光標會回到最左側(cè)扑庞,所以這里選擇使用方法二,個人覺得體驗比較好一些拒逮。

??上圖所示的右側(cè)圖標是默認的罐氨,同樣也可以指定開啟查看密碼的圖標和關(guān)閉查看密碼的圖標,只需要在屬性eyeOpen中指定開啟查看密碼引用的圖片滩援,在eyeClosed中指定關(guān)閉查看密碼引用的圖片即可栅隐,如下,更換開啟查看密碼的圖標,如項目默認的圖標ic_launcher

<com.chaychan.viewlib.PowerfulEditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:funcType="canWatchPwd"
    android:inputType="textPassword"
    app:eyeOpen="@mipmap/ic_launcher"
    />

運行后玩徊,效果如下:

這樣開啟查看密碼的圖標就更換了租悄,如果還需要更換關(guān)閉密碼查看的圖標,可以指定eyeClose恩袱,引用對應的圖標泣棋。

3.設置drawableLeft和drawableRight圖片大小的功能

??原生的EditText并不能在屬性中指定drawableLeft或drawableRight圖片的大小,所以一般開發(fā)的過程中畔塔,一些程序員會采用簡單粗暴的方法潭辈,直接引用一張寬高都很小的圖片。但是在不同屏幕分辨率下澈吨,兼容性就不是很好把敢,比如在一些屏幕分辨率較高的手機上運行,圖標會顯得模糊谅辣。PowerfulEditText可以指定drawableLeft和drawableRight圖片的寬高大小修赞,可以指定為多少個dp,這樣在開發(fā)的時候,可以在各個分辨率圖片文件夾中放入不同尺寸的圖標桑阶,通過設定圖片的寬高屬性來限制顯示的大小柏副,下面演示一下:

<com.chaychan.viewlib.PowerfulEditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:funcType="canWatchPwd"
    android:inputType="textPassword"
    android:drawableLeft="@mipmap/ic_launcher"
    />

??如圖,指定了drawableLeft的圖片為ic_laucher,圖片看起來比較大蚣录,這時如果我們想要將其調(diào)小搓扯,則可以添加leftDrawableWidth、leftDrawableHeight指定左側(cè)圖片的寬高包归。

<com.chaychan.viewlib.PowerfulEditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:funcType="canWatchPwd"
    android:inputType="textPassword"
    android:drawableLeft="@mipmap/ic_launcher"
    app:leftDrawableWidth="30dp"
    app:leftDrawableHeight="30dp"
    />

上面代碼锨推,指定了leftDrawableWidth和leftDrawableHeight的大小都為30dp,運行的效果如下:

可以看到左側(cè)的圖標變小了公壤,同樣也可以設置右側(cè)圖片的寬高换可,對應的屬性是rightDrawableWidth、rightDrawableHeight厦幅。

??源碼解析:

 public PowerfulEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    ta = context.obtainStyledAttributes(attrs, R.styleable.PowerfulEditText);
   
    ...

    init();
}

 if (leftDrawable != null) {
        leftWidth = ta.getDimensionPixelOffset(R.styleable.PowerfulEditText_leftDrawableWidth,leftDrawable.getIntrinsicWidth());
        leftHeight = ta.getDimensionPixelOffset(R.styleable.PowerfulEditText_leftDrawableHeight,leftDrawable.getIntrinsicHeight());
        leftDrawable.setBounds(0, 0, leftWidth, leftHeight);
    }

    if (mRightDrawable != null) {
        rightWidth = ta.getDimensionPixelOffset(R.styleable.PowerfulEditText_rightDrawableWidth,mRightDrawable.getIntrinsicWidth());
        rightHeight = ta.getDimensionPixelOffset(R.styleable.PowerfulEditText_rightDrawableWidth,mRightDrawable.getIntrinsicHeight());
        mRightDrawable.setBounds(0, 0, rightWidth, rightHeight);
        if (mEyeOpenDrawable != null) {
            mEyeOpenDrawable.setBounds(0, 0, rightWidth, rightHeight);
        }
       ...
    }

??這里通過TypedArray獲取XML中配置的對應leftDrawableWidth沾鳄、leftDrawableHeight、rightDrawableWidth确憨、rightDrawableHeight的尺寸大小译荞,如果沒有設置這些屬性瓤的,則默認使用圖標的寬和高,然后通過Drawable.setBounds()方法吞歼,設置右側(cè)圖標的寬高圈膏,達到改變兩側(cè)圖標大小的目的。

設置右側(cè)圖標點擊事件####

PowerfulEditText同樣支持右側(cè)圖片的點擊事件篙骡,如果funcType指定為canClear稽坤,則默認點擊是清除文本。如果需要進行一些額外的操作糯俗,則可以設置回調(diào)尿褪,比如搜索輸入框得湘,右側(cè)是一個搜索的按鈕杖玲,需要為其設置點擊事件的回調(diào)。

布局文件:

 <com.chaychan.viewlib.PowerfulEditText
    android:id="@+id/pet"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:drawableRight="@mipmap/search"
    />

Activity

  PowerfulEditText petUsername = (PowerfulEditText) findViewById(R.id.pet);
    petUsername.setOnRightClickListener(new PowerfulEditText.OnRightClickListener() {
        @Override
        public void onClick(EditText editText) {
            String content = editText.getText().toString().trim();
            if (淘正!TextUtils.isEmpty(content)){
                Toast.makeText(MainActivity.this, "執(zhí)行搜索邏輯", Toast.LENGTH_SHORT).show();
            }
        }
    });

運行效果如下:

??上面布局文件中天揖,和普通的EditText屬性一樣,funcType一共有三個屬性跪帝,分別是normal(默認)、canClear(帶清除功能)些阅、canWatchPwd(帶查看密碼功能)伞剑。如果不指定funcType,則默認是normal,普通方式市埋。

??Activity中黎泣,為PowerfulEditText設置右側(cè)圖片的點擊事件,調(diào)用setOnRightClickListener設置點擊后的回調(diào)缤谎,這里點擊后如果有文本內(nèi)容抒倚,則執(zhí)行搜索邏輯。

??這里僅對EditText的一些功能進行封裝坷澡,對于樣式的更改托呕,就要靠開發(fā)者根據(jù)自己的需求進行修改,修改的方式也不難频敛,只要將background指定為自己編寫的的xml即可项郊。

??關(guān)于右側(cè)圖標點擊事件的回調(diào),和上面所講到的是一致的斟赚,是在onTouchEvent()方法中着降,判斷觸摸范圍是否落在右側(cè)圖標上,然后判斷OnRightClickListener是否為null拗军,如果不為null任洞,則進行回調(diào)蓄喇。OnRightClickListener接口很簡單,回調(diào)的時候傳遞當前的EditText對象,如果需要對右側(cè)圖標點擊事件進行自己的邏輯處理交掏,則通過調(diào)用setOnRightClickListener()進行回調(diào)妆偏。

    /**
     * 右邊圖標點擊的回調(diào)
     */
    public interface OnRightClickListener {
        void onClick(EditText editText);
    }

??關(guān)于PowerfulEditText的相關(guān)屬性,可以通過查看attr.xml便一目了然耀销,如下:

 <declare-styleable name="PowerfulEditText">
    <!--功能的類型-->
    <attr name="funcType">
        <enum name="normal" value="-1"/>
        <enum name="canClear" value="0"/>
        <enum name="canWatchPwd" value="1" />
    </attr>
    <!--關(guān)閉查看密碼的圖標-->
    <attr name="eyeClose" format="reference"/>
    <!--開啟查看密碼的圖標-->
    <attr name="eyeOpen" format="reference"/>
    <!--左側(cè)Drawable的寬度-->
    <attr name="leftDrawableWidth" format="dimension"/>
    <!--左側(cè)Drawable的高度-->
    <attr name="leftDrawableHeight" format="dimension"/>
    <!--右側(cè)Drawable的寬度-->
    <attr name="rightDrawableWidth" format="dimension"/>
    <!--右側(cè)Drawable的高度-->
    <attr name="rightDrawableHeight" format="dimension"/>
</declare-styleable>

導入方式####

在項目根目錄下的build.gradle中的allprojects{}中楼眷,添加jitpack倉庫地址,如下:

allprojects {
    repositories {
        jcenter()
        maven { url 'https://jitpack.io' }//添加jitpack倉庫地址
    }
}

打開app的module中的build.gradle熊尉,在dependencies{}中罐柳,添加依賴,如下:

dependencies {
        ......
        compile 'com.github.chaychan:PowerfulViewLibrary:1.0'
}

??這樣就可以使用PowerfulViewLibrary下的控件了,目前只對EditText的一些功能進行了封裝狰住,往后會把一些常用的View進行封裝张吉,方便項目的開發(fā),我會保持對PowerfulViewLibrary的更新和維護的催植,也希望大家可以向我提出一些建議肮蛹。

源碼github地址:https://github.com/chaychan/PowerfulViewLibrary.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市创南,隨后出現(xiàn)的幾起案子伦忠,更是在濱河造成了極大的恐慌,老刑警劉巖稿辙,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昆码,死亡現(xiàn)場離奇詭異,居然都是意外死亡邻储,警方通過查閱死者的電腦和手機赋咽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吨娜,“玉大人脓匿,你說我怎么就攤上這事』略” “怎么了陪毡?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長勾扭。 經(jīng)常有香客問我缤骨,道長,這世上最難降的妖魔是什么尺借? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任绊起,我火速辦了婚禮,結(jié)果婚禮上燎斩,老公的妹妹穿的比我還像新娘虱歪。我一直安慰自己蜂绎,他們只是感情好,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布笋鄙。 她就那樣靜靜地躺著师枣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪萧落。 梳的紋絲不亂的頭發(fā)上践美,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機與錄音找岖,去河邊找鬼陨倡。 笑死,一個胖子當著我的面吹牛许布,可吹牛的內(nèi)容都是我干的兴革。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼蜜唾,長吁一口氣:“原來是場噩夢啊……” “哼杂曲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起袁余,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤擎勘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后颖榜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棚饵,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年朱转,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片积暖。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡藤为,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出夺刑,到底是詐尸還是另有隱情缅疟,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布遍愿,位于F島的核電站存淫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏沼填。R本人自食惡果不足惜桅咆,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坞笙。 院中可真熱鬧岩饼,春花似錦荚虚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至寞冯,卻和暖如春渴析,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吮龄。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工俭茧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人螟蝙。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓恢恼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胰默。 傳聞我的和親對象是個殘疾皇子场斑,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

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