Android RecyclerView+SwipeRefreshLayoutページング、ドロップダウン・リフレッシュ

9383 ワード

RecyclerViewが登場してからしばらく経ち、support-v 7をインポートして使用できます.
公式には、このコントロールは限られたウィンドウで大量のデータセットを表示するために使用されています.
実はこのような機能のコントロールはよく知られていません.例えば、ListView、GridViewです.
ではListView、GridViewがあるのになぜRecyclerViewのようなコントロールが必要なのでしょうか.
全体的にRecyclerViewアーキテクチャを見ると、挿抜式の体験を提供し、高度なデカップリング、異常な柔軟性を提供します.
提供する異なるLayoutManagerを設定することで、
ItemDecoration、ItemAnimatorは非常に素晴らしい効果を実現します.
表示を制御するには
レイアウトマネージャLayoutManagerでItem間の間隔(描画可能)を制御してください.
ItemDecorationでItemを削除するアニメーションを制御してください.
ItemAnimatorでクリックをコントロールしたり、イベントを長押ししたりして、自分で実現してください....
実現は非常に簡単です
レイアウトファイル:
RecyclerViewで小包SwipeRefreshLayout


        
    

RefreshRecyclerView(カスタムビュー)
public class RefreshRecyclerView extends RecyclerView {

    private AutoLoadAdapter autoLoadAdapter;

    public RefreshRecyclerView(Context context) {
        this(context, null);
    }

    public RefreshRecyclerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RefreshRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private boolean isLoadingMore = false;//        
    private OnLoadMoreListener loadMoreListener;//      
    private boolean loadMoreEnable = false;//        
    private int footerResource = -1;//   
    private boolean footer_visible = false;//       
    private void init() {
        setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

                if (getAdapter() != null && getLayoutManager() != null) {
                    int lastVisiblePosition = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
                    int itemCount = getAdapter().getItemCount();
                    /**
                     *         
                     * itemCount != 0         
                     * lastVisiblePosition + 4 >= itemCount - 1     +4 >=         
                     * distanceY < 0          
                     */
                    if (distanceY < 0 && itemCount != 0 && lastVisiblePosition + 4 >= itemCount - 1 && !isLoadingMore && loadMoreEnable) {
                        Log.i("test","    ");
                        //      
                        loading();
                        if (footerResource != -1){//    
                            //     
                            footer_visible = true;
                            getAdapter().notifyItemChanged(itemCount - 1);
                        }
                        if (loadMoreListener != null) {
                            loadMoreListener.loadMoreListener();
                        }
                    }
                }
            }
        });
    }

    /**
     *       
     */
    private float distanceY = 0;
    float startY = 0;
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        float y = ev.getRawY();
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                startY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                distanceY = y - startY;
                startY = y;
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public void setAdapter(Adapter adapter) {
        SlideInBottomAnimationAdapter slideInBottomAnimationAdapter = new SlideInBottomAnimationAdapter(adapter);
        slideInBottomAnimationAdapter.setDuration(600);
        autoLoadAdapter = new AutoLoadAdapter(slideInBottomAnimationAdapter);//    
        super.setAdapter(autoLoadAdapter);
    }

    /**
     *           
     *
     * @param isEnable
     */
    public void setLoadMoreEnable(boolean isEnable) {
        this.loadMoreEnable = isEnable;
    }

    /**
     *      
     */
    public void setFooterResource(int footerResource) {
        this.footerResource = footerResource;
    }


    /**
     *     
     */
    private void loadMoreComplete() {
        this.isLoadingMore = false;
    }

    /**
     *     
     */
    private void loading(){
        this.isLoadingMore = true;//      
    }

    /**
     *         
     *
     * @param listener
     */
    public void setOnLoadMoreListener(OnLoadMoreListener listener) {
        this.loadMoreListener = listener;
    }

    public interface OnLoadMoreListener {
        void loadMoreListener();//    
    }


    /**
     *     
     */
    public void notifyData() {
        if (getAdapter() != null) {
            loadMoreComplete();
            if(footerResource != -1 && loadMoreEnable){
                //     
                footer_visible = false;
            }
            getAdapter().notifyDataSetChanged();

        }
    }

    public class AutoLoadAdapter extends Adapter {
        private Adapter dataAdapter;//  adapter
        private final int TYPE_FOOTER = Integer.MAX_VALUE;//    

        public AutoLoadAdapter(Adapter adapter) {
            this.dataAdapter = adapter;
        }

        @Override
        public int getItemViewType(int position) {
            if (position == getItemCount() - 1 && loadMoreEnable && footerResource != -1 && footer_visible) {
                return TYPE_FOOTER;
            }
            if (dataAdapter.getItemViewType(position) == TYPE_FOOTER) {
                throw new RuntimeException("adapter itemType   :" + Integer.MAX_VALUE);
            }
            return dataAdapter.getItemViewType(position);

        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            ViewHolder holder = null;
            if (viewType == TYPE_FOOTER) {//  
                holder = new FooterViewHolder(LayoutInflater.from(getContext()).inflate(footerResource, parent, false));
            } else {//  
                holder = dataAdapter.onCreateViewHolder(parent, viewType);
            }
            return holder;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            int itemViewType = getItemViewType(position);
            if (itemViewType != TYPE_FOOTER) {
                dataAdapter.onBindViewHolder(holder, position);
            }
        }

        @Override
        public int getItemCount() {
            if (dataAdapter.getItemCount() != 0) {
                int count = dataAdapter.getItemCount();
                if (loadMoreEnable && footerResource != -1 && footer_visible) {
                    count++;
                }
                return count;
            }
            return 0;
        }

        public class FooterViewHolder extends ViewHolder {

            public FooterViewHolder(View itemView) {
                super(itemView);
            }
        }

    }

}

Activity:
        mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_red_light, android.R.color.ho        lo_blue_light, android.R.color.holo_green_light);
        recyclerView.setLoadMoreEnable(true);//      
        recyclerView.setFooterResource(R.layout.item_footer);//     
        recyclerView.setOnLoadMoreListener(new RefreshRecyclerView.OnLoadMoreListener() {
            @Override
            public void loadMoreListener() {
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < 10; i++) {
                            statisticsResponseModel = new StatisticsResponseModel();
                            statisticsResponseModel.setName("OK" + i);
                            mList.add(statisticsResponseModel);
                        }
                        mRefreshAdapter.setmList(mList);
                        recyclerView.notifyData();//    
                    }
                }, 5000);
            }
        });//  
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mSwipeRefreshLayout.setRefreshing(false);
                        recyclerView.notifyData();//    
                    }
                }, 2000);
            }
        });
    }//    

gradleファイルの追加:
 compile 'jp.wasabeef:recyclerview-animators:1.3.0'

質問連絡:1808418098(微信、QQ)