WanAndroid實(shí)戰(zhàn)——刷新加載

前情回顧:

1.WanAndroid實(shí)戰(zhàn)——首頁(yè)Banner

2.WanAndroid實(shí)戰(zhàn)——首頁(yè)文章

3.WanAndroid實(shí)戰(zhàn)——內(nèi)容顯示

在完成了上面的一系列操作之后終于可以看到文章的內(nèi)容了,但是卻只能看到“最近”的內(nèi)容,無法刷新厨姚,也無法看到之前的內(nèi)容,這篇文章將解決這個(gè)問題嗅榕。按照慣例,先上效果圖:

完成效果.gif

下拉刷新吵聪,上拉加載

目前周圍的同事在做有關(guān)刷新加載的功能都推薦使用開源框架SmartRefreshLayout凌那,實(shí)現(xiàn)起來簡(jiǎn)單,效果也是很炫酷吟逝,我這里使用的是經(jīng)典的形式帽蝶。

1.添加依賴,在gradle里面添加如下內(nèi)容

    implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-21'
    implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0-alpha-21'

2.在布局文件中添加進(jìn)去澎办,因?yàn)槲覀円⑿碌氖莚ecycleView嘲碱,所以在它外面加金砍。

    <com.scwang.smartrefresh.layout.SmartRefreshLayout
        android:id="@+id/refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <com.scwang.smartrefresh.layout.header.ClassicsHeader
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/article_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"

            />

        <com.scwang.smartrefresh.layout.footer.ClassicsFooter
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </com.scwang.smartrefresh.layout.SmartRefreshLayout>

ClassicsHeader和ClassicsFooter是經(jīng)典的頭部和尾部局蚀,如果想使用默認(rèn)的效果,那么這兩個(gè)可以不寫恕稠。

3.接口中添加加載琅绅,刷新的相關(guān)內(nèi)容

Contract.java這個(gè)類中,添加IBaseView鹅巍,這里面用來定義錯(cuò)誤和完成的接口千扶,同時(shí)讓IMainView繼承IBaseView料祠,通過監(jiān)聽這兩種狀態(tài),來完成相關(guān)的操作澎羞,例如隱藏刷新/加載的Header和Footer髓绽。新增了刷新的接口。

package com.tom.wanandroid.contract;

import com.tom.wanandroid.bean.ArticleBean;
import com.tom.wanandroid.bean.BannerBean;

import java.util.List;

import io.reactivex.Observable;

/**
 * <p>Title: Contract</p>
 * <p>Description: </p>
 *
 * @author tom
 * @date 2019/3/7 10:13
 **/
public class Contract {

    public interface IBaseView {
        /**
         * <p>加載錯(cuò)誤回調(diào)</p>
         * @param e Throwable
         */
        void onError(Throwable e);

        /**
         * <p>加載完成</p>
         */
        void onComplete();
    }



    public interface IMainModel {

        /**
         * <p>獲取banner數(shù)據(jù)</p>
         * @return banner數(shù)據(jù)
         */
        Observable<BannerBean> loadBanner();

        /**
         * <p>加載首頁(yè)文章</p>
         * @param number 頁(yè)碼
         * @return 首頁(yè)文章
         */
        Observable<List<ArticleBean>> loadArticle(int number);


        /**
         * <p>刷新首頁(yè)文章</p>
         * @return 首頁(yè)文章
         */
        Observable<List<ArticleBean>> refreshArticle();

    }

    public interface IMainView extends IBaseView{
        /**
         * <p>View 獲取到數(shù)據(jù)后進(jìn)行顯示</p>
         * @param bean banner的數(shù)據(jù)
         */
        void loadBanner(BannerBean bean);


        /**
         * <p>加載首頁(yè)文章信息</p>
         * @param bean 首頁(yè)文章數(shù)據(jù)
         */
        void loadArticle(List<ArticleBean> bean);

        /**
         * <p>刷新首頁(yè)文章</p>
         *
         * @param bean
         */
        void refreshArticle(List<ArticleBean> bean);


    }

    public interface IMainPresenter{

        /**
         * <p>首頁(yè)banner</p>
         */
        void loadBanner();


        /**
         * <p>加載首頁(yè)文章</p>
         * @param number 頁(yè)碼
         */
        void loadArticle(int number);

        /**
         * <p>刷新首頁(yè)文章</p>
         */
        void refreshArticle();

    }
}

4.處理報(bào)錯(cuò)

因?yàn)榻涌谛略鲎苯剩袑?shí)現(xiàn)這些接口的類都會(huì)報(bào)錯(cuò)顺呕,接下來就是處理各種報(bào)錯(cuò)就好了,這里以Model為例括饶,其它的都比較簡(jiǎn)單株茶。

首先將從網(wǎng)站獲取的json數(shù)據(jù)對(duì)應(yīng)的bean更名為ArticleBeanOriginal,然后新建了一個(gè)ArticleBean图焰,這里僅保存用到的屬性启盛,后續(xù)如果有需要添加的地方,可以直接進(jìn)行修改技羔。

package com.tom.wanandroid.bean;

/**
 * <p>Title: ArticleBean</p>
 * <p>Description:處理后的文章bean </p>
 *
 * @author tom
 * @date 2019/3/29 13:39
 **/
public class ArticleBean {

    public int id;
    public String title;
    public String author;
    public String niceDate;
    public long publishTime;
    public String chapterName;
    public String superChapterName;
    public boolean collect;
    public String link;



    @Override
    public String toString() {
        return "ArticleBean{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", niceDate='" + niceDate + '\'' +
                ", publishTime=" + publishTime +
                ", chapterName='" + chapterName + '\'' +
                ", superChapterName='" + superChapterName + '\'' +
                ", collect=" + collect +
                ", link='" + link + '\'' +
                '}';
    }
}

然后在IRetrofitData.java中增加刷新的方法僵闯,刷新固定獲取第0頁(yè)的數(shù)據(jù),因此不需要傳遞參數(shù)藤滥。添加后的文件內(nèi)容如下:

package com.tom.wanandroid.retrofit;

import com.tom.wanandroid.bean.BannerBean;
import com.tom.wanandroid.bean.ArticleBeanOriginal;

import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Path;

/**
 * <p>Title: IRetrofitData</p>
 * <p>Description: </p>
 *
 * @author tom
 * @date 2019/3/7 11:34
 **/
public interface IRetrofitData {
    /**
     * <p>獲取首頁(yè)輪播圖數(shù)據(jù)</p>
     * @return 首頁(yè)輪播圖數(shù)據(jù)
     */
    @GET("banner/json")
    Observable<BannerBean> loadBanner();

    /**
     * <p>獲取首頁(yè)文章數(shù)據(jù)</p>
     * @param number 頁(yè)碼
     * @return 返回首頁(yè)文章
     */
    @GET("article/list/{number}/json")
    Observable<ArticleBeanOriginal> loadMainArticle(@Path("number") int number);


    /**
     * <p>刷新首頁(yè)文章數(shù)據(jù)</p>
     * @return 返回首頁(yè)文章
     */
    @GET("article/list/0/json")
    Observable<ArticleBeanOriginal> refreshMainArticle();

}

接著修改MainModel棍厂,刷新時(shí)固定獲取第0頁(yè)數(shù)據(jù),如果數(shù)據(jù)相同超陆,則不處理牺弹,如果不相同,則放置到已有數(shù)據(jù)的上面时呀,因此需要對(duì)獲取到的數(shù)據(jù)進(jìn)行倒敘排序张漂,即讓獲取到的數(shù)據(jù)為按照發(fā)表時(shí)間倒敘排序,這樣谨娜,在調(diào)用了mArticleBeans.add(0, articleBean);方法后航攒,能夠保證文章的數(shù)據(jù)的順序是正確的。修改后的文件如下趴梢。

package com.tom.wanandroid.model;

import com.tom.wanandroid.bean.ArticleBean;
import com.tom.wanandroid.bean.BannerBean;
import com.tom.wanandroid.contract.Contract;
import com.tom.wanandroid.retrofit.IRetrofitData;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * <p>Title: MainModel</p>
 * <p>Description: </p>
 *
 * @author tom
 * @date 2019/3/7 10:54
 **/
public class MainModel implements Contract.IMainModel {

    private static final String BASE_URL = "http://www.wanandroid.com";

    List<ArticleBean> mArticleBeans = new ArrayList<>();

    @Override
    public Observable<BannerBean> loadBanner() {
        IRetrofitData retrofitData = getIRetrofitData();

        return retrofitData.loadBanner();
    }

    @Override
    public Observable<List<ArticleBean>> loadArticle(int number) {

        return getIRetrofitData().loadMainArticle(number).filter(a ->a.getErrorCode() == 0)
                .map(original -> {
                    original.getData().getDatas().stream().sorted((o1,o2) -> (int)(o2.getPublishTime() - o1.getPublishTime()))
                    .forEach(datas -> {
                        long count = mArticleBeans.stream().filter(b -> b.id == datas.getId()).count();
                        if (count <= 0) {

                            ArticleBean articleBean = new ArticleBean();
                            articleBean.id = datas.getId();
                            articleBean.title = datas.getTitle();
                            articleBean.author = datas.getAuthor();
                            articleBean.niceDate = datas.getNiceDate();
                            articleBean.publishTime = datas.getPublishTime();
                            articleBean.chapterName = datas.getChapterName();
                            articleBean.superChapterName = datas.getSuperChapterName();
                            articleBean.collect = datas.isCollect();
                            articleBean.link = datas.getLink();
                            mArticleBeans.add(articleBean);
                        }
                    });

                    return mArticleBeans;
                });

    }

    @Override
    public Observable<List<ArticleBean>> refreshArticle() {

        return getIRetrofitData().refreshMainArticle().filter(a ->a.getErrorCode() == 0)
                .map(original -> {
                    original.getData().getDatas().stream().sorted((o1, o2) -> (int) (o1.getPublishTime() - o2.getPublishTime()))
                            .forEach(datas -> {
                                //如果數(shù)據(jù)是新數(shù)據(jù)
                                long count = mArticleBeans.stream().filter(b -> b.id == datas.getId()).count();
                                if (count <= 0) {
                                    ArticleBean articleBean = new ArticleBean();
                                    articleBean.id = datas.getId();
                                    articleBean.title = datas.getTitle();
                                    articleBean.author = datas.getAuthor();
                                    articleBean.niceDate = datas.getNiceDate();
                                    articleBean.publishTime = datas.getPublishTime();
                                    articleBean.chapterName = datas.getChapterName();
                                    articleBean.superChapterName = datas.getSuperChapterName();
                                    articleBean.collect = datas.isCollect();
                                    articleBean.link = datas.getLink();
                                    mArticleBeans.add(0, articleBean);

                                }

                            });

                    return mArticleBeans;
                });
    }

    private IRetrofitData getIRetrofitData() {
        Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        return retrofit.create(IRetrofitData.class);
    }

}

順帶一句漠畜,在MainPresenter中,refreshArticle()方法如下坞靶,loadArticle同樣修改即可憔狞。

    @Override
    public void refreshArticle() {
        mModel.refreshArticle()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<ArticleBean>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        mCompositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(List<ArticleBean> articleBeans) {

                        if (isViewAttached()) {
                            getView().refreshArticle(articleBeans);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        if (isViewAttached()) {
                            getView().onError(e);
                        }

                    }

                    @Override
                    public void onComplete() {
                        if (isViewAttached()) {
                            getView().onComplete();
                        }

                    }
                });

    }

5.在View中調(diào)用刷新和加載方法

在View中,設(shè)置加載和刷新的監(jiān)聽彰阴,分別實(shí)現(xiàn)監(jiān)聽的方法瘾敢。

        mRefreshLayout.setOnLoadMoreListener(this);
        mRefreshLayout.setOnRefreshListener(this);
        
    @Override
    public void onLoadMore(@NonNull RefreshLayout refreshLayout) {

        mCurPage++;
        mPresenter.loadArticle(mCurPage);

    }

    @Override
    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
        mCurPage = 0;
        mPresenter.refreshArticle();
    }

還要考慮加載或者刷新失敗時(shí),需要將頭部和尾部隱藏掉,整個(gè)MainActivity的代碼如下簇抵。

package com.tom.wanandroid.view;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.constant.RefreshState;
import com.tom.wanandroid.Constant;
import com.tom.wanandroid.R;
import com.tom.wanandroid.adapter.ArticleAdapter;
import com.tom.wanandroid.base.BaseActivity;
import com.tom.wanandroid.bean.ArticleBean;
import com.tom.wanandroid.bean.BannerBean;
import com.tom.wanandroid.contract.Contract;
import com.tom.wanandroid.presenter.MainPresenter;
import com.tom.wanandroid.utils.GlideImageLoader;
import com.tom.wanandroid.utils.Utils;
import com.youth.banner.Banner;
import com.youth.banner.BannerConfig;
import com.youth.banner.listener.OnBannerListener;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import butterknife.BindView;

/**
 * <p>Title: MainActivity</p>
 * <p>Description: 主頁(yè)activity</p>
 *
 * @author tom
 * @date 2019/3/9 10:15
 */
public class MainActivity extends BaseActivity<Contract.IMainView, MainPresenter> implements Contract.IMainView,
        OnBannerListener, ArticleAdapter.OnItemClickListener,
        com.scwang.smartrefresh.layout.listener.OnLoadMoreListener,
        com.scwang.smartrefresh.layout.listener.OnRefreshListener {

    @BindView(R.id.main_banner)
    Banner mMainBanner;

    @BindView(R.id.article_content)
    RecyclerView mArticleContent;

    @BindView(R.id.refresh_layout)
    SmartRefreshLayout mRefreshLayout;

    ArticleAdapter mArticleAdapter;
    List<ArticleBean> mArticleDatas = new ArrayList<>();
    List<String> mBannerUrls;
    List<String> mTitles;

    /**
     * 當(dāng)前頁(yè)
     */
    int mCurPage = 0;

    /**
     * 總頁(yè)數(shù)庆杜,默認(rèn)只有一頁(yè)
     */
    int mPageCount = 1;


    @Override
    protected int getContentViewId() {
        return R.layout.activity_main;
    }

    @Override
    protected void init(Bundle savedInstanceState) {
        initBanner();
        initArticleRecycle();
        initListener();
        initData();
    }

    /**
     * <p>獲取數(shù)據(jù)</p>
     */
    private void initData() {
        mPresenter.loadBanner();
        mPresenter.refreshArticle();
    }

    /**
     * <p>初始化listener</p>
     */
    private void initListener() {
        //設(shè)置監(jiān)聽
        mMainBanner.setOnBannerListener(this);
        mArticleAdapter.setListener(this);
        mRefreshLayout.setOnLoadMoreListener(this);
        mRefreshLayout.setOnRefreshListener(this);
    }

    /**
     * <p>初始化文章adapter</p>
     */
    private void initArticleRecycle() {
        //設(shè)置adapter
        mArticleContent.setLayoutManager(new LinearLayoutManager(this));
        mArticleAdapter = new ArticleAdapter(mArticleContent, mArticleDatas);
        mArticleContent.setAdapter(mArticleAdapter);
    }

    /**
     * <p>初始化Banner</p>
     */
    private void initBanner() {

        mMainBanner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE);
        mMainBanner.setImageLoader(new GlideImageLoader());
        mMainBanner.setImages(new ArrayList<String>());
        mMainBanner.setBannerTitles(new ArrayList<>());
        mMainBanner.start();
    }

    @Override
    protected MainPresenter createPresenter() {
        return new MainPresenter();
    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    public void loadBanner(BannerBean bean) {


        if (bean.getErrorCode() == Constant.BANNER_SUCCESS) {


            //獲取圖片路徑
            List<String> images = bean.getData()
                    .stream()
                    .map(BannerBean.DataBean::getImagePath)
                    .collect(Collectors.toList());

            mMainBanner.setImages(images);

            //獲取URL
            mBannerUrls = bean.getData()
                    .stream()
                    .map(BannerBean.DataBean::getUrl)
                    .collect(Collectors.toList());


            //獲取title

            mTitles = bean.getData()
                    .stream()
                    .map(BannerBean.DataBean::getTitle)
                    .collect(Collectors.toList());

            mMainBanner.setBannerTitles(mTitles);


            mMainBanner.start();
        }
        else {
            LogUtils.d("bean 獲取失敗");

        }

    }


    @Override
    public void loadArticle(List<ArticleBean> bean) {
        mArticleAdapter.setBeans(bean);
        mArticleDatas = bean;

    }

    @Override
    public void refreshArticle(List<ArticleBean> bean) {
        mArticleAdapter.setBeans(bean);
        mArticleDatas = bean;
    }


    @Override
    public void OnBannerClick(int position) {

        if (mBannerUrls != null) {
            String url = mBannerUrls.get(position);
            String title = mTitles.get(position);
            Utils.startWebView(this, title, url);
        }

    }

    @Override
    public void onItemClick(View view, int position) {

        if (mArticleDatas != null) {
            ArticleBean bean = mArticleDatas.get(position);
            Utils.startWebView(this, bean.title, bean.link);
        }
    }

    @Override
    public void onCollectionClick(View view, int position) {
        ToastUtils.setBgColor(getResources().getColor(R.color.colorPrimaryDark, null));
        ToastUtils.setMsgColor(getResources().getColor(R.color.white, null));
        ToastUtils.showShort(R.string.coming_soon);
    }


    @Override
    public void onLoadMore(@NonNull RefreshLayout refreshLayout) {

        mCurPage++;
        mPresenter.loadArticle(mCurPage);

    }

    @Override
    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
        mCurPage = 0;
        mPresenter.refreshArticle();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mRefreshLayout.finishRefresh();
        mRefreshLayout.finishLoadMore();
    }

    @Override
    public void onError(Throwable e) {
        //加載
        if (mRefreshLayout.getState() == RefreshState.Loading) {

            mRefreshLayout.finishLoadMore();
            mCurPage--;
        }

        //刷新
        if (mRefreshLayout.getState() == RefreshState.Refreshing) {

            mRefreshLayout.finishRefresh();
        }

    }

    @Override
    public void onComplete() {

        LogUtils.d("mRefreshLayout.getState():" + mRefreshLayout.getState());

        //加載
        if (mRefreshLayout.getState() == RefreshState.Loading) {

            mRefreshLayout.finishLoadMore();
        }

        //刷新
        if (mRefreshLayout.getState() == RefreshState.Refreshing) {

            mRefreshLayout.finishRefresh();
        }
    }
}

上滑隱藏Banner

Banner雖然提供了很好的內(nèi)容展示形式,但是在上滑的過程中碟摆,我希望能夠看到更多的文章列表內(nèi)容晃财,這個(gè)時(shí)候選擇將Banner隱藏是最好的辦法,將Banner隱藏的方法有很多典蜕,這里選擇使用官方的控件來處理拓劝,實(shí)現(xiàn)起來也是非常簡(jiǎn)單,只需要在布局文件中進(jìn)行修改即可嘉裤。

1.引入依賴庫(kù)

    //design
    implementation 'com.android.support:design:28.0.0'

2.修改布局文件

這里使用CoordinatorLayout作為根布局郑临,結(jié)合AppBarLayoutCollapsingToolbarLayout來實(shí)現(xiàn)預(yù)期效果屑宠。


<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".view.MainActivity">


    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|snap">

            <com.youth.banner.Banner
                android:id="@+id/main_banner"
                android:layout_width="match_parent"
                android:layout_height="@dimen/banner_height"/>
        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>


    <com.scwang.smartrefresh.layout.SmartRefreshLayout
        android:id="@+id/refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <com.scwang.smartrefresh.layout.header.ClassicsHeader
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/article_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"

            />

        <com.scwang.smartrefresh.layout.footer.ClassicsFooter
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </com.scwang.smartrefresh.layout.SmartRefreshLayout>


</android.support.design.widget.CoordinatorLayout>

全部修改完成后厢洞,運(yùn)行程序,滿足要求典奉,剩下的內(nèi)容后面慢慢加躺翻。

5.WanAndroid實(shí)戰(zhàn)——網(wǎng)絡(luò)判斷

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市卫玖,隨后出現(xiàn)的幾起案子公你,更是在濱河造成了極大的恐慌,老刑警劉巖假瞬,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陕靠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡脱茉,警方通過查閱死者的電腦和手機(jī)剪芥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琴许,“玉大人税肪,你說我怎么就攤上這事“裉铮” “怎么了益兄?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)箭券。 經(jīng)常有香客問我净捅,道長(zhǎng),這世上最難降的妖魔是什么邦鲫? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任灸叼,我火速辦了婚禮,結(jié)果婚禮上庆捺,老公的妹妹穿的比我還像新娘古今。我一直安慰自己,他們只是感情好滔以,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布捉腥。 她就那樣靜靜地躺著,像睡著了一般你画。 火紅的嫁衣襯著肌膚如雪抵碟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天坏匪,我揣著相機(jī)與錄音拟逮,去河邊找鬼。 笑死适滓,一個(gè)胖子當(dāng)著我的面吹牛敦迄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凭迹,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼罚屋,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了嗅绸?” 一聲冷哼從身側(cè)響起脾猛,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鱼鸠,沒想到半個(gè)月后猛拴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚀狰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年漆弄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片造锅。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撼唾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出哥蔚,到底是詐尸還是另有隱情倒谷,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布糙箍,位于F島的核電站渤愁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏深夯。R本人自食惡果不足惜抖格,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一诺苹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雹拄,春花似錦收奔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至势篡,卻和暖如春翩肌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背禁悠。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工念祭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人碍侦。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓棒卷,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親祝钢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子比规,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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

  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí),會(huì)觸發(fā)此異常拦英。 O...
    我想起個(gè)好名字閱讀 5,321評(píng)論 0 9
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)拔妥、插件继准、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,109評(píng)論 4 62
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,105評(píng)論 1 32
  • 《裕語言》速成開發(fā)手冊(cè)3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 10...
    葉染柒丶閱讀 26,852評(píng)論 5 19
  • 我一生當(dāng)中遇到的最美的女孩是一位叫賢琴女孩,她是我的妻子。她有一卷烏黑的頭發(fā)镶奉,她我的全身散發(fā)著東方獨(dú)有的氣質(zhì)啃炸,一雙...
    東青揚(yáng)閱讀 269評(píng)論 2 0