定位

代码!

<LinearLayout 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" 

  android:orientation="vertical" > 

 

  <com.example.pulldown.PullDownScrollView 

      android:id="@+id/refresh_root" 

      android:layout_width="fill_parent" 

      android:layout_height="0dip" 

      android:layout_weight="1" 

      android:background="#161616" 

      android:orientation="vertical" > 

 

      <ScrollView 

          android:id="@+id/scrollview" 

          android:layout_width="fill_parent" 

          android:layout_height="wrap_content" 

          android:scrollbars="none" > 

 

          <LinearLayout 

              android:id="@+id/mainView" 

              android:layout_width="fill_parent" 

              android:layout_height="wrap_content" 

              android:background="#1f1f1f" 

              android:orientation="vertical" > 

 

              <!-- 自已的布局 --> 

 

              <TextView 

                  android:layout_width="match_parent" 

                  android:layout_height="wrap_content" 

                  android:layout_marginTop="10dip" 

                  android:gravity="center" 

                  android:text="@string/hello_world" 

                  android:textColor="@android:color/white" 

                  android:textSize="18sp" /> 

 

              <TextView 

                  android:layout_width="match_parent" 

                  android:layout_height="wrap_content" 

                  android:layout_marginTop="10dip" 

                  android:gravity="center" 

                  android:text="@string/hello_world" 

                  android:textColor="@android:color/white" 

                  android:textSize="18sp" /> 

 

              <TextView 

                  android:layout_width="match_parent" 

                  android:layout_height="wrap_content" 

                  android:layout_marginTop="10dip" 

                  android:gravity="center" 

                  android:text="@string/hello_world" 

                  android:textColor="@android:color/white" 

                  android:textSize="18sp" /> 

 

              <TextView 

                  android:layout_width="match_parent" 

                  android:layout_height="wrap_content" 

                  android:layout_marginTop="10dip" 

                  android:gravity="center" 

                  android:text="@string/hello_world" 

                  android:textColor="@android:color/white" 

                  android:textSize="18sp" /> 

          </LinearLayout> 

      </ScrollView> 

  </com.example.pulldown.PullDownScrollView> 

 

lt;/LinearLayout> 

2.UI使用:

  首先,Activity实现接口:

implements RefreshListener

部分代码如下:

Java代码  收藏代码

  package com.example.pulldown; 

 

import com.example.pulldown.PullDownScrollView.RefreshListener; 

 

import android.os.Bundle; 

import android.os.Handler; 

import android.app.Activity; 

import android.view.Menu; 

 

public class MainActivity extends Activity implements RefreshListener{ 

    private PullDownScrollView mPullDownScrollView; 

    @Override 

    protected void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.activity_main); 

         

        mPullDownScrollView = (PullDownScrollView) findViewById(R.id.refresh_root);   

        mPullDownScrollView.setRefreshListener(this);   

        mPullDownScrollView.setPullDownElastic(new PullDownElasticImp(this));   

    } 

    @Override   

    public void onRefresh(PullDownScrollView view) {   

        new Handler().postDelayed(new Runnable() {   

               

            @Override   

            public void run() {   

                // TODO Auto-generated method stub   

                mPullDownScrollView.finishRefresh("上次刷新时间:12:23");   

            }   

        }, 2000);   

    }   

    @Override 

    public boolean onCreateOptionsMenu(Menu menu) { 

        // Inflate the menu; this adds items to the action bar if it is present. 

        getMenuInflater().inflate(R.menu.activity_main, menu); 

        return true; 

    } 

 

3.再来看看控件代码:

Java代码  收藏代码

import android.content.Context; 

import android.util.AttributeSet; 

import android.view.MotionEvent; 

import android.view.View; 

import android.view.animation.LinearInterpolator; 

import android.view.animation.RotateAnimation; 

import android.widget.AbsListView; 

import android.widget.LinearLayout; 

import android.widget.ScrollView; 

 

 

/**

* @author xwangly@163.com

* @date 2013-7-9

*/ 

public class PullDownScrollView extends LinearLayout { 

 

    private static final String TAG = "PullDownScrollView"; 

 

    private int refreshTargetTop = -60; 

    private int headContentHeight; 

 

    private RefreshListener refreshListener; 

 

    private RotateAnimation animation; 

    private RotateAnimation reverseAnimation; 

     

    private final static int RATIO = 2; 

    private int preY = 0; 

    private boolean isElastic = false; 

    private int startY; 

    private int state; 

     

    private String note_release_to_refresh = "松开更新"; 

    private String note_pull_to_refresh = "下拉刷新"; 

    private String note_refreshing = "正在更新..."; 

     

    private IPullDownElastic mElastic; 

     

 

    public PullDownScrollView(Context context) { 

        super(context); 

        init(); 

 

    } 

 

    public PullDownScrollView(Context context, AttributeSet attrs) { 

        super(context, attrs); 

        init(); 

    } 

 

    private void init() { 

        animation = new RotateAnimation(0, -180, 

                RotateAnimation.RELATIVE_TO_SELF, 0.5f, 

                RotateAnimation.RELATIVE_TO_SELF, 0.5f); 

        animation.setInterpolator(new LinearInterpolator()); 

        animation.setDuration(250); 

        animation.setFillAfter(true); 

 

        reverseAnimation = new RotateAnimation(-180, 0, 

                RotateAnimation.RELATIVE_TO_SELF, 0.5f, 

                RotateAnimation.RELATIVE_TO_SELF, 0.5f); 

        reverseAnimation.setInterpolator(new LinearInterpolator()); 

        reverseAnimation.setDuration(200); 

        reverseAnimation.setFillAfter(true); 

    } 

    /**

    * 刷新监听

    * @param listener

    */ 

    public void setRefreshListener(RefreshListener listener) { 

        this.refreshListener = listener; 

    } 

    /**

    * 下拉布局

    * @param elastic

    */ 

    public void setPullDownElastic(IPullDownElastic elastic) { 

        mElastic = elastic; 

         

        headContentHeight = mElastic.getElasticHeight(); 

        refreshTargetTop = - headContentHeight; 

        LayoutParams lp = new LinearLayout.LayoutParams( 

                LayoutParams.FILL_PARENT, headContentHeight); 

        lp.topMargin = refreshTargetTop; 

        addView(mElastic.getElasticLayout(), 0, lp); 

    } 

     

    /**

    * 设置更新提示语

    * @param pullToRefresh 下拉刷新提示语

    * @param releaseToRefresh 松开刷新提示语

    * @param refreshing 正在刷新提示语

    */ 

    public void setRefreshTips(String pullToRefresh, String releaseToRefresh, String refreshing) { 

        note_pull_to_refresh = pullToRefresh; 

        note_release_to_refresh = releaseToRefresh; 

        note_refreshing = refreshing; 

    } 

    /*

    * 该方法一般和ontouchEvent 一起用 (non-Javadoc)

    * 

    * @see

    * android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)

    */ 

    @Override 

    public boolean onInterceptTouchEvent(MotionEvent ev) { 

        Logger.d(TAG, "onInterceptTouchEvent"); 

        printMotionEvent(ev); 

        if (ev.getAction() == MotionEvent.ACTION_DOWN) { 

            preY = (int) ev.getY(); 

        } 

        if (ev.getAction() == MotionEvent.ACTION_MOVE) { 

 

            Logger.d(TAG, "isElastic:" + isElastic + " canScroll:"+ canScroll() + " ev.getY() - preY:"+(ev.getY() - preY)); 

            if (!isElastic && canScroll() 

                    && (int) ev.getY() - preY >= headContentHeight / (3*RATIO) 

                    && refreshListener != null && mElastic != null) { 

 

                isElastic = true; 

                startY = (int) ev.getY(); 

                Logger.i(TAG, "在move时候记录下位置startY:" + startY); 

                return true; 

            } 

 

        } 

        return super.onInterceptTouchEvent(ev); 

    } 

 

    @Override 

    public boolean onTouchEvent(MotionEvent event) { 

        Logger.d(TAG, "onTouchEvent"); 

        printMotionEvent(event); 

        handleHeadElastic(event); 

        return super.onTouchEvent(event); 

    } 

 

    private void handleHeadElastic(MotionEvent event) { 

        if (refreshListener != null && mElastic != null) { 

            switch (event.getAction()) { 

            case MotionEvent.ACTION_DOWN: 

                Logger.i(TAG, "down"); 

                break; 

            case MotionEvent.ACTION_UP: 

 

                Logger.i(TAG, "up"); 

                if (state != IPullDownElastic.REFRESHING && isElastic) { 

                     

                    if (state == IPullDownElastic.DONE) { 

                        // 什么都不做 

                        setMargin(refreshTargetTop); 

                    } 

                    if (state == IPullDownElastic.PULL_To_REFRESH) { 

                        state = IPullDownElastic.DONE; 

                        setMargin(refreshTargetTop); 

                        changeHeaderViewByState(state, false); 

                        Logger.i(TAG, "由下拉刷新状态,到done状态"); 

                    } 

                    if (state == IPullDownElastic.RELEASE_To_REFRESH) { 

                        state = IPullDownElastic.REFRESHING; 

                        setMargin(0); 

                        changeHeaderViewByState(state, false); 

                        onRefresh(); 

                        Logger.i(TAG, "由松开刷新状态,到done状态"); 

                    } 

 

                } 

                isElastic = false; 

                break; 

            case MotionEvent.ACTION_MOVE: 

                Logger.i(TAG, "move"); 

                int tempY = (int) event.getY(); 

                 

                if (state != IPullDownElastic.REFRESHING && isElastic) { 

                    // 可以松手去刷新了 

                    if (state == IPullDownElastic.RELEASE_To_REFRESH) { 

                        if (((tempY - startY) / RATIO < headContentHeight) 

                                && (tempY - startY) > 0) { 

                            state = IPullDownElastic.PULL_To_REFRESH; 

                            changeHeaderViewByState(state, true); 

                            Logger.i(TAG, "由松开刷新状态转变到下拉刷新状态"); 

                        } else if (tempY - startY <= 0) { 

                            state = IPullDownElastic.DONE; 

                            changeHeaderViewByState(state, false); 

                            Logger.i(TAG, "由松开刷新状态转变到done状态"); 

                        } 

                    } 

                    if (state == IPullDownElastic.DONE) { 

                        if (tempY - startY > 0) { 

                            state = IPullDownElastic.PULL_To_REFRESH; 

                            changeHeaderViewByState(state, false); 

                        } 

                    } 

                    if (state == IPullDownElastic.PULL_To_REFRESH) { 

                        // 下拉到可以进入RELEASE_TO_REFRESH的状态 

                        if ((tempY - startY) / RATIO >= headContentHeight) { 

                            state = IPullDownElastic.RELEASE_To_REFRESH; 

                            changeHeaderViewByState(state, false); 

                            Logger.i(TAG, "由done或者下拉刷新状态转变到松开刷新"); 

                        } else if (tempY - startY <= 0) { 

                            state = IPullDownElastic.DONE; 

                            changeHeaderViewByState(state, false); 

                            Logger.i(TAG, "由DOne或者下拉刷新状态转变到done状态"); 

                        } 

                    } 

                    if (tempY - startY > 0) { 

                        setMargin((tempY - startY)/2 + refreshTargetTop); 

                    } 

                } 

                break; 

            } 

        } 

    } 

     

    /**

    * 

    */ 

    private void setMargin(int top) { 

        LinearLayout.LayoutParams lp = (LayoutParams) mElastic.getElasticLayout() 

                .getLayoutParams(); 

        lp.topMargin = top; 

        // 修改后刷新 

        mElastic.getElasticLayout().setLayoutParams(lp); 

        mElastic.getElasticLayout().invalidate(); 

    } 

 

    private void changeHeaderViewByState(int state, boolean isBack) { 

 

        mElastic.changeElasticState(state, isBack); 

        switch (state) { 

        case IPullDownElastic.RELEASE_To_REFRESH: 

            mElastic.showArrow(View.VISIBLE); 

            mElastic.showProgressBar(View.GONE); 

            mElastic.showLastUpdate(View.VISIBLE); 

            mElastic.setTips(note_release_to_refresh); 

 

            mElastic.clearAnimation(); 

            mElastic.startAnimation(animation); 

            Logger.i(TAG, "当前状态,松开刷新"); 

            break; 

        case IPullDownElastic.PULL_To_REFRESH: 

            mElastic.showArrow(View.VISIBLE); 

            mElastic.showProgressBar(View.GONE); 

            mElastic.showLastUpdate(View.VISIBLE); 

            mElastic.setTips(note_pull_to_refresh); 

 

            mElastic.clearAnimation(); 

 

            // 是由RELEASE_To_REFRESH状态转变来的 

            if (isBack) { 

                mElastic.startAnimation(reverseAnimation); 

            } 

            Logger.i(TAG, "当前状态,下拉刷新"); 

            break; 

        case IPullDownElastic.REFRESHING: 

            mElastic.showArrow(View.GONE); 

            mElastic.showProgressBar(View.VISIBLE); 

            mElastic.showLastUpdate(View.GONE); 

            mElastic.setTips(note_refreshing); 

 

            mElastic.clearAnimation(); 

            Logger.i(TAG, "当前状态,正在刷新..."); 

            break; 

        case IPullDownElastic.DONE: 

            mElastic.showProgressBar(View.GONE); 

            mElastic.clearAnimation(); 

//            arrowImageView.setImageResource(R.drawable.goicon); 

            // tipsTextview.setText("下拉刷新"); 

            // lastUpdatedTextView.setVisibility(View.VISIBLE); 

            Logger.i(TAG, "当前状态,done"); 

            break; 

        } 

    } 

 

    private void onRefresh() { 

        // downTextView.setVisibility(View.GONE); 

//        scroller.startScroll(0, i, 0, 0 - i); 

//        invalidate(); 

        if (refreshListener != null) { 

            refreshListener.onRefresh(this); 

        } 

    } 

 

    /**

    * 

    */ 

    @Override 

    public void computeScroll() { 

//        if (scroller.computeScrollOffset()) { 

//            int i = this.scroller.getCurrY(); 

//            LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.refreshView 

//                    .getLayoutParams(); 

//            int k = Math.max(i, refreshTargetTop); 

//            lp.topMargin = k; 

//            this.refreshView.setLayoutParams(lp); 

//            this.refreshView.invalidate(); 

//            invalidate(); 

//        } 

    } 

 

    /**

    * 结束刷新事件,UI刷新完成后必须回调此方法

    * @param text 一般传入:“上次更新时间:12:23”

    */ 

    public void finishRefresh(String text) { 

        if (mElastic == null) { 

            Logger.d(TAG, "finishRefresh mElastic:" + mElastic); 

            return; 

        } 

        state = IPullDownElastic.DONE; 

        mElastic.setLastUpdateText(text); 

        changeHeaderViewByState(state,false); 

        Logger.i(TAG, "执行了=====finishRefresh"); 

 

        mElastic.showArrow(View.VISIBLE); 

        mElastic.showLastUpdate(View.VISIBLE); 

        setMargin(refreshTargetTop); 

//        scroller.startScroll(0, i, 0, refreshTargetTop); 

//        invalidate(); 

    } 

 

    private boolean canScroll() { 

        View childView; 

        if (getChildCount() > 1) { 

            childView = this.getChildAt(1); 

            if (childView instanceof AbsListView) { 

                int top = ((AbsListView) childView).getChildAt(0).getTop(); 

                int pad = ((AbsListView) childView).getListPaddingTop(); 

                if ((Math.abs(top - pad)) < 3 

                        && ((AbsListView) childView).getFirstVisiblePosition() == 0) { 

                    return true; 

                } else { 

                    return false; 

                } 

            } else if (childView instanceof ScrollView) { 

                if (((ScrollView) childView).getScrollY() == 0) { 

                    return true; 

                } else { 

                    return false; 

                } 

            } 

 

        } 

        return canScroll(this); 

    } 

     

    /**

    * 子类重写此方法可以兼容其它的子控件,目前只兼容AbsListView和ScrollView

    * @param view

    * @return

    */ 

    public boolean canScroll(PullDownScrollView view) { 

        return false; 

    } 

 

    private void printMotionEvent(MotionEvent event) { 

        switch (event.getAction()) { 

        case MotionEvent.ACTION_DOWN: 

            Logger.d(TAG, "down"); 

            break; 

        case MotionEvent.ACTION_MOVE: 

            Logger.d(TAG, "move"); 

            break; 

        case MotionEvent.ACTION_UP: 

            Logger.d(TAG, "up"); 

        default: 

            break; 

        } 

    } 

    /**

    * 刷新监听接口

    */ 

    public interface RefreshListener { 

        public void onRefresh(PullDownScrollView view); 

    } 

 

4.接口:

Java代码  收藏代码

import android.view.View; 

import android.view.animation.Animation; 

 

/**

* @author xwangly@163.com

* @date 2013-7-10

* 下拉控件接口

*/ 

public interface IPullDownElastic { 

    public final static int RELEASE_To_REFRESH = 0; 

    public final static int PULL_To_REFRESH = 1; 

    public final static int REFRESHING = 2; 

    public final static int DONE = 3; 

 

    public View getElasticLayout(); 

 

    public int getElasticHeight(); 

 

    public void showArrow(int visibility); 

 

    public void startAnimation(Animation animation); 

 

    public void clearAnimation(); 

 

    public void showProgressBar(int visibility); 

 

    public void setTips(String tips); 

 

    public void showLastUpdate(int visibility); 

 

    public void setLastUpdateText(String text); 

     

    /**

    * 可以不用实现此方法,PullDownScrollView会处理ElasticLayout布局中的状态 

    * 如果需要特殊处理,可以实现此方法进行处理

    * 

    * @param state  @see RELEASE_To_REFRESH

    * @param isBack 是否是松开回退

    */ 

    public void changeElasticState(int state, boolean isBack); 

 

5.默认实现:

Java代码  收藏代码

import android.content.Context; 

import android.view.LayoutInflater; 

import android.view.View; 

import android.view.animation.Animation; 

import android.widget.ImageView; 

import android.widget.ProgressBar; 

import android.widget.TextView; 

 

 

/**

* @author xwangly@163.com

* @date  2013-7-10

* 默认下拉控件布局实现

*/ 

public class PullDownElasticImp implements IPullDownElastic { 

    private View refreshView; 

    private ImageView arrowImageView; 

    private int headContentHeight; 

    private ProgressBar progressBar; 

    private TextView tipsTextview; 

    private TextView lastUpdatedTextView; 

     

    private Context mContext; 

    public PullDownElasticImp(Context context) { 

        mContext = context; 

        init(); 

    } 

     

 

    private void init() { 

        // 刷新视图顶端的的view 

        refreshView = LayoutInflater.from(mContext).inflate( 

                R.layout.refresh_top_item, null); 

 

        // 指示器view 

        arrowImageView = (ImageView) refreshView 

                .findViewById(R.id.head_arrowImageView); 

        // 刷新bar 

        progressBar = (ProgressBar) refreshView 

                .findViewById(R.id.head_progressBar); 

        // 下拉显示text 

        tipsTextview = (TextView) refreshView.findViewById(R.id.refresh_hint); 

        // 下来显示时间 

        lastUpdatedTextView = (TextView) refreshView 

                .findViewById(R.id.refresh_time); 

 

        headContentHeight = Utils.dip2px(mContext, 50); 

    } 

 

    /**

    * @return

    * 

    */ 

    @Override 

    public View getElasticLayout() { 

        return refreshView; 

    } 

 

    /**

    * @return

    * 

    */ 

    @Override 

    public int getElasticHeight() { 

        return headContentHeight; 

    } 

 

    /**

    * @param show

    * 

    */ 

    @Override 

    public void showArrow(int visibility) { 

        arrowImageView.setVisibility(visibility); 

    } 

 

    /**

    * @param animation

    * 

    */ 

    @Override 

    public void startAnimation(Animation animation) { 

        arrowImageView.startAnimation(animation); 

    } 

 

    /**

    * 

    * 

    */ 

    @Override 

    public void clearAnimation() { 

        arrowImageView.clearAnimation(); 

    } 

 

    /**

    * @param show

    * 

    */ 

    @Override 

    public void showProgressBar(int visibility) { 

        progressBar.setVisibility(visibility); 

    } 

 

    /**

    * @param tips

    * 

    */ 

    @Override 

    public void setTips(String tips) { 

        tipsTextview.setText(tips); 

    } 

 

    /**

    * @param show

    * 

    */ 

    @Override 

    public void showLastUpdate(int visibility) { 

        lastUpdatedTextView.setVisibility(visibility); 

    } 

 

    /**

    * @param text

    * 

    */ 

    public void setLastUpdateText(String text) { 

        lastUpdatedTextView.setText(text); 

    } 

 

 

    /**

    * @param state

    * @param isBack

    * 

    */ 

    @Override 

    public void changeElasticState(int state, boolean isBack) { 

        // TODO Auto-generated method stub 

         

    } 

 

6.默认实现的布局:

Java代码  收藏代码

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 

    android:layout_width="fill_parent" 

    android:layout_height="-50.0dip" 

    android:orientation="vertical" > 

 

    <LinearLayout 

        android:layout_width="fill_parent" 

        android:layout_height="0.0dip" 

        android:layout_weight="1.0" 

        android:gravity="center" 

        android:orientation="horizontal" > 

 

        <!-- 箭头图像、进度条 --> 

 

        <FrameLayout 

            android:layout_width="wrap_content" 

            android:layout_height="wrap_content" 

            android:layout_alignParentLeft="true" 

            android:layout_centerVertical="true" 

            android:layout_marginLeft="30dip" > 

 

            <!-- 箭头 --> 

 

            <ImageView 

                android:id="@+id/head_arrowImageView" 

                android:layout_width="wrap_content" 

                android:layout_height="wrap_content" 

                android:layout_gravity="center" 

                android:src="@drawable/goicon" /> 

 

            <!-- 进度条 --> 

 

            <ProgressBar 

                android:id="@+id/head_progressBar" 

                style="@android:style/Widget.ProgressBar.Small.Inverse" 

                android:layout_width="wrap_content" 

                android:layout_height="wrap_content" 

                android:layout_gravity="center" 

                android:visibility="gone" /> 

        </FrameLayout> 

 

        <LinearLayout 

            android:layout_width="fill_parent" 

            android:layout_height="fill_parent" 

            android:gravity="center" 

            android:orientation="vertical" > 

 

            <!-- 提示 --> 

 

            <TextView 

                android:id="@+id/refresh_hint" 

                android:layout_width="wrap_content" 

                android:layout_height="wrap_content" 

                android:text="下拉刷新" 

                android:textColor="#f2f2f2" 

                android:textSize="16sp" /> 

 

            <!-- 最近更新 --> 

 

            <TextView 

                android:id="@+id/refresh_time" 

                android:layout_width="wrap_content" 

                android:layout_height="wrap_content" 

                android:text="上次更新" 

                android:textColor="#b89766" 

                android:textSize="10sp" /> 

        </LinearLayout> 

    </LinearLayout> 

 

</LinearLayout> 

6.图片资源:

@drawable/goicon

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

推荐阅读更多精彩内容