RecyclerViewドロップダウン・リフレッシュとアップロード


前言
従来の記事では、RecyclerView追加headerfooterをどのように使用するかについて言及しましたが、今日はRecyclerViewを使用して、一般的なドロップダウン・リフレッシュとアップロードのより多くの機能を実現するために、より深く拡張してみましょう.もちろんこれらの機能の実現も、前のRecyclerViewにヘッダとfooterを追加したことに基づいて実現されており、よく分からないので、前の文章を見ておくと理解がよくなるかもしれません.
に頼る
皆さんの使用方法のために私はすでに彼をJcenterにアップロードしましたので、皆さんは次のコードを呼び出して直接使用することができます.
compile 'com.idisfkj.enchancerecyclerview:mylibrary:1.1.1'

EnhanceRecyclerView
この拡張RecyclerViewEnhanceRecyclerViewと命名し、RecyclerViewを継承します.ドロップダウン・リフレッシュとアップ・アップを実現するには、頭と尾のレイアウトを実現する必要があることを知っています.そのため、私たちは先に前の知識を利用してEnhanceRecycleViewheaderfooterを追加します.
public void initView() {
        View headerView = LayoutInflater.from(getContext()).inflate(R.layout.head_layout, null);
        View footerView = LayoutInflater.from(getContext()).inflate(R.layout.footer_layout, null);
        addHeaderView(headerView);
        addFooterView(footerView);
    }

その中のレイアウトファイルは多く言わないで、addHeaderViewとaddFooterViewの方法は私の前の文章を見ることができて、詳しい紹介があります
Listenerの設定
ドロップダウン・リフレッシュとアップロードを実現するためには、当然、リスナーに対する処理が欠かせないので、以下では、リスナーOnScrollListenerOnTouchListenerの処理について詳しく説明する.
OnScrollListener EnhanceRecyclerViewaddOnScrollListenerを追加し、onScrollStateChangedonScrolledメソッドを実装します.
onScrolled onScrolledでは、EnhanceRcyclerViewの合計数、ビュー表示の最初のitemitemの位置、およびビュー表示の最後のEnhanceRecyclerViewitemの位置を取得します.EnhanceRecyclerViewの合計数については、ダイレクトコールを取得するのに便利です.
totalCount = getLayoutManager().getItemCount();
itemRecyclerViewLinearLayoutManagerGridLayoutManagerのレイアウトが異なるため、他の2つは異なるStaggeredGridLayoutManagerによって取得されるので、具体的なコードを見てみましょう.
if (getLayoutManager() instanceof LinearLayoutManager) {
                    lastItem = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
                    firstVisible = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
                } else {
                    into = ((StaggeredGridLayoutManager) getLayoutManager()).findLastVisibleItemPositions(into);
                    firstInto = ((StaggeredGridLayoutManager) getLayoutManager()).findFirstVisibleItemPositions(firstInto);
                    lastItem = into[0];
                    firstVisible = firstInto[0];
                }

onScrollStateChanged
その3つの重要なデータを取得すると、managerで具体的な論理を実現することができ、この方法では主にアップロードに対するより多くの処理を実現する.
if (lastItem == adapter.getItemCount() + 1 && newState == RecyclerView.SCROLL_STATE_IDLE && !isLoad) {
                    ViewGroup.LayoutParams params = getFooterView(0).getLayoutParams();
                    params.width = RecyclerView.LayoutParams.MATCH_PARENT;
                    params.height = RecyclerView.LayoutParams.WRAP_CONTENT;
                    getFooterView(0).setLayoutParams(params);
                    getFooterView(0).setVisibility(View.VISIBLE);
                    smoothScrollToPosition(totalCount);
                    isLoad = true;
                    loadMoreListener.onLoadMore();
                }
                if (firstVisible == 0) {
                    isTop = true;
                } else {
                    isTop = false;
                    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams();
                    params.width = RecyclerView.LayoutParams.MATCH_PARENT;
                    params.height = RecyclerView.LayoutParams.WRAP_CONTENT;
                    params.setMargins(0, -getHeaderView(0).getHeight(), 0, 0);
                    getHeaderView(0).setLayoutParams(params);
                }

簡単に説明すると、コアはonScrollStateChangedが最後の位置にあるかどうかを判断し、もしそうであればより多くの操作をロードし続けることであり、ここではデータ処理に対するインタフェースを提供するのでlastItemを実現すればよい.
より多くのコアをアップロードすると、他のソースコードを表示できます.
OnTouchListener
このリスナーは主にドロップダウン・リフレッシュを処理します.私たちは、その中でよく知られているloadMoreListener.onLoadMore();MotionEvent.ACTION_DOWNMotionEvent.ACTION_MOVEをそれぞれ処理します.MotionEvent.ACTION_UPは、押下された座標位置を簡単に取得するものであり、ここではあまり説明しないが、以下、主に他の2つについて簡単に説明する.
ACTION_MOVE
これは,タッチ後の処理に対して,スライド距離に応じてACTION_DOWNのテキストとレイアウトビューの表示を動的に変更する論理である.
public void touchMove(MotionEvent event) {
        endY = event.getY();
        moveY = endY - startY;
        //  item    
        if (moveY > 0 && !isRefreshing) {
            //          
            scrollToPosition(0);

            if (getHeaderView(0).getVisibility() == GONE)
                getHeaderView(0).setVisibility(VISIBLE);

            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams();
            params.width = RecyclerView.LayoutParams.MATCH_PARENT;
            params.height = RecyclerView.LayoutParams.WRAP_CONTENT;
            // header moveY         
            if (moveY >= 400) {
                moveY = 100 + moveY / 4;
            } else {
                moveY = moveY / 2;
            }
            viewHeight = getHeaderView(0).getHeight();
            if (viewHeight <= 0)
                viewHeight = 130;
            moveY = moveY - viewHeight;
            params.setMargins(0, (int) moveY, 0, 0);
            getHeaderView(0).setLayoutParams(params);
            if (moveY > 80) {
                text.setText(getResources().getString(R.string.release_to_refresh));
            } else {
                text.setText(getResources().getString(R.string.pull_to_refresh));
            }
        } else {
            if (getHeaderView(0).getVisibility() != GONE && !isRefreshing) {
                getHeaderView(0).setVisibility(GONE);
            }
        }
    }

ドロップダウン時の上部からの距離の変化は、headerを設定することによって動的に変化する.
ACTION_UP
最後のタッチ処理は、画面を離れる際にスライドの距離に応じて、データをロードするインタフェースを呼び出すか、ドロップダウン・リフレッシュ・ヘッダを隠すか、具体的にはコードを見てみましょう.
public void touchUp() {
        if (!isRefreshing && (endY -startY) != 0 ) {

            RecyclerView.LayoutParams params1 = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams();
            params1.width = RecyclerView.LayoutParams.MATCH_PARENT;
            params1.height = RecyclerView.LayoutParams.WRAP_CONTENT;

            if (moveY >= 80) {
                text.setText(getResources().getString(R.string.refreshing));
                params1.setMargins(0, 0, 0, 0);
                isRefreshing = true;
                //    
                pullToRefresh.onRefreshing();
            } else {
                if (viewHeight <= 0)
                    viewHeight = 130;
                params1.setMargins(0, -viewHeight, 0, 0);
                getHeaderView(0).setVisibility(GONE);
            }
            getHeaderView(0).setLayoutParams(params1);
        }
    }

コードの中で重要な点はすべて信じることができてすべて理解することができることを指摘して、このようにプルダウンと引き延ばすロジックは基本的に実現して、次にインタフェースの設計を見てみましょう
プルダウンとプルアップインタフェース
public interface PullToRefreshListener {
        void onRefreshing();
    }

    public void setPullToRefreshListener(PullToRefreshListener pullToRefresh) {
        if (loadMoreListener == null) {
            initListener();
        }
        this.pullToRefresh = pullToRefresh;
    }

    public interface LoadMoreListener {
        void onLoadMore();
    }

    public void setLoadMoreListener(LoadMoreListener loadMoreListener) {
        if (pullToRefresh == null) {
            initListener();
        }
        this.loadMoreListener = loadMoreListener;
    }

インタフェース傍受を追加する場合に、前にmarginに設定された傍受を初期化します.
ステータスリセット設定
呼び出しのドロップダウン・リフレッシュまたはアップロードがより多くなった後、一般的な方法を構築して実現し、状態のリセットとデータの更新を行い、呼び出しを統一するのに便利です.
 public void setLoadMoreComplete() {
        RecyclerView.LayoutParams params = (LayoutParams) getFooterView(0).getLayoutParams();
        params.width = 0;
        params.height = 0;
        getFooterView(0).setLayoutParams(params);
        getFooterView(0).setVisibility(View.GONE);
        this.getAdapter().notifyDataSetChanged();
        isLoad = false;
    }

    public void setRefreshComplete() {
        RecyclerView.LayoutParams params1 = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams();
        params1.width = RecyclerView.LayoutParams.MATCH_PARENT;
        params1.height = RecyclerView.LayoutParams.WRAP_CONTENT;
        params1.setMargins(0, -getHeaderView(0).getHeight(), 0, 0);
        getHeaderView(0).setLayoutParams(params1);
        getHeaderView(0).setVisibility(GONE);
        this.getAdapter().notifyDataSetChanged();
        isRefreshing = false;
    }

使用した作業は完了しました.次に呼び出しの例を示します.
使用
xmlでの参照


リスニングの設定
 mRecyclerView.setPullToRefreshListener(new com.idisfkj.mylibrary.EnhanceRecyclerView.PullToRefreshListener() {
            @Override
            public void onRefreshing() {
                refreshData();
            }
        });
        mRecyclerView.setLoadMoreListener(new EnhanceRecyclerView.LoadMoreListener() {
            @Override
            public void onLoadMore() {
                loadMoreData();
            }
        });
EnhanceRecyclerViewおよびrefreshData()データをロードする論理は示されないが、ネットワークデータを要求した後、対応するloadMoreData()およびmRecyclerView.setRefreshComplete()を呼び出して状態をリセットすることを覚えておく必要がある.その他の mRecyclerView.setLoadMoreComplete()Adapterなどの設定は多くは言わないが、原生のLayoutManagerと同じである.
効果
まとめ
実は全体的に難点は2つあります
  • 追加RecyclerViewheaderです.この先はすでに攻略して、しかも原理も比較的に簡単です
  • タッチおよびスライドリスニングロジックを実現する.これは主に論理的な理解であり,リフレッシュの過程全体を全体的に分析することで,上のコードをよく理解することができる.ビューのダイナミック表示に応じてインタフェースの呼び出しに応じて、これらのエンジニアリングをうまく処理できます.

  • もちろん上の実現には瑕疵があるかもしれませんが、指摘してほしいのは、私はそれに応じて修正するか、あなたたちが修正した後に私に提出することができます.私は統一して修正します.ありがとうございます.
    プロジェクトのアドレス:https://github.com/idisfkj/En...個人ブログ:https://idisfkj.github.io/arc...
    に注目