Notepad

圖標.jpg

簡述:


記事本的第一個版本,需要完善的還有很多,完成了基本的增刪改查的功能,以及在正文中插入圖片,對內(nèi)容進行分類,根據(jù)內(nèi)容查找等基本功能,對于刪除添加了回收站機制,可在回收站中對已刪除的內(nèi)容進行恢復或者永久刪除
暫時只支持Android5.0以上的設備運行,后續(xù)版本將會對4.4版本進行兼容,對4.4以下的設備未做兼容打算

關于.jpg
主界面
主界面.jpg
編輯界面
編輯界面.jpg

功能點:

基礎功能

  • 對記事的增刪改
  • 添加時間戳
  • 查詢內(nèi)容

拓展功能

  • 對記事進行分類
  • 在記事中添加圖片
  • 一些界面美化以及人性化細節(jié)設置

基礎功能

對記事的增刪改

使用了數(shù)據(jù)庫輔助類SQLiteOpenHelper來創(chuàng)建數(shù)據(jù)庫

數(shù)據(jù)的插入

使用dbHelper封裝insert方法

插入數(shù)據(jù)

ContentValues values  = new ContentValues();
values.put(COLUMN_NAME_NOTE_TITLE ,title);
values.put(COLUMN_NAME_NOTE_CONTENT ,content);
values.put(COLUMN_NAME_NOTE_DATE ,dateNum);
dbread.insert(TABLE_NAME_NOTES ,null,values);

原先使用的是execSQL()方法來插入數(shù)據(jù),但是有一個問題就是輸入 ' 這個符號使,執(zhí)行語句就會出錯,

原先的插入方法

sql = "insert into " +NotesDB.TABLE_NAME_NOTES +"(" 
            +COLUMN_NAME_ID + " ,"
            +COLUMN_NAME_NOTE_TITLE +","
            +COLUMN_NAME_NOTE_CONTENT + " ,"
            +COLUMN_NAME_NOTE_DATE + ")"
            +" values("+count+","+"'"+ title +"'"+","+"'"+ content +"'"+","+"'"+ dateNum + "')";
Log.d("LOG",sql);
dbread.execSQL(sql);
數(shù)據(jù)的修改

使用dbHelper封裝update方法

ContentValues values  = new ContentValues();; 
values.put(COLUMN_NAME_NOTE_TITLE ,title);    
values.put(COLUMN_NAME_NOTE_CONTENT ,content);  
values.put(COLUMN_NAME_NOTE_DATE,dateNum);
String where = "_id="+id;
dbread.update(TABLE_NAME_NOTES ,values ,where, null);

同上,使用數(shù)據(jù)庫語句的execSQL()方法會因為輸入 ' 而出錯,此處不再列出

數(shù)據(jù)的刪除

本應用的刪除分兩步進行,第一步只是先把記事的屬性改為已刪除,并在回收站顯示,第二部才是進行在數(shù)據(jù)庫的刪除

第一步
更改屬性為刪除

    Cursor content = c1;
    String id = c1.getString(content.getColumnIndex("_id"));
    String setCategory = "update note set category ='" +   CATEGORY_DELETED + "' where _id=" + id;
    Log.d("DELETE",setCategory);
    dbread.execSQL(setCategory);

第二步
在數(shù)據(jù)庫中刪除

    Cursor content = (Cursor) deletedview.getItemAtPosition(n);
    String id =content.getString(content.getColumnIndex("_id"));
    String recovery = "delete from note where _id=" + id;
    dbread.execSQL(recovery);

至此,本應用的核心功能增刪改已經(jīng)完成

下面是徹底刪除一條記事的流程:

主界面長按選擇刪除

主界面長按.jpg

在彈出的提示中確認刪除,此時,主界面列表已經(jīng)不顯示這條記錄

刪除提示.jpg

而在回收站中可以看到先前被刪除的記錄,長按則可以選擇回復或者徹底刪除

回收站長按.jpg

選擇刪除則彈出提示,這條記錄"徹底刪除"已在數(shù)據(jù)庫中刪除

永久刪除.jpg

邏輯的判斷
進入編輯界面有兩個途徑,第一是點擊新建按鈕,第二是從記事列表進入,所以我們加入了一個屬性,若是新建按鈕則為0(調用插入函數(shù)),若是從記事列表則為1(調用修改函數(shù)).

if(ENTER_STATE == 0){
                noteInsert();
        else{
                noteUpdate();
            }
        }

添加時間戳

首先要在顯示的listview中加入一個TextView組件來顯示這個時間,
使用SimpleDateFormat 可以把當前時間格式化成指定格式

Date date = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");

String dateNum = sdf.format(date);

然后在數(shù)據(jù)庫相對應的列中加入這個字符串即可


查詢內(nèi)容

查詢的方法在工具欄點擊查詢按鈕即可調出searchview,然后輸入所需查詢的文字然后點擊鍵盤的搜索即可查詢內(nèi)容包含關鍵詞的記錄


查詢1.jpg

查詢"在"的結果


查詢結果.jpg

實現(xiàn)

具體搜索的實現(xiàn)代碼不難,執(zhí)行一下代碼就可以將查詢到的內(nèi)容放到Cursor里,然后用適配器進行適配就可以在列表中顯示了

String  sql = "select * from note where category !='"+CATEGORY_DELETED+"' and content like ?";

Cursor cursor = dbread.rawQuery(sql, new String[]{"%"+word+"%"});

但是為了實現(xiàn)搜索欄,我們需要用到一個新的組件 SearchView

首先要在AndroidManifest的顯示搜索欄的活動中加入

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
        <meta-data
            android:name="android.app.default_searchable"
            android:value="edu.fjnu.birdie.notemd.MainActivity"/>   

并在顯示搜索結果的活動中加入

     <intent-filter>           
     <action android:name="android.intent.action.SEARCH" />
     <category android:name="android.intent.category.DEFAULT" />
     </intent-filter>

在 onCreateOptionsMenu(Menu menu)函數(shù)中加入

     SearchManager searchManager =
               (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView =
                (SearchView) menu.findItem(R.id.action_search).getActionView();
        searchView.setSearchableInfo(
                searchManager.getSearchableInfo(getComponentName()));
        String SearchContent = getIntent().getStringExtra(SearchManager.QUERY);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                Intent intent = new Intent(MainActivity.this,SearchActivity.class);
                intent.putExtra("word",query);
                startActivity(intent);
                return true;
            }
            @Override
            public boolean onQueryTextChange(String newText) {
                return true;
            }
        });
        

即可讓搜索欄中輸入的文字傳到顯示搜索結果的活動中,并在顯示結果的搜索欄中進行dbread.rawQuery()并裝配到listview就可以得到搜索結果


拓展功能

對記事進行分類

此處的分類有"默認", "重要", "備忘", "筆記", "日程" ,用戶不可自定義
此處一是作為分類,二也是為后續(xù)添加的功能留下接口(備忘接口添加鬧鐘提醒等,但這個版本只單純的作為分類功能)
同時還有一個隱藏分類 刪除
刪除也是通過分類到刪除分類并在select的時候去掉這個分類的記錄

修改分類可以從主界面長按或者編輯界面的右上角分類按鈕進行

分類菜單.jpg

實現(xiàn)

public void addCategory(){
        //Toast.makeText(this,"add_catagory",Toast.LENGTH_SHORT).show();
        //{ "默認", "重要", "備忘", "筆記", "日程" };
        if(ENTER_STATE == 1) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("設置分組");
            builder.setSingleChoiceItems(category, 0, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    int choose = which;
                    switch (which) {
                        case 0: {
                            setCategory = "update note set category ='" + CATEGORY_NORMAL + "' where _id=" + id;
                            Log.d("EXE", setCategory);
                            break;
                        }
....
builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dbread.execSQL(setCategory);
                }
            });
            builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                }
            });
            builder.create();
            builder.show();

使用一個AlertDialog彈出單選框,并根據(jù)選項的不同來加載不同的sql語句,并在確定后執(zhí)行sql語句.


在記事中添加圖片

在編輯界面 點擊右下角的按鈕,就會打開相冊,選擇相冊中的圖片即可將圖片加入到文本中

插入圖片1.jpg

實現(xiàn):

1.首先使用intent.getData得到uri
2.然后調用BitmapFactory的解碼函數(shù)decodeStream且要求的參數(shù)為流(Stream),所以要用ContentResolver解析uri為流。
3.接著通過一個resizeImage函數(shù)重新調整bitmap大小
4.然后就是要把所得到的圖片放到EditText里了

首先要在AndroidManifest中加入權限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

首先
對點擊按鈕的事件創(chuàng)建監(jiān)聽

Intent getImage  = new Intent("android.intent.action.GET_CONTENT");               getImage.addCategory(Intent.CATEGORY_OPENABLE);
getImage.setType("image/*");
startActivityForResult(getImage, 1);

ACTION_GET_CONTENT是標準的Activity Action的一種漾橙,那什么是Activity Action呢稚配,簡單來說就是讓用戶選擇一種特殊的數(shù)據(jù)并得到它。

ACTION_GET_CONTENT可以讓用戶在運行的程序中取得數(shù)據(jù)柏副,例如取照片勾邦,當然這里的運行的程序指的是手機上的文件管理器之類的。

addCategory是要增加一個分類割择,增加一個什么分類呢眷篇?就是增加CATEGORY_OPENABLE,從字面意思值是增加一個可以打開的分類荔泳,也即是取得的uri要可以被ContentResolver解析蕉饼,注意這里的分類即是執(zhí)行的附加條件虐杯。

setType就是設置取得的數(shù)據(jù)類型為image,也即是取照片昧港。

protected void onActivityResult(int requestCode, int resultCode,
                                    Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        ContentResolver resolver = getContentResolver();
        if (resultCode == RESULT_OK) {
            if (requestCode == 1) {
                Uri originalUri = intent.getData();
                String Imgpath = getPath(this,originalUri);
                Uri realUri = Uri.parse("file://"+Imgpath);//真實路徑轉化為Uri
                String realPath = "content://media/"+Imgpath;
                try {
                    Bitmap originalBitmap = BitmapFactory.decodeFile(Imgpath);
                    Log.d("imageUri",originalUri.toString() );
                    if(originalBitmap != null) {
                        bitmap = resizeImage(originalBitmap);
                    }else{
                        Log.d("ob","null");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (bitmap != null) {
                    insertIntoEditText(getBitmapMime(bitmap, realUri));
                } else {
                    Toast.makeText(noteEdit.this, "獲取圖片失敗",
                            Toast.LENGTH_SHORT).show();
                }
            }
        }
        if (bitmap != null) {
        }
    }

將得到的圖片轉化成真實地址

下面是轉化成圖片的真實地址 參考文章:Android4.4中獲取資源路徑問題

public static String getPath(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[] {
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

在TextView中顯示圖片

這里用到了Spannable和ImageSpan來在EditText中顯示圖片

這邊使用了< img >標簽標注圖片的路徑

//設置Spannable String
    private SpannableString getBitmapMime(Bitmap pic, Uri uri) {
        String path = "<img>"+uri.getPath()+"<img>";
        SpannableString ss = new SpannableString(path);
        ImageSpan span = new ImageSpan(this, pic);
        ss.setSpan(span, 0, path.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return ss;
    }
//將SS插入EditText
    private void insertIntoEditText(SpannableString ss) {
        insertEnter();//圖片添加到新的一行
        Editable et = et_content.getText();// 先獲取Edittext中的內(nèi)容
        int start = et_content.getSelectionStart();
        et.insert(start, ss);// 設置ss要添加的位置
        et_content.setText(et);// 把et添加到Edittext中
        et_content.setSelection(start + ss.length());// 設置Edittext中光標在最后
        Log.d("Text",et_content.getText().toString());
        insertEnter();//添加完圖片后換行
    }

插入圖片時在圖片上下各插入一個空行優(yōu)化排版

//排版問題,插入EditText時在圖片的上下一行加入空格;
    private  void insertEnter(){
        Editable et = et_content.getText();
        int start = et_content.getSelectionStart();
        String enter = "\n";
        et.insert(start,enter);
        et_content.setText(et);
        et_content.setSelection(start + enter.length());
    }

在文本中設置圖片的顯示大小

//壓縮圖片
    public Bitmap resizeImage(Bitmap bitmap)
    {
        if(bitmap != null) {

            Bitmap BitmapOrg = bitmap;
            int width = BitmapOrg.getWidth();
            int height = BitmapOrg.getHeight();
            int newWidth = 480;
            int newHeight = 800;
            float scale =  ((float) newWidth) / width;
            float scaleWidth = ((float) newWidth) / width;
            float scaleHeight = ((float) newHeight) / height;
            Matrix matrix = new Matrix();
            matrix.postScale(scale, scale);//比例不變
            Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
                    height, matrix, true);
            return resizedBitmap;

        }else{
            return null;
        }
    }

? 在EditText中加載圖片

? 使用了正則表達式來識別< img >標簽,并使用 ImageSpan來顯示圖片

/將內(nèi)容中的圖片加載出來
        SpannableString ss = new SpannableString(last_content);
        Pattern p= Pattern.compile("<img>.*<img>");
        Matcher m=p.matcher(last_content);
        while(m.find()){
            String image=m.group();
            String path=image.substring(5,image.length()-5);
            Bitmap bm = BitmapFactory.decodeFile(path);
                Log.d("path",path);
            if(bm==null)
            {
                Log.d("bm","null");
            }
            Bitmap rbm = resizeImage(bm);
            ImageSpan span = new ImageSpan(this, rbm);
            ss.setSpan(span, m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }

一些界面美化以及人性化細節(jié)設置

本應用參照了Material Design,雖然并未完全規(guī)范,不過在界面上還是達到了相對應的簡潔,在操作邏輯上也符合用戶的使用

界面美化

界面的演變

4.12 --雛形
內(nèi)容:

  • 通過ListView,Button,EditText等控件做出初始的界面
  • 并通過內(nèi)嵌數(shù)據(jù)庫SQLite 完成對內(nèi)容的增刪改
1g.jpg

4.13 --重新設計界面
內(nèi)容:

  • 對界面進行重新設計
2g.jpg

為了使輸入界面更加簡潔,可以通過 在<EditText>中,加入

android:background="@null"

去掉輸入框下的橫線

4.13 --Material Design
內(nèi)容:

  • 基于對界面的重新設計,加入了Material Design
    雖然并不是很規(guī)范,但會在后續(xù)慢慢完善
  • 完成了搜索的基本邏輯,記事本的增刪改查功能基本完善
  • 同時對設置菜單,關于界面進行了初步的設計,但大部分功能都未實現(xiàn)
3g_1.jpg

3g_2.jpg

后續(xù)的版本都是在第三次界面修改后基本沒有太大的變化,主要實在功能上的變化

當前版本

mg-1.jpg
人性化細節(jié)設置
  • 虛擬鍵盤設置
  • 自動補充標題
  • 提醒設置
  • 空界面提示

虛擬鍵盤設置
新建記事會自動彈出虛擬鍵盤,而二次編輯不彈出虛擬鍵盤,需要點擊才會彈出鍵盤,因為作為記事類軟件后續(xù)修改的頻率遠低于查看的頻率,自動彈出鍵盤反而會降低用戶體驗
此外,光標自動聚焦在內(nèi)容編輯處,標題在記事類軟件中的存在性并不重要,若要編輯標題則需要點擊標題欄
實現(xiàn)

        et_title.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                et_title.setFocusableInTouchMode(true);
                return false;
            }
        });
        //新建文本時調用軟鍵盤,如果是打開原來存在的文本默認不打開軟鍵盤
        //在Manifest中添加android:windowSoftInputMode="stateHidden"使得虛擬鍵盤不會自動彈出
        if(ENTER_STATE == 0){
            Log.d("KeyBoard","VISIBLE");
            Log.d("ENTER_STATE",ENTER_STATE+"");            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
        } 
        

自動補充標題
若用戶覺得標題不重要大可不填,將會自動生成標題

                    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd-HH-mm");
                    String dateNum1 = sdf.format(date);
                    //title = "新建記事"+ dateNum1;//自動添加為時間
                     title = "新建記事";//添加為新建記事
                }

提醒設置
在刪除,編輯了內(nèi)容未保存的情況下,空內(nèi)容保存記錄,都會彈出提示框來提示用戶確保不會產(chǎn)生誤操作
(在回收站中的刪除沒有提示,邏輯上如果你已經(jīng)進到回收站并確認要刪除那條被刪除過的記錄,應該不會是誤操作)

未保存提示


未保存提示.jpg

刪除提示


刪除提示.jpg

空界面提示
在沒有記錄的首頁,搜索不到結果的搜索頁面,沒有回收記錄的回收站,不會因為沒有記錄而空在那里,而是會有一定的文字提醒

沒有記錄會提示點擊右下角添加


nullmain.jpg

無搜索結果


nullsearch.jpg

無回收文件


nulldelete.jpg

實現(xiàn)
在Layout中同時放兩個Item都是matchparents
然后通過判斷select結果來判斷是要顯示Listview還是顯示提示性文字
以MainActivity為例

    public boolean isNoteNull(){
        String sql = "select * from note where category !='"+CATEGORY_DELETED+"'";
        Log.d("sql",sql);
        Cursor c = dbManager.executeSql(sql, null);
        int number = c.getCount();
        Log.d("Note number",number+"");
        if(number == 0){
            ListView listView = (ListView)findViewById(R.id.notelist);
            TextView textView = (TextView)findViewById(R.id.main_text);
            listView.setVisibility(View.GONE);
            textView.setVisibility(View.VISIBLE);
            return true;
        }else{
            ListView listView = (ListView)findViewById(R.id.notelist);
            TextView textView = (TextView)findViewById(R.id.main_text);
            textView.setVisibility(View.GONE);
            listView.setVisibility(View.VISIBLE);
            return false;
        }
    }
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末擎椰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子创肥,更是在濱河造成了極大的恐慌达舒,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓤的,死亡現(xiàn)場離奇詭異休弃,居然都是意外死亡,警方通過查閱死者的電腦和手機圈膏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門塔猾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人稽坤,你說我怎么就攤上這事丈甸。” “怎么了尿褪?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵睦擂,是天一觀的道長。 經(jīng)常有香客問我杖玲,道長顿仇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任摆马,我火速辦了婚禮臼闻,結果婚禮上,老公的妹妹穿的比我還像新娘囤采。我一直安慰自己述呐,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布蕉毯。 她就那樣靜靜地躺著乓搬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪代虾。 梳的紋絲不亂的頭發(fā)上进肯,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音棉磨,去河邊找鬼江掩。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的频敛。 我是一名探鬼主播项郊,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼斟赚!你這毒婦竟也來了着降?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拗军,失蹤者是張志新(化名)和其女友劉穎任洞,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體发侵,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡交掏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了刃鳄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盅弛。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖叔锐,靈堂內(nèi)的尸體忽然破棺而出挪鹏,到底是詐尸還是另有隱情,我是刑警寧澤愉烙,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布讨盒,位于F島的核電站,受9級特大地震影響步责,放射性物質發(fā)生泄漏返顺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一蔓肯、第九天 我趴在偏房一處隱蔽的房頂上張望遂鹊。 院中可真熱鬧,春花似錦省核、人聲如沸稿辙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赋咽,卻和暖如春旧噪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脓匿。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工淘钟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陪毡。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓米母,卻偏偏與公主長得像勾扭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子铁瞒,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

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