zoukankan      html  css  js  c++  java
  • 封装RecyclerViewAdapter实现RecyclerView下拉刷新上拉载入很多其它

    实现

    关于下拉刷新使用的是github上的项目Ultra Pull To Refresh项目。
    gradle依赖例如以下:

      compile 'in.srain.cube:ultra-ptr:1.0.11'

    重点是上拉载入很多其它的实现。因为RecyclerView并不支持加入HeardView与FooterView,因此我们仅仅能自
    己实现。
    首先定义一些局部变量

    
        public static final int STATE_LOAD = 0;
        public static final int STATE_LOADING = 1;
        public static final int STATE_LOADCOMPLE = 2;
        public static final int STATE_NODATA = 3;
        private int mState = STATE_LOAD;
        private ProgressBar pb;
        private TextView tv;
        private View footView;
        public static final int TYPE_FOOT = Integer.MAX_VALUE;

    记得在原有Item数量上+1

      @Override
        public int getItemCount() {
            return super.getItemCount() + 1;
        }

    通过重写RecyclerView.Adapter的getItemViewType在列表最后返回FOOTER_TYPE。

     @Override
        public int getItemViewType(int position) {
            if(position==getItemCount()-1){
                return TYPE_FOOT;
            }else {
                return  0;
            }
        }

    在方法中onCreateViewHolder方法中通过viewType载入指定的布局。

     @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if (viewType == TYPE_FOOT) {
                footView = mInflater.inflate(R.layout.layout_footer_more, parent, false);
                tv = (TextView) footView.findViewById(R.id.tv_info);
                pb = (ProgressBar) footView.findViewById(R.id.pb);
                return new FooterHolder(footView);
            } else {
                return super.onCreateViewHolder(parent, viewType);
            }
        }

    依据不同的状态设置显示样式

     private String getTextByState() {
            String result = "上拉载入很多其它";
            pb.setVisibility(View.INVISIBLE);
            footView.setVisibility(View.VISIBLE);
            switch (mState) {
                case STATE_LOAD:
                    footView.setVisibility(View.GONE);
                    break;
                case STATE_LOADCOMPLE:
                    result = "载入完毕";
                    break;
                case STATE_LOADING:
                    result = "正在载入很多其它....";
                    pb.setVisibility(View.VISIBLE);
                    break;
                case STATE_NODATA:
                    result = "没有很多其它了";
                    break;
            }
            return result;
        }
    

    因为须要一些扩展因此将上一次封装的Adapter做了一些调整。

    package trs.com.myapp.adapter;
    
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import com.bumptech.glide.Glide;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.ParameterizedType;
    import java.util.List;
    
    import trs.com.myapp.R;
    
    /**
     * Created by zhuguohui on 2016/3/23.
     */
    public class TRSRecyclerAdapter<T, H extends RecyclerView.ViewHolder> extends RecyclerView.Adapter {
        List<T> data;
        Context context;
        protected final LayoutInflater mInflater;
        protected int layoutId;
    
        public TRSRecyclerAdapter(List<T> data, Context context, int layoutId) {
            this.data = data;
            this.layoutId = layoutId;
            this.context = context;
            mInflater = LayoutInflater.from(context);
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = mInflater.inflate(layoutId, parent, false);
            return getInstanceOfH(view);
        }
    
        H getInstanceOfH(View view) {
            ParameterizedType superClass = (ParameterizedType) getClass().getGenericSuperclass();
            Class<H> type = (Class<H>) superClass.getActualTypeArguments()[1];
            try {
                Constructor<H> constructor = type.getConstructor(View.class);
                return constructor.newInstance(view);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
    
        @Override
        public final void onBindViewHolder(RecyclerView.ViewHolder h, int position) {
            T t = data.get(position);
            bindData(t, h);
        }
    
        private void setDataToHolder(T t, RecyclerView.ViewHolder h) {
            Field[] fields = h.getClass().getDeclaredFields();
            Object o ;
            for (Field f : fields) {
                f.setAccessible(true);
                o = null;
                try {
                    o = f.get(h);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if (o instanceof TextView) {
                    TextView tv = (TextView) o;
                    Object value = getValueFromFiled(t, f.getName());
                    if (value instanceof CharSequence) {
                        tv.setText((CharSequence) value);
                    }
                } else if (o instanceof ImageView) {
                    ImageView iv = (ImageView) o;
                    Object value = getValueFromFiled(t, f.getName());
                    if (value instanceof String) {
                        String url = (String) value;
                        Glide.with(context).load(url).placeholder(R.drawable.default_pic).into(iv);
                    }
                }
    
    
            }
        }
    
        public Object getValueFromFiled(T t, String name) {
            try {
                Field hf = t.getClass().getDeclaredField(name);
                hf.setAccessible(true);
                return hf.get(t);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        public void bindData(T t, RecyclerView.ViewHolder h) {
            setDataToHolder(t, h);
        }
    
        @Override
        public int getItemCount() {
            return data == null ? 0 : data.size();
        }
    
    }
    

    这是具有载入很多其它功能的Adapter继承自TRSRecyclerAdapter:

    package trs.com.myapp.adapter;
    
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    import java.util.List;
    
    import trs.com.myapp.R;
    import trs.com.myapp.holder.TRSViewHolder;
    
    /**
     * Created by yuelin on 2016/3/28.
     */
    public class TRSMoreAdapter<T, H extends RecyclerView.ViewHolder> extends TRSRecyclerAdapter<T, H> {
    
    
        public static final int STATE_LOAD = 0;
        public static final int STATE_LOADING = 1;
        public static final int STATE_LOADCOMPLE = 2;
        public static final int STATE_NODATA = 3;
        private int mState = STATE_LOAD;
    
        private ProgressBar pb;
        private TextView tv;
        private View footView;
        public static final int TYPE_FOOT = Integer.MAX_VALUE;
    
        public TRSMoreAdapter(List<T> data, Context context, int layoutId) {
            super(data, context, layoutId);
        }
    
        @Override
        public int getItemCount() {
            return super.getItemCount() + 1;
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List payloads) {
            if (holder instanceof FooterHolder) {
                tv.setText(getTextByState());
            } else {
                super.onBindViewHolder(holder, position, payloads);
            }
        }
    
        private String getTextByState() {
            String result = "上拉载入很多其它";
            pb.setVisibility(View.INVISIBLE);
            footView.setVisibility(View.VISIBLE);
            switch (mState) {
                case STATE_LOAD:
                    footView.setVisibility(View.GONE);
                    break;
                case STATE_LOADCOMPLE:
                    result = "载入完毕";
                    break;
                case STATE_LOADING:
                    result = "正在载入很多其它....";
                    pb.setVisibility(View.VISIBLE);
                    break;
                case STATE_NODATA:
                    result = "没有很多其它了";
                    break;
            }
            return result;
        }
    
        public void setState(int state) {
            if (state != STATE_LOAD && state != STATE_LOADCOMPLE && state != STATE_LOADING && state != STATE_NODATA) {
                throw new RuntimeException("状态有误!

    "); } mState = state; notifyDataSetChanged(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == TYPE_FOOT) { footView = mInflater.inflate(R.layout.layout_footer_more, parent, false); tv = (TextView) footView.findViewById(R.id.tv_info); pb = (ProgressBar) footView.findViewById(R.id.pb); return new FooterHolder(footView); } else { return super.onCreateViewHolder(parent, viewType); } } public static class FooterHolder extends TRSViewHolder { public TextView title; public TextView time; public ImageView image; public FooterHolder(View itemView) { super(itemView); } } @Override public int getItemViewType(int position) { if(position==getItemCount()-1){ return TYPE_FOOT; }else { return 0; } } }

    而关于Adapter状态的改变,须要通过给RecyclerView加入滚动监听器实现。为了方便起见,我将这些加入监听器。设置Adapter状态统统封装在一个LoadMoreRecyclerView中。

    package trs.com.myapp.view;
    
    import android.content.Context;
    import android.support.v7.widget.GridLayoutManager;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.util.AttributeSet;
    
    import trs.com.myapp.adapter.RefreshAdapter;
    import trs.com.myapp.adapter.TRSMoreAdapter;
    
    /**
     * Created by yuelin on 2016/3/25.
     */
    public class LoadMoreRecyclerView extends RecyclerView {
        private TRSMoreAdapter refreshAdapter;
    
    
        public LoadMoreRecyclerView(Context context) {
            this(context, null);
        }
    
        public LoadMoreRecyclerView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public LoadMoreRecyclerView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            setOnScrollListener(null);
        }
    
    
        @Override
        public void setOnScrollListener(OnScrollListener listener) {
            LoadMoreListener loadMoreListener = new LoadMoreListener(listener);
            super.setOnScrollListener(loadMoreListener);
        }
    
        public interface OnLoadMoreListener {
            void OnLoad();
        }
    
        OnLoadMoreListener mOnloadmoreLister = null;
    
        public void SetOnLoadMoreLister(OnLoadMoreListener listener) {
            mOnloadmoreLister = listener;
        }
    
        private class LoadMoreListener extends OnScrollListener {
            private OnScrollListener listener;
            private int lastVisibleItem;
    
            public LoadMoreListener(OnScrollListener listener) {
                this.listener = listener;
            }
    
            @Override
            public void onScrollStateChanged(RecyclerView view, int newState) {
                if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == getAdapter().getItemCount()) {
                    if (mOnloadmoreLister != null && haveData) {
                        refreshAdapter.setState(RefreshAdapter.STATE_LOADING);
                        mOnloadmoreLister.OnLoad();
                    }
                }
    
                if (listener != null) {
                    listener.onScrollStateChanged(view, newState);
                }
            }
    
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            //注意:因为findLastVisibleItemPosition方法眼下没有在LayoutManger中声明为抽象方法。因此不同直接通过LayoutManager调用。
                if (getLayoutManager() instanceof LinearLayoutManager) {
                    LinearLayoutManager lm = (LinearLayoutManager) getLayoutManager();
                    lastVisibleItem = lm.findLastVisibleItemPosition();
                } else if (getLayoutManager() instanceof GridLayoutManager) {
                    GridLayoutManager gm = (GridLayoutManager) getLayoutManager();
                    lastVisibleItem = gm.findLastVisibleItemPosition();
                }
    
                if (listener != null) {
                    listener.onScrolled(recyclerView, dx, dy);
                }
            }
        }
    
    
        @Override
        public void setAdapter(Adapter adapter) {
            if(!(adapter instanceof TRSMoreAdapter)){
                throw new IllegalArgumentException("请使用TRSMoreAdapter");
            }
            refreshAdapter = (TRSMoreAdapter) adapter;
            super.setAdapter(refreshAdapter);
        }
    
        private boolean haveData = true;
    
        public void loadComplete(final boolean haveData) {
            this.haveData = haveData;
            if (!haveData) {
                refreshAdapter.setState(RefreshAdapter.STATE_NODATA);
            } else {
                refreshAdapter.setState(RefreshAdapter.STATE_LOAD);
            }
    
        }
    
    }
    

    使用

    1.自己定义adpater继承自TRSMoreAdapter

    package trs.com.myapp.adapter;
    
    import android.content.Context;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import java.util.List;
    
    import trs.com.myapp.R;
    import trs.com.myapp.bean.NewsItem;
    import trs.com.myapp.holder.TRSViewHolder;
    
    /**
     * Created by zhuguohui on 2016/3/23.
     */
    public class NewsAdapter1 extends TRSMoreAdapter<NewsItem,NewsAdapter1.NewsViewHolder> {
    
    
        public NewsAdapter1(List<NewsItem> data, Context context) {
            super(data, context, R.layout.item_news_layout);
        }
    
        public static class NewsViewHolder extends TRSViewHolder{
            public TextView title;
            public TextView time;
            public ImageView image;
            public NewsViewHolder(View itemView) {
                super(itemView);
            }
        }
    }
    

    2.使用
    LoadMoreRecyclerView 进行布局

    <?

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

    > <in.srain.cube.views.ptr.PtrFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ptr_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:gravity="center" android:orientation="vertical"> <trs.com.myapp.view.LoadMoreRecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" /> </in.srain.cube.views.ptr.PtrFrameLayout>

    3.设置Adapter与载入很多其它监听器

    //注意adpater必须是基础自TRSMoreAdapter
     recyclerView.setAdapter(adapter);
       recyclerView.SetOnLoadMoreLister(new LoadMoreRecyclerView.OnLoadMoreListener() {
                @Override
                public void OnLoad() {
                    pageIndex++;
                    loadData(pageIndex);
                }
            });

    4.完毕时调用:

     if (recyclerView != null) {
                recyclerView.loadComplete(!error&&haseMore);
          }

    效果

    这里写图片描写叙述

  • 相关阅读:
    EVM靶机渗透
    Joomla漏洞复现
    渗透测试
    Kali软件库认识
    谷歌hack语法
    Metasploit学习
    sqli-labs less-17
    sqli-labs(less-11-16)
    sqli-labs (less-8-less-10)
    less-7
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7116271.html
Copyright © 2011-2022 走看看