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(カスタムビュー)
Activity:
gradleファイルの追加:
質問連絡:1808418098(微信、QQ)
公式には、このコントロールは限られたウィンドウで大量のデータセットを表示するために使用されています.
実はこのような機能のコントロールはよく知られていません.例えば、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)