RecyclerViewシリーズ(2)プルダウンリフレッシュ、プルアップロード、アイテムクリックモニタリング

RecyclerViewプルダウンの更新、プルアップの読み込み、アイテムのクリックの監視

プルダウンして更新し、プルアップしてさらにロードします。SmartRefreshLayoutを使用し
て、さまざまなコントロールサポートし、ロードスタイルをカスタマイズすることをお勧めします...
アドレス:https//github.com/scwang90/SmartRefreshLayout

効果画像:

エフェクト画像

注:アイテムクリック効果は追加されていないため、デモンストレーションはトーストの最初にクリックされたアイテムのみであり、視覚的には表示されません。子供用の靴はコードをコピーして、自分で効果を試すことができます。

実施原則

  1. プルダウンリフレッシュ: Googleの公式v4パッケージのSwipeRefreshLayout、データプルダウンリフレッシュ操作に使用されます。
  2. プルアップしてさらに読み込む:「RecyclerViewシリーズ(1)」でFootViewをRecyclerView追加する方法を採用し、現在の画面で最後に表示されているアイテムの下部の位置がRecyclerViewの下部の位置と等しいかどうかを監視します。等しい場合は、下にスライドすると、FootViewも表示されます。したがって、より多くのデータがロードされます。
  3. アイテムクリックイベント:
    (A)使用するアダプタで** OnItemClickListenerインターフェイスを構築し、インターフェイスが実装できるメソッドを設定しますvoid OnItemClick(View view、int position、String url);
    (B )onCreateViewHolder()アイテムレイアウト生成します表示時にビューのクリックリスナーsetOnClickListener(this)を設定してから、アダプターにクリックイベントリスナーを実装させます。
    (C)onBindViewHolder()メソッドタグをholder.itemView設定して、データを伝送できるようにします。(D)実施の内部メソッド設定OnItemClickListenerのOnClick(){}実装します。

コードリスト:

アダプターコードの内容

package adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.zpf.animmenu.R;

import java.util.ArrayList;

/**
 * 下拉刷新,上拉加载更多,ItemClickListener
 */

public class RvAdapterItemClick extends RecyclerView.Adapter<RvAdapterItemClick.ItemClickViewHolder>
        implements View.OnClickListener{
    
    

    private final int TYPE_FOOT = -1;
    private final int TYPE_ITEM = 0;
    /**
     * 规定每次加载更多返回数据为10条,如果数据count < 10则说明没有更多数据了,反之则有更多数据
     * */
    private final int COUNT_LOAD_MORE = 10;

    private Context mContext;
    private ArrayList<String> strings = new ArrayList<>();
    private OnItemClickListener listener;
    private View footView;
    /**
     * 用来记录RecyclerView是否正在加载数据,防止多次请求数据
     * */
    private boolean isLoading = false;
    /**
     * 记录是否还有更多数据,用来设置Foot——View显示与否
     * */
    private boolean hasMoreData = false;

    public RvAdapterItemClick(Context context) {

        this.mContext = context;
    }

    public boolean isLoading() {
        return isLoading;
    }

    public void setLoading(boolean loading) {
        isLoading = loading;
    }

    @Override
    public void onClick(View view) {

        if (listener != null) {

            listener.OnItemClick(view, (Integer) view.getTag(R.id.iv_item_head_foot),
                    (String) view.getTag(R.layout.item_head_foot_rv));
        }
    }


    public interface OnItemClickListener{
    
    

        void OnItemClick(View view, int position, String url);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {

        this.listener = listener;
    }

    public void setModels(ArrayList<String> strings) {

        if (strings != null && !strings.isEmpty()) {

            this.strings = strings;
            hasMoreData = !(strings.size() < COUNT_LOAD_MORE);
            notifyDataSetChanged();
        }
    }

    public void appendModels(ArrayList<String> strings) {

        if (strings != null && !strings.isEmpty()) {

            this.strings.addAll(strings);
            hasMoreData = !(strings.size() < COUNT_LOAD_MORE);

        } else
            hasMoreData = false;

        setFootView(hasMoreData);

        notifyDataSetChanged();
    }

    @Override
    public int getItemViewType(int position) {
        return position == strings.size() ? TYPE_FOOT : TYPE_ITEM;
    }

    @Override
    public ItemClickViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

        View view;
        if (viewType == TYPE_FOOT) {

            view = footView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_foot_rv, viewGroup, false);
            setFootView(hasMoreData);

        } else {

            view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_head_foot_rv, viewGroup, false);
            view.setOnClickListener(this);

        }
        return new ItemClickViewHolder(view, viewType);
    }

    @Override
    public void onBindViewHolder(ItemClickViewHolder holder, int position) {

        if (getItemViewType(position) == TYPE_FOOT)
            return;

        String url = strings.get(position);
        //通过setTag将该item对应的url信息保存,用于item点击事件Toast显示
        holder.itemView.setTag(R.layout.item_head_foot_rv, url);
        holder.itemView.setTag(R.id.iv_item_head_foot, position);
        holder.tv.setText(url);

    }

    @Override
    public int getItemCount() {
        //添加了一个Foot—View,所以 +1;
        return strings.size() + 1;
    }

    class ItemClickViewHolder extends ViewHolder{

        private ImageView iv;
        private TextView tv;

        ItemClickViewHolder(View itemView, int viewType) {
            super(itemView);

            if (viewType == TYPE_FOOT)
                return;

            iv = (ImageView) itemView.findViewById(R.id.iv_item_head_foot);
            tv = (TextView) itemView.findViewById(R.id.tv_item_head_foot);

        }
    }

    /**
     * 根据是否还有更多数据处理FootView显示与否
     * */
    private void setFootView(boolean hasMoreData) {

        if (hasMoreData && footView != null)
            footView.setVisibility(View.VISIBLE);
        else if (footView != null)
            footView.setVisibility(View.GONE);
    }
}

アダプターが使用するアイテムレイアウトの場合、画像はアップロードされません。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:contentPadding="8dp"
    app:cardElevation="2dp"
    app:cardUseCompatPadding="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/iv_item_head_foot"
            android:layout_width="56dp"
            android:layout_height="56dp"
            android:contentDescription="@null"
            android:src="@mipmap/bg_loading"
            android:scaleType="centerCrop"/>

        <TextView
            android:id="@+id/tv_item_head_foot"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:textSize="14sp"
            android:lines="2"
            android:lineSpacingMultiplier="1.2"/>
    </LinearLayout>

</android.support.v7.widget.CardView>

アダプターが使用するFootViewxml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal">

    <ProgressBar
        android:layout_width="24dp"
        android:layout_height="24dp"
        style="@style/Base.TextAppearance.AppCompat.Small.Inverse"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加载更多"
        android:layout_margin="16dp"
        android:textSize="14sp"/>

    <ProgressBar
        android:layout_width="24dp"
        android:layout_height="24dp"
        style="@style/Base.TextAppearance.AppCompat.Small.Inverse"/>

</LinearLayout>

アクティビティでAdaprerを使用するコード

package com.example.zpf.animmenu;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Arrays;

import adapter.RvAdapterItemClick;

public class RecyclerItemClickActivity extends BaseActivity {
    
    

    private final String[] urls = {
            "http://hbimg.b0.upaiyun.com/6293fd60a2597a6017633e3c8e3816d89b70dc2165ad9-jkFvRh_fw658",
            "http://icon.nipic.com/BannerPic/20160426/photo/20160426160807.jpg",
            "http://icon.nipic.com/BannerPic/20160426/photo/20160426160826.jpg",
            "http://icon.nipic.com/BannerPic/20160426/photo/20160426160848.jpg",
            "http://icon.nipic.com/BannerPic/20160426/photo/20160426160908.jpg",
            "http://icon.nipic.com/BannerPic/20160426/photo/20160426160926.jpg",
            "http://pic94.nipic.com/file/20160409/11284670_185122899000_2.jpg",
            "http://pic94.nipic.com/file/20160403/22743169_220209251000_2.jpg",
            "http://pic94.nipic.com/file/20160410/18807750_102028863000_2.jpg",
            "http://pic94.nipic.com/file/20160406/22743169_234848884000_2.jpg",
            "http://pic94.nipic.com/file/20160406/19700831_040444643000_2.jpg",
            "http://pic94.nipic.com/file/20160321/7874840_094355922000_2.jpg",
            "http://pic94.nipic.com/file/20160406/22743169_233812263000_2.jpg",
            "http://pic94.nipic.com/file/20160407/21544848_224025191000_2.jpg"};

    /**
     * 模拟下拉的handler message what
     * */
    private final int MSG_DATA_DOWN = 0;

    /**
     * 模拟上拉加载更多的handler message what
     * */
    private final int MSG_DATA_UP = 1;

    private SwipeRefreshLayout refreshLayout;
    private RvAdapterItemClick adapterItemClick;

    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            doMessage(msg);
        }
    };

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

        initView();
    }

    private void initView() {

        refreshLayout = (SwipeRefreshLayout) findViewById(R.id.srl_item_click);
        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {

                refreshLayout.setRefreshing(true);
                handler.sendEmptyMessageDelayed(MSG_DATA_DOWN, 3000);
            }
        });

        RecyclerView rv = (RecyclerView) findViewById(R.id.rv_item_click);
        rv.setLayoutManager(new LinearLayoutManager(this));
        rv.setHasFixedSize(true);
        rv.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

                LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
                int lastPosition = manager.findLastVisibleItemPosition();
                View viewLast = manager.findViewByPosition(lastPosition);

                //viewFoot.getBottom() == recyclerView.getBottom() 表示已经滑动到最底部
                if (viewLast != null && viewLast.getBottom() == recyclerView.getBottom() &&
                        !adapterItemClick.isLoading()) {

                    //将加载数据状态设置true,防止多次加载,在doMessage里将值重置
                    adapterItemClick.setLoading(true);

                    //模拟三秒后获取到数据
                    handler.sendEmptyMessageDelayed(MSG_DATA_UP, 3000);
                }
            }
        });

        adapterItemClick = new RvAdapterItemClick(this);
        rv.setAdapter(adapterItemClick);

        ArrayList<String> strings = new ArrayList<>();
        strings.addAll(Arrays.asList(urls));
        adapterItemClick.setModels(strings);

        adapterItemClick.setOnItemClickListener(new RvAdapterItemClick.OnItemClickListener() {
            @Override
            public void OnItemClick(View view, int position, String url) {

                //RecyclerView的ItemClick点击事件的处理
                Toast.makeText(RecyclerItemClickActivity.this, String.valueOf(position),
                        Toast.LENGTH_SHORT).show();
            }
        });

    }

    /**
     * 模拟网络请求数据返回结果处理
     * */
    private void doMessage(Message msg) {

        //模拟下拉数据反馈处理
        if (msg.what == MSG_DATA_DOWN) {

            refreshLayout.setRefreshing(false);

            ArrayList<String> urlList = new ArrayList<>();
            urlList.addAll(Arrays.asList(urls));
            adapterItemClick.setModels(urlList);

        }
        //模拟上拉数据反馈处理
        else if (msg.what == MSG_DATA_UP) {

            adapterItemClick.setLoading(false);

            ArrayList<String> strings = new ArrayList<>();
            strings.addAll(Arrays.asList(urls));
            adapterItemClick.appendModels(strings);
        }
    }
}

わかりました、それだけです!興味があれば、コードをコピーして試してみてください。

おすすめ

転載: blog.csdn.net/nsacer/article/details/72669060