Android-RecyclerView側(cè)滑刪除和拖拽操作撑柔,最底部條目不參與操作+上拉加載更多實現(xiàn)

===滑動拖拽===

Look, ItemTouchHelper | Android Developers

ItemTouchHelper
public class ItemTouchHelper 
extends RecyclerView.ItemDecoration implements RecyclerView.OnChildAttachStateChangeListener

java.lang.Object
   ?    android.support.v7.widget.RecyclerView.ItemDecoration
       ?    android.support.v7.widget.helper.ItemTouchHelper

This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.

It works with a RecyclerView and a Callback class, which configures what type of interactions are enabled and also receives events when user performs these actions.

Depending on which functionality you support, you should override onMove(RecyclerView, ViewHolder, ViewHolder) and / or onSwiped(ViewHolder, int).

This class is designed to work with any LayoutManager but for certain situations, it can be optimized for your custom LayoutManager by extending methods in the ItemTouchHelper.Callback class or implementing ItemTouchHelper.ViewDropHandler interface in your LayoutManager.

By default, ItemTouchHelper moves the items' translateX/Y properties to reposition them. You can customize these behaviors by overriding onChildDraw(Canvas, RecyclerView, ViewHolder, float, float, int, boolean) or onChildDrawOver(Canvas, RecyclerView, ViewHolder, float, float, int, boolean).

Most of the time you only need to override onChildDraw.

解釋:就是說這是一個支持RecyclerView的滑動刪除和拖拽的實體類脂信。

它靠一個回調(diào)來實現(xiàn)唇兑,也就是ItemTouchHelper.Callback | Android Developers

基于這個支持锨并,你還需要實現(xiàn)[onMove(RecyclerView, ViewHolder, ViewHolder)](https://link.zhihu.com/?target=https%3A//developer.android.google.cn/reference/android/support/v7/widget/helper/ItemTouchHelper.Callback.html%3Fhl%3Dzh-cn%23onMove%28android.support.v7.widget.RecyclerView%2C%2520android.support.v7.widget.RecyclerView.ViewHolder%2C%2520android.support.v7.widget.RecyclerView.ViewHolder%29)and / or[onSwiped(ViewHolder, int)](https://link.zhihu.com/?target=https%3A//developer.android.google.cn/reference/android/support/v7/widget/helper/ItemTouchHelper.Callback.html%3Fhl%3Dzh-cn%23onSwiped%28android.support.v7.widget.RecyclerView.ViewHolder%2C%2520int%29) 方法。

這個類還支持特定解決方案的所有LayoutManager五垮,但是需要你繼承ItemTouchHelper.Callback或者實現(xiàn)ItemTouchHelper.ViewDropHandler 接口乍惊。

另外你通過重寫onChildDraw 方法可以實現(xiàn)移動屬性的自定義。

1. 所以創(chuàng)建一個這樣的實體對象就是像這樣:

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
                return 0;
            }

            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
                return false;
            }

            @Override
            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {

            }
        }); 

2. 調(diào)用就是如下的方法咯, attach一下RecyclerView就可以啦...

  void  attachToRecyclerView(RecyclerView recyclerView)
Attaches the ItemTouchHelper to the provided RecyclerView.

還有其他方法如下放仗,先不管嘛润绎,慢慢來

image

Look2, 所以重點來了,就是這個 ItemTouchHelper.Callback | Android Developers 如果不想自定義匙监,其實有個官方簡單版ItemTouchHelper.SimpleCallback | Android Developers<u style="text-decoration: none; border-bottom: 1px dashed grey;"> 這個可能就不能針對某個條目單獨處理了咯....</u>

不過人家已經(jīng)把移動操作弄好了凡橱。另外滑動效果也處理了,你只需要將滑動的條目從adapter中刪除即可亭姥!參數(shù)就是滑動的方向和拖拽的方法處理(比如只能向上拖動稼钩,左滑右滑啥的),如下:

     ItemTouchHelper itemTouchHelper2 = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN,
                ItemTouchHelper.LEFT) {
            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
                return true;
            }

            @Override
            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
                // remove from adapter
            }
        });

Then,如果我們希望列表類似如下:(底部的條目不能被滑動刪除达罗,也不能被移動坝撑,同時也不能被拖動的條目改變位置...)

image

1. 這個時候就需要我們自定義ItemTouchHelper.Callback | Android Developers

然后重點重寫如下三個方法,基本上就可以進行相關(guān)控制了粮揉。當然有些也可以簡單重寫巡李,比如isLongPressDragEnabled()這些,可以控制狀態(tài)扶认。

 abstract int   getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)

  abstract boolean  onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
Called when ItemTouchHelper wants to move the dragged item from its old position to the new position.

abstract void   onSwiped(RecyclerView.ViewHolder viewHolder, int direction)
Called when a ViewHolder is swiped by the user.

2. 我們?yōu)榱丝刂谱詈蟮臈l目不能操作的情況多糠,我們重點關(guān)注下getMovementFlags方法

getMovementFlags
added in version 24.1.0
int getMovementFlags (RecyclerView recyclerView, 
                RecyclerView.ViewHolder viewHolder)
Should return a composite flag which defines the enabled move directions in each state (idle, swiping, dragging).

Instead of composing this flag manually, you can use makeMovementFlags(int, int) or makeFlag(int, int).

This flag is composed of 3 sets of 8 bits, where first 8 bits are for IDLE state, next 8 bits are for SWIPE state and third 8 bits are for DRAG state. Each 8 bit sections can be constructed by simply OR'ing direction flags defined in ItemTouchHelper.

For example, if you want it to allow swiping LEFT and RIGHT but only allow starting to swipe by swiping RIGHT, you can return:

      makeFlag(ACTION_STATE_IDLE, RIGHT) | makeFlag(ACTION_STATE_SWIPE, LEFT | RIGHT);

This means, allow right movement while IDLE and allow right and left movement while swiping.

這個屬性返回值就意味著你對該條目的操作狀態(tài)赴邻,比如我們獲取當前位置是最后一個條目,進行如下處理:(mList.size()需要你外部傳入鏈表mList喲)

  @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        //int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        //int swipeFlags = ItemTouchHelper.LEFT;
        int[] flags;
        if (viewHolder.getLayoutPosition() == (mList.size() - 1)){
            flags =  new int[]{0, 0};
        }else{
            flags =  new int[]{ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT};
        }
        return makeMovementFlags(flags[0], flags[1]);
    }         

也就是說不管是滑動還是拖拽,只要是最后一個條目身堡,那么標志都為0海洼,也就是什么都不能干玉控!其他情況嫌套,正常左滑,拖拽即可誉察!

當然其實我們可以搞一個回調(diào)來返回想要的處理与涡,如果說很多頁面都是同樣的操作,倒是可以再次封裝一下,最后我們貼上我的自定義:

SimpleItemTouchHelperCallback.java

import android.graphics.Canvas;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;

/*
 *@Description: 側(cè)滑刪除輔助類
 *@Author: hl
 *@Time: 2019/1/4 15:52
 */
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
    private Sthc_Movement sthc_movement;

    public SimpleItemTouchHelperCallback(Sthc_Movement sthc_movement){
        this.sthc_movement = sthc_movement;
    }

    /**
     * 控制每個條目的可操作狀態(tài) - 滑動驼卖,拖拽等  來源->getFlag
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        //int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        //int swipeFlags = ItemTouchHelper.LEFT;
        int[] flags = sthc_movement.getFlag(viewHolder.getLayoutPosition());
        return makeMovementFlags(flags[0], flags[1]);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        sthc_movement.onMove(viewHolder, target);
        return true;
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    @Override
    public boolean isItemViewSwipeEnabled() {
        return true;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        sthc_movement.onSwiped(viewHolder, i);
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
                            float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            final float alpha = 1 - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
            viewHolder.itemView.setAlpha(alpha);
            viewHolder.itemView.setTranslationX(dX);
        }
    }

    public interface Sthc_Movement{
        public void onMove(RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target);
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction);
        public int[] getFlag(int postion);
    }
}

LookEnd,具體使用如下(注意移動條目交換的操作就行)

    ///< 側(cè)滑刪除和拖拽排序
        SimpleItemTouchHelper itemTouchHelper = new SimpleItemTouchHelper(new SimpleItemTouchHelperCallback(new SimpleItemTouchHelperCallback.Sthc_Movement() {
            @Override
            public void onMove(RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                int fromPosition = viewHolder.getAdapterPosition();
                int toPosition = target.getAdapterPosition();
                ///< 禁止拖動到新增菜單的底部
                if (toPosition >= (mList.size() - 1)){
                    return;
                }
                if (fromPosition < toPosition) {
                    for (int i = fromPosition; i < toPosition; i++) {
                        Collections.swap(mList, i, i + 1);
                    }
                } else {
                    for (int i = fromPosition; i > toPosition; i--) {
                        Collections.swap(mList, i, i - 1);
                    }
                }
                baseAdapter.notifyItemMoved(fromPosition, toPosition);
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                int position = viewHolder.getAdapterPosition();
                mList.remove(position);
                baseAdapter.notifyItemRemoved(position);
            }

            /**
             * 控制每個條目的可操作狀態(tài) - 滑動氨肌,拖拽等  對應(yīng)->getMovementFlags
             * @param position
             * @return
             */
            @Override
            public int[] getFlag(int position) {
                if (position == (mList.size() - 1)){
                    return new int[]{0, 0};
                }else{
                    return new int[]{ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT};
                }
            }
        }));
        itemTouchHelper.attachToRecyclerView(dailyItemsRv);

其中注意不允許其他條目在底部菜單下面,所以我增加了如下判斷:

image

基本上簡單需求是滿足了酌畜。對了儒飒,1. onChildDrawif (actionState == ItemTouchHelper.ACTION_STATE_SWIPE**) 的處理,是滑動過程alpha透明度的變化檩奠。滑動慢點可以看到效果附帽。埠戳。。

2. SimpleItemTouchHelper沒什么東東蕉扮,就簡單繼承了下ItemTouchHelper | Android Developers 后面或許還可以增加額外自定義處理整胃。

這個先簡單這樣認識下,畢竟小萌新都沒接觸過喳钟,有時候就是需要項目多實戰(zhàn)屁使。把常用的都搞搞,然后深入奔则,然后源碼剖析蛮寂,這樣應(yīng)該才能掌握的更好!

===上拉加載更多===

說起這個易茬,一般小萌新都是搬磚的酬蹋,只會用人家的框架 - 下拉刷新,上拉加載更多抽莱!我們來看看官方的下拉刷新SwipeRefreshLayout | Android Developers 這個簡單入門使用還好范抓,先不搞特別復雜的效果:

        // 設(shè)置顏色屬性的時候一定要注意是引用了資源文件還是直接設(shè)置16進制的顏色,因為都是int值容易搞混
        // 設(shè)置下拉進度的背景顏色食铐,默認就是白色的
        dailyHisItemsSwr.setProgressBackgroundColorSchemeResource(android.R.color.white);
        // 設(shè)置下拉進度的主題顏色
        dailyHisItemsSwr.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark);
        // 下拉時觸發(fā)SwipeRefreshLayout的下拉動畫匕垫,動畫完畢之后就會回調(diào)這個方法
        dailyHisItemsSwr.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                // 開始刷新,設(shè)置當前為刷新狀態(tài)
                //swipeRefreshLayout.setRefreshing(true);
                //                if (startload){
                //                    return;
                //                }

                // 模擬下: 
                //  這里是主線程
                // 一些比較耗時的操作虐呻,比如聯(lián)網(wǎng)獲取數(shù)據(jù)象泵,需要放到子線程去執(zhí)行
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //  加載數(shù)據(jù)
                        //  刷新數(shù)據(jù) baseAdapter.notifyDataSetChanged();
                        //  加載完數(shù)據(jù)設(shè)置為不刷新狀態(tài),將下拉進度收起來
                        dailyHisItemsSwr.setRefreshing(false);
                    }
                }, 500);

                // 這個不能寫在外邊铃慷,不然會直接收起來
                //swipeRefreshLayout.setRefreshing(false);
            }
        });

基本就能看到下拉刷新的效果啦....

然后接著我們快速入門下上拉加載更多吧单芜,這個有點點麻煩,另外如果SwipeRefreshLayout + RecyclerView實現(xiàn)下拉刷新/上拉加載更多 - 可能還會遇到很多問題需要處理(比如下拉時禁止上拉犁柜,上拉加載過程中禁止下拉刷新洲鸠,還有就是上拉加載觸發(fā)的條件-當前如果沒有數(shù)據(jù),可能就不能上拉加載了,可能就是全屏顯示無數(shù)據(jù)扒腕,點擊刷新獲取了, 總之要實現(xiàn)一個效果體驗好的上拉加載/下拉刷新框架不是這么容易的)绢淀。 從目前小萌新的感覺來看,實現(xiàn)上拉加載更多動畫瘾腰,上拉停止動畫皆的,回彈,這個過程是需要監(jiān)聽持續(xù)touch事件的蹋盆,也就是說單純的靠監(jiān)聽RecyclerView的addOnScrollListener貌似不太行费薄,必須有持續(xù)監(jiān)聽。 后面要專門搞搞這個上拉加載更多的效果....

說這么多栖雾,開始吧...**上拉加載更多楞抡。 **目前的方案基本都是監(jiān)聽RecyclerView的滾動,然后判斷是上拉加載更多的話析藕,則Adapter底部條目對應(yīng)顯示加載更多召廷,以及還可以擴展“沒有更多了”等效果。

1. 先看下Adapter的擴展處理吧 - 看關(guān)鍵點就可以了账胧!每個人的適配器不同竞慢!

1.1 首先就是如果是需要展示底部加載狀態(tài)的情況下,返回的item個數(shù)多一個

image

1.2 然后就是getItemViewType返回不同的類型

image

1.3 接著就是布局加載以及數(shù)據(jù)綁定治泥,小萌新是分別搞了多個不同狀態(tài)的布局筹煮。綁定數(shù)據(jù)的時候就處理正常條目數(shù)據(jù)即可,加載狀態(tài)的布局不做綁定操作>蛹小寺谤!

image

1.4 額外提供一些數(shù)據(jù)刷新以及狀態(tài)判斷的方法

/**
     * 添加更多數(shù)據(jù)
     * @param _baseMulDataModelList
     */
    public void addMoreItem(List<BaseDataModel> _baseMulDataModelList) {
        state = STATE.HIDE;
        baseMulDataModelList.addAll(_baseMulDataModelList);
        notifyDataSetChanged();
    }

    /**
     * 開始加載
     */
    public void startLoad() {
        state = STATE.START_LOAD;
        notifyDataSetChanged();
    }

    /**
     * 加載中
     */
    public void startLoading() {
        state = STATE.LOADING;
        notifyDataSetChanged();
    }

    /**
     * 加載結(jié)束,無更多數(shù)據(jù)了
     */
    public void finishNoMoreData() {
        state = STATE.NO_MOREDATA;
        notifyDataSetChanged();
    }

    /**
     * 是否開始加載了
     * @return
     */
    public boolean bIsStart(){
        return state == STATE.START_LOAD;
    }

    /**
     * 是否正在加載
     * @return
     */
    public boolean bIsLoading(){
        return state == STATE.LOADING || state == STATE.NO_MOREDATA;
    }

    public boolean bJustLoading(){
        return state == STATE.LOADING;
    }

2. 以上就基本構(gòu)建好了吮播。接下來就是我們適配器創(chuàng)建RecyclerView.OnScrollListener | Android Developers 变屁,上拉加載處理了...

2.1 你網(wǎng)上搜有些“SwipeRefreshLayout和RecyclerView實現(xiàn)下拉刷新上拉加載更多”,基本方案都類似意狠。就是細節(jié)處理不太一樣粟关。有些是在onScrollStateChanged中請求上拉加載,有些是在onScrolled處理上拉加載环戈,大部分還是在onScrollStateChanged中進行了處理闷板。

2.2 需要注意, 如果你的條目不滿一屏的話院塞,上拉加載不會觸發(fā)onScrolled回調(diào)遮晚,所以你要注意在onScrolled處理的地方喲!

按小萌新想法拦止,這種情況可以不用觸發(fā)上拉加載更多县遣,本來就那么多數(shù)據(jù)糜颠,正常的邏輯!哈哈萧求。其兴。。

2.3 所以小萌新的總結(jié)是:onScrolled中進行判斷是否上拉加載更多夸政,并且滿足條件元旬,開啟加載;然后當滑動停止時守问, 在onScrollStateChanged中進行數(shù)據(jù)加載(需要判斷是否開啟了加載匀归,這樣可以避免不滿一屏也上拉的操作;同時還要判斷是否正在下拉刷新這些情況....)

看下兩個方法和一些屬性介紹...

onScrollStateChanged
added in version 22.1.0
void onScrollStateChanged (RecyclerView recyclerView, 
                int newState)
Callback method to be invoked when RecyclerView's scroll state changes.

Parameters
recyclerView    RecyclerView: The RecyclerView whose scroll state has changed.
newState    int: The updated scroll state. One of SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING or SCROLL_STATE_SETTLING.

onScrolled
added in version 22.1.0
void onScrolled (RecyclerView recyclerView, 
                int dx, 
                int dy)
Callback method to be invoked when the RecyclerView has been scrolled. This will be called after the scroll has completed.

This callback will also be called if visible item range changes after a layout calculation. In that case, dx and dy will be 0.

Parameters
recyclerView    RecyclerView: The RecyclerView which scrolled.
dx  int: The amount of horizontal scroll.
dy  int: The amount of vertical scroll.

dy可以用來判斷是下滑還是上滑的耗帕,目前按照我的邏輯朋譬,暫時不需要這個處理,我只需要判斷上拉加載更多時兴垦,是否達到了底部?- 靠獲取底部條目的bottom位置字柠,然后跟RecyclerView做差值探越,小于10基本就是了。此時就可以開始加載...

   /**初始化界面***/
   private void initView(){
        ///< 上拉加載更多監(jiān)聽
        adh_dailyHisItemsRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                Log.e("test", "newState=" + newState);

                ///< 正在刷新窑业,則直接返回
                if (dailyHisItemsSwr.isRefreshing() || baseAdapter.bIsLoading()) return;

                ///< 加載更多 onScrolled中上拉加載條件滿足時進行加載更多的操作??其他優(yōu)化钦幔?
                if (baseAdapter.bIsStart() &&
                        !baseAdapter.bIsLoading() &&
                        newState == RecyclerView.SCROLL_STATE_IDLE) {
                    baseAdapter.startLoading();
                    loadMoreDate();
                }
                //Log.e("test", "startload=" + startload + " newState=" + newState);
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                //lastVisibleItem = layoutManager.findLastVisibleItemPosition();
                //bUpLoad = dy > 0;
                Log.e("test", "dy=" + dy);

                if (baseAdapter.bIsLoading()) return;

                View viewlast = layoutManager.findViewByPosition(baseAdapter.getItemCount() - 1);
                Log.e("test", "viewlast=" + viewlast);
                ///< 當滑動到底部item的時候(此時底部bottom基本就是高度),設(shè)置startload = true常柄,展示加載中(可以修改為動畫顯示)
                if (null != viewlast && (recyclerView.getHeight() - viewlast.getBottom()) < 10) {
                    //Log.e("test", "getHeight=" + recyclerView.getHeight());
                    //Log.e("test", "getTop=" + viewlast.getTop());
                    //Log.e("test", "getBottom=" + viewlast.getBottom());
                    baseAdapter.startLoad();
                }
            }
        });
   }      

   /**
     * 加載更多
     */
    private void loadMoreDate() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                List<BaseDataModel> mListTemp = new ArrayList<>();
                for (int i = 0; i < 20; i++) {
                    DailyHisAdapterItemBean dailyHisAdapterItemBean = new DailyHisAdapterItemBean();
                    dailyHisAdapterItemBean.setDate("2019.11.11");
                    dailyHisAdapterItemBean.setNames("殺豬刀一把/青椒炒蘋果/蘿卜抄西瓜/蘿卜抄西瓜");
                    dailyHisAdapterItemBean.setTotal_price(12.28);
                    dailyHisAdapterItemBean.setTotal_weight(0.5);
                    mListTemp.add(dailyHisAdapterItemBean);
                }
                baseAdapter.addMoreItem(mListTemp);
                baseAdapter.finishNoMoreData();
            }
        }, 2000);
    }

基本就ojbk了鲤氢。。西潘。

image
image

總之卷玉,小萌新又接觸了一些知識。這塊后面要加強喷市,是需要看下第三方框架源碼相种,然后學習下。 雖然不用總是造輪子品姓,但是還是知道多點比較好吧....

心情好寝并,放松,開心的學習就好 - 小萌新

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腹备,一起剝皮案震驚了整個濱河市衬潦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌植酥,老刑警劉巖镀岛,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡哎媚,警方通過查閱死者的電腦和手機喇伯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拨与,“玉大人稻据,你說我怎么就攤上這事÷蛐” “怎么了捻悯?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長淤毛。 經(jīng)常有香客問我今缚,道長,這世上最難降的妖魔是什么低淡? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任姓言,我火速辦了婚禮,結(jié)果婚禮上蔗蹋,老公的妹妹穿的比我還像新娘何荚。我一直安慰自己,他們只是感情好猪杭,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布餐塘。 她就那樣靜靜地躺著,像睡著了一般皂吮。 火紅的嫁衣襯著肌膚如雪戒傻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天蜂筹,我揣著相機與錄音需纳,去河邊找鬼。 笑死艺挪,一個胖子當著我的面吹牛候齿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播闺属,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼慌盯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掂器?” 一聲冷哼從身側(cè)響起亚皂,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎国瓮,沒想到半個月后灭必,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狞谱,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年禁漓,在試婚紗的時候發(fā)現(xiàn)自己被綠了跟衅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡播歼,死狀恐怖伶跷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情秘狞,我是刑警寧澤叭莫,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站烁试,受9級特大地震影響雇初,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜减响,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一靖诗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧支示,春花似錦刊橘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咒循。三九已至据途,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叙甸,已是汗流浹背颖医。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留裆蒸,地道東北人熔萧。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像僚祷,于是被迫代替她去往敵國和親佛致。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

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