1.1 ListView使用技巧

Android高级进阶学习笔记》第1个知识点:ListView使用技巧

目录

1、ListView常用优化技巧
    1.1 使用ViewHolder模式提高效率
    1.2 设置项目间分隔线
    1.3 隐藏ListView的滚动条
    1.4 取消ListView的Item点击效果
    1.5 设置ListView需要显示在第几项
    1.6 动态修改ListView
    1.7 遍历ListView中的所有Item
    1.8 处理空ListView
    1.9 ListView的滑动监听
        1.9.1 OnTouchListener
        1.9.2 OnScrollListener
2、ListView常用拓展
    2.1 具有弹性的ListView
    2.2 自动显示、隐藏布局的ListView
    2.3 聊天界面的实现
    2.4动态改变ListView布局

1、ListView常用优化技巧

1.1 使用ViewHolder模式提高效率

ViewHolder模式是提高ListView效率的一个重要的方法。ViewHolder模式充分利用了ListView的视图缓存机制,避免了每次在调用getView()的时候都去通过findViewById()实例化控件,完整代码如下

public class NotifyAdapter extends BaseAdapter {

    private List<String> mData;
    private LayoutInflater mInflater;

    public NotifyAdapter(Context context, List<String> data) {
        this.mData = data;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        // 判断是否缓存
        if (convertView == null) {
            holder = new ViewHolder();
            // 通过LayoutInflater实例化布局
            convertView = mInflater.inflate(R.layout.notify_item, null);
            holder.img = (ImageView) convertView.findViewById(R.id.imageView);
            holder.title = (TextView) convertView.findViewById(R.id.textView);
            convertView.setTag(holder);
        } else {
            // 通过tag找到缓存的布局
            holder = (ViewHolder) convertView.getTag();
        }
        // 设置布局中控件要显示的视图
        holder.img.setBackgroundResource(R.drawable.ic_launcher);
        holder.title.setText(mData.get(position));
        return convertView;
    }

    public final class ViewHolder {
        public ImageView img;
        public TextView title;
    }
}

1.2 设置项目间分隔线

  • 系统默认


    image.png
  • 自定义

        android:dividerHeight="10dp"
        android:divider="@android:color/darker_gray"
image.png
  • 把分隔线设置透明
 android:divider="@null"
image.png

1.3 隐藏ListView的滚动条

android:scrollbars="none"

1.4 取消ListView的Item点击效果

5.X以上是水波纹效果,5.X以下是一个改变背景颜色的效果,设置如下所示的listSelector的属性值可以去掉点击效果

 android:listSelector="@android:color/transparent"
 android:listSelector="#00000000"

1.5 设置ListView需要显示在第几项

ListView以Item为单位进行显示,默认显示在第一个Item,当需要指定具体显示的Item时,可以通过如下代码来实现

 //瞬间完成的移动
 mListView.setSelection(position);
        //实现平滑移动
        mListView.smoothScrollByOffset(offset);
        mListView.smoothScrollBy(diatance,duration);
        mListView.smoothScrollToPosition(index);

1.6 动态修改ListView

        
        //对适配器的数据进行更新
        mData.add("new");
        mAdapter.notifyDataSetChanged();

注意的是,必须保证传进Adapter的数据List是同一个List而不能是其它对象,否则将无法实现该效果。

完整代码如下:

public class NotifyTest extends Activity {

    private List<String> mData;
    private ListView mListView;
    private NotifyAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.notify);
        mData = new ArrayList<String>();
        for (int i = 0; i < 20; i++) {
            mData.add("" + i);
        }
        mListView = (ListView) findViewById(R.id.listView);


        mAdapter = new NotifyAdapter(this, mData);
        mListView.setAdapter(mAdapter);
      
    }

    public void btnAdd(View view) {

        //对适配器的数据进行更新
        mData.add("new");
        mAdapter.notifyDataSetChanged();
        mListView.setSelection(mData.size() - 1);
    }
}
image.png

1.7 遍历ListView中的所有Item

  for (int i = 0; i < mListView.getChildCount(); i++) {
            View view = mListView.getChildAt(i);
        }

1.8 处理空ListView

ListView用于展示列表数据,但当列表中无数据时,ListView不会显示任何数据或者提示,不过ListView提供了一个方法--setEmptyView(),可以通过这个方法我们给ListView设置一个在空数据下显示的默认提示,使用方法如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <ListView
        android:id="@+id/lv_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
    <ImageView
        android:id="@+id/iv_empty"
        android:src="@mipmap/ic_launcher"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>
        private ListView lvList;
        private ImageView ivEmpty;


        lvList = (ListView) findViewById(R.id.lv_list);
        ivEmpty = (ImageView) findViewById(R.id.iv_empty);
        lvList.setEmptyView(ivEmpty);

1.9 ListView的滑动监听

ListView的滑动监听主要包括:OnTouchListener以及OnScrollListener,此外开发者通常还需要使用GestureDetector手势识别、VelocityTracker滑动速度检测辅助类来完成更好的监听。

1.9.1 OnTouchListener
        lvList.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    
                    //触摸时操作
                    case MotionEvent.ACTION_DOWN:
                        break;
                        
                    //移动时操作
                    case MotionEvent.ACTION_HOVER_MOVE:
                        break;

                    //离开时操作
                    case MotionEvent.ACTION_UP:
                        break;
                }
                return false;
            }
        });
1.9.2 OnScrollListener
        mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                switch (scrollState){
                    //滑动停止时
                    case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                        Log.d(TAG,"SCROLL_STATE_IDLE===========");
                        break;

                    //正在滑动时
                    case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                        Log.d(TAG,"SCROLL_STATE_TOUCH_SCROLL===========");
                        break;

                    //手指用力滑动,即是在离开后ListView由于惯性继续滑动
                    case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                        Log.d(TAG,"SCROLL_STATE_FLING===========");
                        break;
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                //firstVisibleItem:当前能看见的第一个Item的ID(从0开始)
                //visibleItemCount:当前能看见的Item总数
                //totalItemCount:整个ListView的Item总数

                //滚动时一直调用
                Log.d(TAG,"onScroll=============");

                Log.d(TAG,"firstVisibleItem============="+firstVisibleItem);
                Log.d(TAG,"visibleItemCount============="+visibleItemCount);
                Log.d(TAG,"totalItemCount============="+totalItemCount);

                //重要的使用场景1:判断是否滚动到了最后一行
                if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0){
                    Log.d(TAG,"滚动到了最后一行============");
                }

                //重要的使用场景2:判断滚动方向
                if (firstVisibleItem > lastVisibleItemPosition){ 
                    //上滑
                }else if (firstVisibleItem < lastVisibleItemPosition){
                    //下滑
                }
                lastVisibleItemPosition = firstVisibleItem;
            }
        });
image.png
image.png
image.png
image.png

此外,ListView封装了一些方法来获取当前可视的Item的位置等消息

        
        //获取可视区域内最后一个Item的id
        mListView.getLastVisiblePosition();

        //获取可视区域内第一个Item的id
        mListView.getFirstVisiblePosition();

2、ListView常用拓展

2.1 具有弹性的ListView

Android默认的ListView在滚动到顶端或者低端的时候,没有很好的提示,下面通过修改源码的方法来实现其中的一种实现方式。

源码中的方法如下:


image.png

代码实现过程:


/**
 * 具有弹性滑动的ListView
 */
public class CustomListview extends ListView {

    private int mMaxOverDistance = 30;

    public CustomListview(Context context) {
        super(context);
    }

    public CustomListview(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomListview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    
    //初始化操作
    private void initView(Context context){
        //让不同分辨率都显示一样的距离
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        float density  =  metrics.density;
        mMaxOverDistance = (int)(density * mMaxOverDistance);
        
    }

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        return super.overScrollBy(
                deltaX, deltaY,
                scrollX, scrollY,
                scrollRangeX, scrollRangeY,
                maxOverScrollX, mMaxOverDistance,
                isTouchEvent);
    }
}
image.png

2.2 自动显示、隐藏布局的ListView

GIF.gif
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:headerDividersEnabled="false" />

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@android:color/holo_blue_light" />

</RelativeLayout>
public class ScrollHideListView extends Activity {

    private Toolbar mToolbar;
    private ListView mListView;
    private String[] mStr = new String[20];
    private int mTouchSlop;
    private float mFirstY;
    private float mCurrentY;
    private int direction;
    private ObjectAnimator mAnimator;
    private boolean mShow = true;

    //判断滑动事件
    View.OnTouchListener myTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mFirstY = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    mCurrentY = event.getY();
                    if (mCurrentY - mFirstY > mTouchSlop) {
                        direction = 0;// 上拉
                    } else if (mFirstY - mCurrentY > mTouchSlop) {
                        direction = 1;// 下拉
                    }
                    if (direction == 1) {
                        if (mShow) {
                            toolbarAnim(1);//show
                            mShow = !mShow;
                        }
                    } else if (direction == 0) {
                        if (!mShow) {
                            toolbarAnim(0);//hide
                            mShow = !mShow;
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.scroll_hide);

        //获取系统认为的最低滑动距离
//        mTouchSlop = TOUCH_SLOP;
//        private static final int TOUCH_SLOP = 8;
        mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mListView = (ListView) findViewById(R.id.listview);
        for (int i = 0; i < mStr.length; i++) {
            mStr[i] = "Item " + i;
        }

        //给ListView添加一个头部:是为了避免第一个Item被toolbar遮挡
        View header = new View(this);
        header.setLayoutParams(new AbsListView.LayoutParams(
                AbsListView.LayoutParams.MATCH_PARENT,

                //abc_action_bar_default_height_material : 获取系统ActonBar的高度
                (int) getResources().getDimension(
                        R.dimen.abc_action_bar_default_height_material)));
        mListView.addHeaderView(header);
        mListView.setAdapter(new ArrayAdapter<String>(
                ScrollHideListView.this,
                android.R.layout.simple_expandable_list_item_1,
                mStr));
        mListView.setOnTouchListener(myTouchListener);
    }

    private void toolbarAnim(int flag) {
        if (mAnimator != null && mAnimator.isRunning()) {
            mAnimator.cancel();
        }
        if (flag == 0) { //隐藏ToolBar
            mAnimator = ObjectAnimator.ofFloat(mToolbar,
                    "translationY", mToolbar.getTranslationY(), 0);
        } else { //显示ToolBar
            mAnimator = ObjectAnimator.ofFloat(mToolbar,
                    "translationY", mToolbar.getTranslationY(),
                    -mToolbar.getHeight());
        }
        mAnimator.start();
    }
}

2.3 聊天界面的实现

image.png

实现思路:通过Adapter的getItemViewType()和getViewTypeCount()方法来加载不同的布局

左边消息的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:padding="10dp">

    <ImageView
        android:id="@+id/icon_in"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/text_in"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/chatitem_in_bg"
        android:gravity="center"
        android:textSize="20sp" />

</LinearLayout>

右边消息的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical|right"
    android:orientation="horizontal"
    android:padding="10dp">


    <TextView
        android:id="@+id/text_out"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/chatitem_out_bg"
        android:gravity="center"
        android:textSize="20sp" />

    <ImageView
        android:id="@+id/icon_out"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

</LinearLayout>

信息实体Bean

public class ChatItemListViewBean {

    private int type;
    private String text;
    private Bitmap icon;

    public ChatItemListViewBean() {
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public Bitmap getIcon() {
        return icon;
    }

    public void setIcon(Bitmap icon) {
        this.icon = icon;
    }
}

适配器的实现:

public class ChatItemListViewAdapter extends BaseAdapter {

    private List<ChatItemListViewBean> mData;
    private LayoutInflater mInflater;

    public ChatItemListViewAdapter(Context context,
                                   List<ChatItemListViewBean> data) {
        this.mData = data;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        ChatItemListViewBean bean = mData.get(position);
        return bean.getType();
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            if (getItemViewType(position) == 0) {
                holder = new ViewHolder();
                convertView = mInflater.inflate(
                        R.layout.chat_item_itemin, null);
                holder.icon = (ImageView) convertView.findViewById(
                        R.id.icon_in);
                holder.text = (TextView) convertView.findViewById(
                        R.id.text_in);
            } else {
                holder = new ViewHolder();
                convertView = mInflater.inflate(
                        R.layout.chat_item_itemout, null);
                holder.icon = (ImageView) convertView.findViewById(
                        R.id.icon_out);
                holder.text = (TextView) convertView.findViewById(
                        R.id.text_out);
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.icon.setImageBitmap(mData.get(position).getIcon());
        holder.text.setText(mData.get(position).getText());
        return convertView;
    }

    public final class ViewHolder {
        public ImageView icon;
        public TextView text;
    }
}

主界面逻辑实现:

public class ChatItemListViewTest extends Activity {

    private ListView mListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.chat_item_main);

        mListView = (ListView) findViewById(R.id.listView_chat);
        ChatItemListViewBean bean1 = new ChatItemListViewBean();
        bean1.setType(0);
        bean1.setIcon(BitmapFactory.decodeResource(getResources(),
                R.drawable.in_icon));
        bean1.setText("Hello how are you?");

        ChatItemListViewBean bean2 = new ChatItemListViewBean();
        bean2.setType(1);
        bean2.setIcon(BitmapFactory.decodeResource(getResources(),
                R.drawable.ic_launcher));
        bean2.setText("Fine thank you, and you?");

        ChatItemListViewBean bean3 = new ChatItemListViewBean();
        bean3.setType(0);
        bean3.setIcon(BitmapFactory.decodeResource(getResources(),
                R.drawable.in_icon));
        bean3.setText("I am fine too");

        ChatItemListViewBean bean4 = new ChatItemListViewBean();
        bean4.setType(1);
        bean4.setIcon(BitmapFactory.decodeResource(getResources(),
                R.drawable.ic_launcher));
        bean4.setText("Bye bye");

        ChatItemListViewBean bean5 = new ChatItemListViewBean();
        bean5.setType(0);
        bean5.setIcon(BitmapFactory.decodeResource(getResources(),
                R.drawable.in_icon));
        bean5.setText("See you");

        List<ChatItemListViewBean> data = new ArrayList<ChatItemListViewBean>();
        data.add(bean1);
        data.add(bean2);
        data.add(bean3);
        data.add(bean4);
        data.add(bean5);
        mListView.setAdapter(new ChatItemListViewAdapter(this, data));
    }
}

2.4动态改变ListView布局

GIF.gif

实现思路:在getView()的时候,通过判断来选择加载不同的布局

适配器代码实现:

public class FocusListViewAdapter extends BaseAdapter {

    private List<String> mData;
    private Context mContext;
    private int mCurrentItem = 0;

    public FocusListViewAdapter(Context context, List<String> data) {
        this.mContext = context;
        this.mData = data;
    }

    public int getCount() {
        return mData.size();
    }

    public Object getItem(int position) {
        return mData.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        LinearLayout layout = new LinearLayout(mContext);
        layout.setOrientation(LinearLayout.VERTICAL);
        if (mCurrentItem == position) {
            layout.addView(addFocusView(position));
        } else {
            layout.addView(addNormalView(position));
        }
        return layout;
    }

    public void setCurrentItem(int currentItem) {
        this.mCurrentItem = currentItem;
    }

    private View addFocusView(int i) {
        ImageView iv = new ImageView(mContext);
        iv.setImageResource(R.drawable.ic_launcher);
        return iv;
    }

    private View addNormalView(int i) {
        LinearLayout layout = new LinearLayout(mContext);
        layout.setOrientation(LinearLayout.HORIZONTAL);
        ImageView iv = new ImageView(mContext);
        iv.setImageResource(R.drawable.in_icon);
        layout.addView(iv, new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
        TextView tv = new TextView(mContext);
        tv.setText(mData.get(i));
        layout.addView(tv, new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
        layout.setGravity(Gravity.CENTER);
        return layout;
    }

主界面逻辑实现:

public class FocusListViewTest extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.focus);
        ListView listView = (ListView) findViewById(R.id.focus_listView);
        List<String> data = new ArrayList<String>();
        data.add("I am item 1");
        data.add("I am item 2");
        data.add("I am item 3");
        data.add("I am item 4");
        data.add("I am item 5");
        final FocusListViewAdapter adapter = new FocusListViewAdapter(this, data);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                adapter.setCurrentItem(position);
                adapter.notifyDataSetChanged();
            }
        });
    }
}
《Android高级进阶学习笔记》目录链接地址:

https://www.jianshu.com/c/abfff0ab5dbb

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容