仿电商应用中搜索模块的实现【GreenDao数据库存储数据】

好久没写博客了,主要是最近太忙了(好吧,其实是因为自己太懒了)。进入正题,今天主要实现的功能是:搜索。 没错,搜索模块在很多电商类app中是很常见的,实现起来也比较容易,但是经常在群里看见有人问有没有关于搜索功能的demo,加之我最近自己做的一个项目中也有搜索模块,所以这里就来说说我是怎么实现的。

这里非常感谢 干货集中营 提供的搜索的接口。据说不含效果图的文章都是耍流氓,,吓得我赶紧来了张效果图,如下图所示
这里写图片描述

需求介绍

1.首先,我们要监听搜索框EditText 我们在afterTextChanged()方法中需要去进行判断,当EditText有值时,搜索框后面的清除图标显示,我们根据输入的关键字向服务器发送请求(通过Handler每隔一段时间延迟请求),这样做的原因是因为 假如用户输入io然后又在极短时间内继续输入s,延迟发送请求就可以避免重复像服务器提交数据。需要注意的是,每次发送请求之前需要检查是否还存在有未处理的消息,有,则需要取消掉。
2.当我们向服务器请求到数据之后,点击item进入详情页的时候,我们需要将这条数据存储起来,作为历史记录向用户展示。关于数据存储的方式有很多,这里我采用的是GreenDao数据库来保存数据。这里特别说明一下,新版本的GreenDao使用步骤简化了很多,使用起来还是很爽的。关于GreenDao的使用,如果还没用过此数据库的童鞋可以看我这篇文章http://blog.csdn.net/xiaxiazaizai01/article/details/53118748,这里就不再详细介绍了。
3.当我们用电商类的搜索时,可以发现,最近搜索的记录会显示在最上面,并且当再次搜索此字段时,并不会重复添加,只是更新了时间,因为我们是按时间排序的。
4.主要介绍下此demo中用到的一些比较不错的框架,BaseRecyclerViewAdapterHelper 非常好用的一个Recyclerview框架,OkGo 网络请求

具体代码说明

首先,看看我们的布局文件 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ECECEC"
    >

    <LinearLayout
        android:id="@+id/ll_top"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:gravity="center_vertical"
        android:background="#FFFFFF"
        android:orientation="horizontal"
        >
        <ImageView
            android:id="@+id/search_back"
            android:layout_width="45dp"
            android:layout_height="match_parent"
            android:paddingLeft="6dp"
            android:paddingRight="6dp"
            android:src="@drawable/back_ic"
            />
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            android:gravity="center_vertical"
            android:background="@drawable/search_bg_shape"
            android:orientation="horizontal"
            >
            <EditText
                android:id="@+id/et_search"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:drawableLeft="@drawable/search_icon"
                android:hint="android/ios/福利/前端/休息视频"
                android:drawablePadding="10dp"
                android:textSize="14sp"
                android:layout_margin="5dp"
                android:singleLine="true"
                android:background="@null"
                />
            <ImageView
                android:id="@+id/search_clear"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_margin="5dp"
                android:src="@drawable/clear_search_ic"
                android:visibility="gone"/>
        </LinearLayout>
        <TextView
            android:id="@+id/tv_search"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:text="搜索"
            android:textColor="#333333"
            android:textSize="16sp"/>
    </LinearLayout>
    <View
        android:id="@+id/line"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@id/ll_top"
        android:background="#e2e2e2"/>
    <!-- 热搜模块,这里不做重点,省略。。。 -->

    <!-- 搜索历史模块 -->
    <LinearLayout
        android:id="@+id/ll_history"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_below="@id/line"
        android:visibility="gone">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:layout_marginLeft="10dp"
            android:text="历史搜索"
            android:textColor="#333333"
            android:textSize="16sp"
            android:textStyle="bold"/>
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#e2e2e2"/>
        <android.support.v7.widget.RecyclerView
            android:id="@+id/history_search_recyclerview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>

    <!-- 搜索的结果展示模块 -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/search_data_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/line"
        android:visibility="gone"/>
    <RelativeLayout
        android:id="@+id/rl_progress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/line"
        android:layout_marginTop="20dp"
        android:gravity="center_horizontal"
        android:visibility="gone"
        >
        <com.json.search.CustomProgressBar
            android:id="@+id/progress_bar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:padding="5dp"
            app:search_progress_color="#10a679"
            app:search_progress_width="1dp"
            app:search_radius="6dp"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/progress_bar"
            android:layout_marginLeft="5dp"
            android:layout_centerVertical="true"
            android:text="加载中..."/>
    </RelativeLayout>
</RelativeLayout>

接着,看下我们存储数据库所需要的实体类是如何定义的

/**
 *  历史搜索的实体类  保存到数据库
 */

@Entity
public class SearchHistoryBean {
    @Id
    private Long id;
    @Property(nameInDb = "title")
    private String desc;
    @Property(nameInDb = "url")
    private String url;
    @Property(nameInDb = "time")
    private long publishedAt;
    @Generated(hash = 649301100)
    public SearchHistoryBean(Long id, String desc, String url, long publishedAt) {
        this.id = id;
        this.desc = desc;
        this.url = url;
        this.publishedAt = publishedAt;
    }
    @Generated(hash = 1570282321)
    public SearchHistoryBean() {
    }
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getDesc() {
        return this.desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public String getUrl() {
        return this.url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public long getPublishedAt() {
        return this.publishedAt;
    }
    public void setPublishedAt(long publishedAt) {
        this.publishedAt = publishedAt;
    }
}

主要逻辑是在我们的MainActivity中,接下来我们就来简单的看看EditText的监听。注释写的很详细了

etSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable editable) {
                //EditText上有文字变动时,有未发出的搜索请求,则应取消
                if(mHandler.hasMessages(SEARCH_MESSAGE)){
                    mHandler.removeMessages(SEARCH_MESSAGE);
                }
                //如果为空,直接显示搜索历史,否则,显示搜索结果
                if(TextUtils.isEmpty(editable)){
                    searchClear.setVisibility(View.GONE);
                    rlProgress.setVisibility(View.GONE);//显示加载中的提示语
                    searchResultRv.setVisibility(View.GONE);
                    //需要进一步判断,因为用户如果点击的是键盘上自带的删除键的话,会导致历史搜索的布局不隐藏
                    if(mDatas != null && mDatas.size() > 0){
                        llHistory.setVisibility(View.VISIBLE);
                    }else{
                        llHistory.setVisibility(View.GONE);
                    }
                } else {
                    if(lists != null && lists.size() > 0){//先判断之前的集合是否有数据,有的话则先清空,不然的话紧接着搜索,此时列表中还显示着上次的结果
                        lists.clear();
                        lists = null;
                    }
                    searchClear.setVisibility(View.VISIBLE);
                    rlProgress.setVisibility(View.VISIBLE);//显示加载中的提示语
                    searchResultRv.setVisibility(View.VISIBLE);
                    llHistory.setVisibility(View.GONE);
                    //延迟500ms开始搜索
                    mHandler.sendEmptyMessageDelayed(SEARCH_MESSAGE, 500);
                }
            }
        });

将数据插入数据库,当我们用电商类的搜索时,可以发现,最近搜索的记录会显示在最上面,并且当再次搜索此字段时,并不会重复添加,只是更新了时间,因为我们是按时间排序的。

private void saveDatasToDb(int position) {
        //插入数据之前先查  防止重复添加  这里查单条(一个实体)数据
        SearchHistoryBean historyBeen = historyDao.queryBuilder().where(SearchHistoryBeanDao.Properties.Desc.eq(lists.get(position).getDesc())).build().unique();
        if(historyBeen != null){
            historyDao.delete(historyBeen);//存在,则删除此条数据
        }
        bean = new SearchHistoryBean(null,lists.get(position).getDesc(),
                lists.get(position).getUrl(), Long.parseLong(TimeDifferentUtil.formatTimeDate(format,System.currentTimeMillis())));
        //historyDao.insert(bean);
        historyDao.insertOrReplace(bean);//其实这里用的是insertOrReplace  即使相同也会添加并且替换之前的
    }

我们再来看看查询数据

//先判断数据库中是否有数据,有,则显示历史记录
        historyDao = MyApplication.getDaoSession(MainActivity.this).getSearchHistoryBeanDao();
        List<SearchHistoryBean> historyBeenLists = historyDao.queryBuilder().orderDesc(SearchHistoryBeanDao.Properties.PublishedAt).build().list();
        if(historyBeenLists != null && historyBeenLists.size() > 0){
            //说明数据库中含有数据
            llHistory.setVisibility(View.VISIBLE);
            mDatas = new ArrayList<>();
            for(SearchHistoryBean bean : historyBeenLists){
                String title = bean.getDesc();
                SearchResultBean.ResultsBean resultBean = new SearchResultBean.ResultsBean();
                resultBean.setDesc(title);
                resultBean.setUrl(bean.getUrl());
                mDatas.add(resultBean);
            }
            historyAdapter = new SearchHistoryAdapter(mDatas);
            historySearchRv.setAdapter(historyAdapter);
            if(mDatas != null && mDatas.size() > 0){
                historyAdapter.addFooterView(historyFooter);
            }else{
                historyAdapter.removeFooterView(historyFooter);
            }
        }

下面给出完整的MainActivity的代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener,BaseQuickAdapter.RequestLoadMoreListener{

    public static String SEARCHURL = "http://gank.io/api/search/query/listview/category/";
    private RelativeLayout rlProgress;//提示正在加载中
    private ImageView ivBack;//返回按钮
    private EditText etSearch;
    private ImageView searchClear;//清除按钮
    private TextView tvSearch;//标题栏上面的搜索按钮
    private LinearLayout llHistory;//历史搜索的整体布局
    private RecyclerView historySearchRv;//历史搜索记录
    private SearchHistoryAdapter historyAdapter;//搜索历史的adapter
    private RecyclerView searchResultRv;//搜索结果
    private SearchResultAdapter resultAdapter;//搜索结果的adapter
    private SwipeRefreshLayout swipeRefreshLayout;
    private List<SearchResultBean.ResultsBean> lists;//数据源
    private Gson gson;

    private int currentPage = 1;//当前页
    private int pageSize = 10;
    private String format= "yyyyMMddHHmmss"; //初始化一些时间设置格式
    private SearchHistoryBeanDao historyDao;//DAO
    private SearchHistoryBean bean;
    private List<SearchResultBean.ResultsBean> mDatas;
    private View historyFooter;//添加尾部
    private TextView tvClear;//清空历史记录


    private static final int SEARCH_MESSAGE = 1;

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case SEARCH_MESSAGE:
                    //网络请求数据
                    requestNetWorkDatas();
                    break;
            }
        }
    };

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

        //初始化控件
        iniViews();
        //初始化搜索结果的adapter
        resultAdapter = new SearchResultAdapter(null);
        resultAdapter.isFirstOnly(false);
        resultAdapter.setOnLoadMoreListener(this);
        searchResultRv.setAdapter(resultAdapter);

        //先判断数据库中是否有数据,有,则显示历史记录
        historyDao = MyApplication.getDaoSession(MainActivity.this).getSearchHistoryBeanDao();
        List<SearchHistoryBean> historyBeenLists = historyDao.queryBuilder().orderDesc(SearchHistoryBeanDao.Properties.PublishedAt).build().list();
        if(historyBeenLists != null && historyBeenLists.size() > 0){
            //说明数据库中含有数据
            llHistory.setVisibility(View.VISIBLE);
            mDatas = new ArrayList<>();
            for(SearchHistoryBean bean : historyBeenLists){
                String title = bean.getDesc();
                SearchResultBean.ResultsBean resultBean = new SearchResultBean.ResultsBean();
                resultBean.setDesc(title);
                resultBean.setUrl(bean.getUrl());
                mDatas.add(resultBean);
            }
            historyAdapter = new SearchHistoryAdapter(mDatas);
            historySearchRv.setAdapter(historyAdapter);
            if(mDatas != null && mDatas.size() > 0){
                historyAdapter.addFooterView(historyFooter);
            }else{
                historyAdapter.removeFooterView(historyFooter);
            }
        }
    }

    private void iniViews() {
        rlProgress = (RelativeLayout) findViewById(R.id.rl_progress);
        ivBack = (ImageView) findViewById(R.id.search_back);
        etSearch = (EditText) findViewById(R.id.et_search);
        searchClear = (ImageView) findViewById(R.id.search_clear);
        tvSearch = (TextView) findViewById(R.id.tv_search);
        llHistory = (LinearLayout) findViewById(R.id.ll_history);
        //当历史搜索有数据时,则加载footer布局  清空历史记录
        historyFooter = LayoutInflater.from(this).inflate(R.layout.history_search_footer, null);
        tvClear = (TextView) historyFooter.findViewById(R.id.clear_tv);
        //清空历史记录
        tvClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //清空集合
                mDatas.clear();
                //清空数据库  删除所有数据
                historyDao.deleteAll();
                //实时更新UI界面,还需要隐藏掉尾布局,以及历史搜索等字样
                historyAdapter.notifyDataSetChanged();
                historyFooter.setVisibility(View.GONE);
                llHistory.setVisibility(View.GONE);
            }
        });

        ivBack.setOnClickListener(this);
        etSearch.setOnClickListener(this);
        searchClear.setOnClickListener(this);
        tvSearch.setOnClickListener(this);

        historySearchRv = (RecyclerView) findViewById(R.id.history_search_recyclerview);
        searchResultRv = (RecyclerView) findViewById(R.id.search_data_recyclerview);
        //设置展示样式
        historySearchRv.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        searchResultRv.setLayoutManager(new LinearLayoutManager(MainActivity.this));

        etSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                //EditText上有文字变动时,有未发出的搜索请求,则应取消
                if(mHandler.hasMessages(SEARCH_MESSAGE)){
                    mHandler.removeMessages(SEARCH_MESSAGE);
                }
                //如果为空,直接显示搜索历史,否则,显示搜索结果
                if(TextUtils.isEmpty(editable)){
                    searchClear.setVisibility(View.GONE);
                    rlProgress.setVisibility(View.GONE);//显示加载中的提示语
                    searchResultRv.setVisibility(View.GONE);
                    //需要进一步判断,因为用户如果点击的是键盘上自带的删除键的话,会导致历史搜索的布局不隐藏
                    if(mDatas != null && mDatas.size() > 0){
                        llHistory.setVisibility(View.VISIBLE);
                    }else{
                        llHistory.setVisibility(View.GONE);
                    }
                } else {
                    if(lists != null && lists.size() > 0){//先判断之前的集合是否有数据,有的话则先清空,不然的话紧接着搜索,此时列表中还显示着上次的结果
                        lists.clear();
                        lists = null;
                    }
                    searchClear.setVisibility(View.VISIBLE);
                    rlProgress.setVisibility(View.VISIBLE);//显示加载中的提示语
                    searchResultRv.setVisibility(View.VISIBLE);
                    llHistory.setVisibility(View.GONE);
                    //延迟500ms开始搜索
                    mHandler.sendEmptyMessageDelayed(SEARCH_MESSAGE, 500);
                }
            }
        });

        //点击搜索结果item,跳转到相应页面,并且将item上的内容保存到greendao数据库
        searchResultRv.addOnItemTouchListener(new OnItemClickListener() {
            @Override
            public void onSimpleItemClick(BaseQuickAdapter adapter, View view, int position) {
                //先将内容填充到EditText上,再跳转
                //            etSearch.setText(lists.get(position).getDesc());
                //跳转
                Intent intent = new Intent(MainActivity.this, InfoActivity.class);
                intent.putExtra("url",lists.get(position).getUrl());
                startActivity(intent);
                //保存到数据库
                saveDatasToDb(position);
                //finish
                MainActivity.this.finish();
            }
        });

        //点击历史搜索中的item  跳转到相应的页面
        historySearchRv.addOnItemTouchListener(new OnItemClickListener() {
            @Override
            public void onSimpleItemClick(BaseQuickAdapter adapter, View view, int position) {
                //先将内容填充到EditText上,再跳转
                //             etSearch.setText(mDatas.get(position).getDesc());
                //跳转
                Intent intent = new Intent(MainActivity.this, InfoActivity.class);
                intent.putExtra("url",mDatas.get(position).getUrl());
                startActivity(intent);
                //同时将此数据更新到最上面
                //插入数据之前先查  防止重复添加  这里查单条(一个实体)数据
                SearchHistoryBean historyBeen = historyDao.queryBuilder().where(SearchHistoryBeanDao.Properties.Desc.eq(mDatas.get(position).getDesc())).build().unique();
                if(historyBeen != null){
                    historyDao.delete(historyBeen);//存在,则删除此条数据
                }
                //historyDao = MyApplication.getDaoSession(SearchActivity.this).getSearchHistoryBeanDao();
                bean = new SearchHistoryBean(null,mDatas.get(position).getDesc(),
                        mDatas.get(position).getUrl(), Long.parseLong(TimeDifferentUtil.formatTimeDate(format,System.currentTimeMillis())));
                historyDao.insertOrReplace(bean);//其实这里用的是insertOrReplace  即使相同也会添加并且替换之前的
                //finish
                MainActivity.this.finish();
            }
        });
    }

    private void saveDatasToDb(int position) {
        //插入数据之前先查  防止重复添加  这里查单条(一个实体)数据
        SearchHistoryBean historyBeen = historyDao.queryBuilder().where(SearchHistoryBeanDao.Properties.Desc.eq(lists.get(position).getDesc())).build().unique();
        if(historyBeen != null){
            historyDao.delete(historyBeen);//存在,则删除此条数据
        }
        //historyDao = MyApplication.getDaoSession(SearchActivity.this).getSearchHistoryBeanDao();
        bean = new SearchHistoryBean(null,lists.get(position).getDesc(),
                lists.get(position).getUrl(), Long.parseLong(TimeDifferentUtil.formatTimeDate(format,System.currentTimeMillis())));
        //historyDao.insert(bean);
        historyDao.insertOrReplace(bean);//其实这里用的是insertOrReplace  即使相同也会添加并且替换之前的
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.search_back:
                finish();
                break;
            case R.id.search_clear:
                etSearch.setText("");
                //还需要判断
                if(mDatas != null && mDatas.size() > 0){
                    llHistory.setVisibility(View.VISIBLE);
                }else{
                    llHistory.setVisibility(View.GONE);
                }
                break;
            case R.id.tv_search:
                break;
        }
    }

    private void requestNetWorkDatas() {
        currentPage = 1;
        OkGo.get(SEARCHURL+etSearch.getText().toString().trim()+"/count/10/page/"+currentPage)
                .tag("MainActivity")
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(String s, Call call, Response response) {
                        gson = new Gson();
                        SearchResultBean searchResultBean = gson.fromJson(s, SearchResultBean.class);
                        if(!searchResultBean.isError()){
                            lists = searchResultBean.getResults();
                            if(lists != null && lists.size() > 0){
                                resultAdapter.setNewData(lists);
                            }
                        }
                    }

                    @Override
                    public void onError(Call call, Response response, Exception e) {
                        super.onError(call, response, e);
                    }

                    @Override
                    public void onBefore(BaseRequest request) {
                        super.onBefore(request);
                        //弹窗提醒正在加载中
                        rlProgress.setVisibility(View.VISIBLE);
                    }

                    @Override
                    public void onAfter(String s, Exception e) {
                        super.onAfter(s, e);
                        //关闭弹窗
                        rlProgress.setVisibility(View.GONE);
                    }
                });
    }

    @Override
    public void onLoadMoreRequested() {
        currentPage++;
        searchResultRv.postDelayed(new Runnable() {
            @Override
            public void run() {
                OkGo.get(SEARCHURL+etSearch.getText().toString().trim()+"/count/10/page/"+currentPage)
                        .tag("MainActivity")
                        .execute(new StringCallback() {
                            @Override
                            public void onSuccess(String s, Call call, Response response) {
                                gson = new Gson();
                                SearchResultBean searchResultBean = gson.fromJson(s, SearchResultBean.class);
                                if(!searchResultBean.isError()){
                                    List<SearchResultBean.ResultsBean> lists = searchResultBean.getResults();
                                    if(lists != null && lists.size() > 0){
                                        //定义接口时,我们设置的是每页显示10条数据
                                        if(lists.size() < pageSize){
                                            //请求获取到的总数据 < 每页需要显示的数据时,隐藏掉没有更多数据的提示
                                            resultAdapter.loadMoreEnd(true);//true:隐藏提示 false:显示提示
                                        }else{
                                            //                        if(mCurrentCounter >= totalCounts){//由于接口获取不到总的数据量,所以这里先注释掉
                                            //                           categoryThreeAdapter.loadMoreEnd(false);//刷新完成后,提示没有更多数据,false:提示  true:隐藏
                                            //                       }else{
                                            //注意,这里用的是addData(),在之前的数据集合后面添加下一条
                                            resultAdapter.addData(lists);
                                            //                            mCurrentCounter = categoryThreeAdapter.getData().size();
                                            //调用完成的方法  注意:加载完数据之后一定要调用完成的方法,否则不会再执行上拉刷新,这里我将刷新完成放在了请求完成方法中
                                            //                            categoryThreeAdapter.loadMoreComplete();
                                            //                        }
                                        }
                                    }else{
                                        //当上拉加载失败时,提示
                                        resultAdapter.loadMoreFail();
                                    }
                                }
                            }

                            @Override
                            public void onError(Call call, Response response, Exception e) {
                                super.onError(call, response, e);
                            }

                            @Override
                            public void onAfter(String s, Exception e) {
                                super.onAfter(s, e);
                                //最后调用结束刷新的方法
                                resultAdapter.loadMoreComplete();
                            }
                        });
            }
        }, 1000);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        OkGo.getInstance().cancelTag("MainActivity");
        mHandler.removeMessages(SEARCH_MESSAGE);
        mHandler = null;
    }
}
其实,在做的过程中还是有很多细节需要去处理的,比如说:当页面销毁时,我们要取消网络请求,同时移除handler消息等等,否则的话就会持有Activity的引用,造成内存泄漏。
点击这里下载完整代码
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值