高级UI

Android上拉加载更多和下拉刷新

2019-08-14  本文已影响0人  番茄tomato

采用SmartRefreshLayout来实现上拉刷新和下拉加载更多:
参考:
https://github.com/scwang90/SmartRefreshLayout
https://www.jianshu.com/p/8717f73c1b88

gradle中导入SmartRefreshLayout库:

//添加smartrefresh 用于上拉请求更多和下拉刷新

 //(1.0.5及以前版本的老用户升级需谨慎,API改动过大)

    implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' 

//没有使用特殊Header,可以不加这行

    implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0'  

布局文件中添加SmartRefreshLayout,在其中添加recycleview

<com.scwang.smartrefresh.layout.SmartRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/refreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        tools:listitem="@layout/item_news"
        />

</com.scwang.smartrefresh.layout.SmartRefreshLayout>

activity中 声明出data,adapter等等:

    @BindView(R.id.recyclerView)

    RecyclerView mRecyclerView;

    @BindView(R.id.refreshLayout)

    SmartRefreshLayout refreshLayout;

    RecyclerView.Adapter mAdapter;

    List<NewsBean.ResultBean> mData=null;

首先,自定义方法初始化recycleview:

    void  initRecycleView(){//初始化RecycleView

        mData=new ArrayList<>();

        mAdapter = new NewsAdapter(mData);//那边adapter接收的bean的list

        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mRecyclerView.setAdapter(mAdapter);

    }

然后初始化RefreshLayout:

        //设置加载头和脚样式 不同样式已经封装在资源文件里了
//按CTRL进入WaterDropHeader同一个包下边选择
        refreshLayout.setRefreshHeader(new WaterDropHeader(this));
        refreshLayout.setRefreshFooter(new ClassicsFooter(this));
    void initRefreshLayout() {

        refreshLayout.setOnRefreshListener(new OnRefreshListener() {

            @Override

            public void onRefresh(RefreshLayout refreshlayout) {

                mPresenter.getNews(page, true);

                refreshlayout.finishRefresh(2000/*,false*/);//传入false表示刷新失败

            }

        });

        refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {

            @Override

            public void onLoadMore(RefreshLayout refreshlayout) {

                mPresenter.getNews(page, false);//请求下一页

                refreshlayout.finishLoadMore(2000/*,false*/);//传入false表示加载失败

            }

        });

    }

以上两个方法在initData中调用:

    @Override

    public void initData(@Nullable Bundle savedInstanceState) {

        initRefreshLayout();

        initRecycleView();

        mPresenter.getNews(page, true);//第一次进入activity请求数据

    }

然后分别实现showmsg和showMoreMsg方法:

    @Override

    public void showData(NewsBean newsBean) {//刷新或者第一次显示进入 显示数据

        mData.clear();

        mData.addAll(newsBean.getResult());

        mAdapter.notifyDataSetChanged();//宣布数据发生变化 适配器重新适配

    }

    @Override

    public void showMoreData(NewsBean newsBean) {//加载更多 显示数据

        mData.addAll(newsBean.getResult());

        mAdapter.notifyDataSetChanged();

    }

重点:
mAdapter.notifyDataSetChanged();
这里宣布数据作出改变 适配器自动重新填充数据
(不要再傻乎乎的回调了 对我自己说)

以下为完整代码(只有activity和adapter,,其他的P层和M层的东西 就不拿出来了 另外附带一个图片加载)

activity

package safetytaxfree.de.myweather.mvp.ui.activity;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.jess.arms.base.BaseActivity;
import com.jess.arms.di.component.AppComponent;
import com.jess.arms.utils.ArmsUtils;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;


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

import butterknife.BindView;
import safetytaxfree.de.myweather.di.component.DaggerNewsComponent;
import safetytaxfree.de.myweather.mvp.contract.NewsContract;
import safetytaxfree.de.myweather.mvp.model.entity.NewsBean;
import safetytaxfree.de.myweather.mvp.presenter.NewsPresenter;

import safetytaxfree.de.myweather.R;
import safetytaxfree.de.myweather.mvp.ui.adapter.NewsAdapter;


import static com.jess.arms.utils.Preconditions.checkNotNull;


/**
 * ================================================
 * Description:
 * <p>
 * Created by MVPArmsTemplate on 08/14/2019 10:39
 * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
 * <a href="https://github.com/JessYanCoding">Follow me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms/wiki">See me</a>
 * <a href="https://github.com/JessYanCoding/MVPArmsTemplate">模版请保持更新</a>
 * ================================================
 */
public class NewsActivity extends BaseActivity<NewsPresenter> implements NewsContract.View {

    @BindView(R.id.recyclerView)
    RecyclerView mRecyclerView;
    @BindView(R.id.refreshLayout)
    SmartRefreshLayout refreshLayout;
    RecyclerView.Adapter mAdapter;
    List<NewsBean.ResultBean> mData=null;


    int page = 0;//第0页为随机的东西 从第二页开始
    @Override
    public void setupActivityComponent(@NonNull AppComponent appComponent) {
        DaggerNewsComponent //如找不到该类,请编译一下项目
                .builder()
                .appComponent(appComponent)
                .view(this)
                .build()
                .inject(this);
    }

    @Override
    public int initView(@Nullable Bundle savedInstanceState) {
        return R.layout.activity_news; //如果你不需要框架帮你设置 setContentView(id) 需要自行设置,请返回 0
    }

    @Override
    public void initData(@Nullable Bundle savedInstanceState) {
        initRefreshLayout();
        initRecycleView();
        mPresenter.getNews(page, true);//第一次进入activity请求数据
    }

    void  initRecycleView(){//初始化RecycleView
        mData=new ArrayList<>();
        mAdapter = new NewsAdapter(mData);//那边adapter接收的bean的list
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(mAdapter);
    }




    void initRefreshLayout() {
        //设置加载头和脚样式
        refreshLayout.setRefreshHeader(new WaterDropHeader(this));
        refreshLayout.setRefreshFooter(new ClassicsFooter(this));
        refreshLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(RefreshLayout refreshlayout) {

                mPresenter.getNews(page, true);

                refreshlayout.finishRefresh(2000/*,false*/);//传入false表示刷新失败
            }
        });
        refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore(RefreshLayout refreshlayout) {
                mPresenter.getNews(page, false);//请求下一页
                refreshlayout.finishLoadMore(2000/*,false*/);//传入false表示加载失败
            }
        });
    }


    @Override
    public void showData(NewsBean newsBean) {//刷新或者第一次显示进入 显示数据
        mData.clear();
        mData.addAll(newsBean.getResult());
        mAdapter.notifyDataSetChanged();//宣布数据发生变化 适配器重新适配
    }


    @Override
    public void showMoreData(NewsBean newsBean) {//加载更多 显示数据
        mData.addAll(newsBean.getResult());
        mAdapter.notifyDataSetChanged();
    }


    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }

    @Override
    public void showMessage(@NonNull String message) {
        checkNotNull(message);
        ArmsUtils.snackbarText(message);
    }

    @Override
    public void launchActivity(@NonNull Intent intent) {
        checkNotNull(intent);
        ArmsUtils.startActivity(intent);
    }

    @Override
    public void killMyself() {
        finish();
    }


}

adapter

package safetytaxfree.de.myweather.mvp.ui.adapter;

import android.support.annotation.NonNull;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.jess.arms.base.BaseHolder;
import com.jess.arms.base.DefaultAdapter;
import com.jess.arms.di.component.AppComponent;
import com.jess.arms.http.imageloader.ImageLoader;
import com.jess.arms.http.imageloader.glide.ImageConfigImpl;
import com.jess.arms.utils.ArmsUtils;


import java.util.List;

import butterknife.BindView;
import safetytaxfree.de.myweather.R;
import safetytaxfree.de.myweather.mvp.model.entity.NewsBean;

public class NewsAdapter extends DefaultAdapter<NewsBean.ResultBean> {


    public NewsAdapter(List<NewsBean.ResultBean> infos) {
        super(infos);
    }

    @NonNull
    @Override
    public BaseHolder<NewsBean.ResultBean> getHolder(@NonNull View v, int viewType) {
        return new NewsItemHolder(v);//返回holder
    }

    @Override
    public int getLayoutId(int viewType) {//设置item的layout
        return R.layout.item_news;
    }


    class NewsItemHolder extends BaseHolder<NewsBean.ResultBean> {

        @BindView(R.id.news_img)
        ImageView news_img;
        @BindView(R.id.news_title)
        TextView news_title;
        //图片的请求和缓存
        private ImageLoader mImageLoader;
        private AppComponent mAppComponent;

        public NewsItemHolder(View itemView) {
            super(itemView);
            mAppComponent = ArmsUtils.obtainAppComponentFromContext(itemView.getContext());
            mImageLoader = mAppComponent.imageLoader();
        }

        @Override
        public void setData(@NonNull NewsBean.ResultBean data, int position) {
            news_title.setText(data.getText());
            //itemView 的 Context 就是 Activity, Glide 会自动处理并和该 Activity 的生命周期绑定
            String imgUrl = (String) data.getImages();
            //String imgUrl="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png";
/*            将http替换为https
if (imgUrl .startsWith("http:")){
                imgUrl=imgUrl.replace("http:","https:");
            }*/
            mImageLoader.loadImage(itemView.getContext(),
                    ImageConfigImpl
                            .builder()
                            .url(imgUrl)
                            .imageView(news_img)
                            .build());
//data.getHeader()
        }

        @Override
        protected void onRelease() {//刷新
            //只要传入的 Context 为 Activity, Glide 就会自己做好生命周期的管理, 其实在上面的代码中传入的 Context 就是 Activity
            //所以在 onRelease 方法中不做 clear 也是可以的, 但是在这里想展示一下 clear 的用法
            mImageLoader.clear(mAppComponent.application(), ImageConfigImpl.builder()
                    .imageViews(news_img)
                    .build());
            this.news_img = null;
            this.news_title = null;
            this.mAppComponent = null;
            this.mImageLoader = null;
        }
    }

}

上一篇下一篇

猜你喜欢

热点阅读