RecyclerViewプルダウンの更新、プルアップの読み込み、アイテムのクリックの監視
プルダウンして更新し、プルアップしてさらにロードします。SmartRefreshLayoutを使用し
て、さまざまなコントロールをサポートし、ロードスタイルをカスタマイズすることをお勧めします...
アドレス:https://github.com/scwang90/SmartRefreshLayout
効果画像:
注:アイテムクリック効果は追加されていないため、デモンストレーションはトーストの最初にクリックされたアイテムのみであり、視覚的には表示されません。子供用の靴はコードをコピーして、自分で効果を試すことができます。
実施原則
- プルダウンリフレッシュ: Googleの公式v4パッケージのSwipeRefreshLayoutは、データプルダウンリフレッシュ操作に使用されます。
- プルアップしてさらに読み込む:「RecyclerViewシリーズ(1)」でFootViewをRecyclerViewに追加する方法を採用し、現在の画面で最後に表示されているアイテムの下部の位置がRecyclerViewの下部の位置と等しいかどうかを監視します。等しい場合は、下にスライドすると、FootViewも表示されます。したがって、より多くのデータがロードされます。
- アイテムクリックイベント:
(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);
}
}
}
わかりました、それだけです!興味があれば、コードをコピーして試してみてください。