English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Implementierungsmethode für das Hochladen mehrerer Elemente und das Herunterziehen des Aktualisierungsmechanismus in Android RecyclerView

RecyclerView ist schon lange da, aber in Projekten wurde zuvor immer ListView verwendet, und in den letzten Projekten wurde viel RecycleView verwendet. Besonders der Pull-to-Refresh der Wasserfall-View, im Internet gibt es viele, aber keine passenden, also habe ich selbst zusammengefasst.

Schauen wir uns erst einmal ein Bild an:

 

 

Es gibt zwei Möglichkeiten, um die Funktionen von Pull-to-Load-More und Pull-to-Refresh mit RecyclerView zu implementieren:

1dieser Art und Weise, Android.support.v zu verwenden4diesem Control .widget.SwipeRefreshLayout zu implementieren.

2mit RecyleView enthaltendem eigenständigen Control.

Es ist nicht gut, Header in RecycleView hinzuzufügen, zuvor konnte ich Header und Footer in ListView hinzufügen, aber RecycleView scheint nicht so gut zu handhaben. Für den ersten, der die System-Android.support.v verwendet4mit .widget.SwipeRefreshLayout implementiert, was auch sehr nützlich ist, aber Produkte vermeiden in der Regel diese Art von Pull-to-Refresh, um sich selbst als cool zu erscheinen, sie machen oft ihre eigenen mit Animationen, was ziemlich lächerlich ist... also müssen wir nur die Methode verwenden2Ende.

Kurz gesagt, die Methode2Die Implementierungsmethode, die Elternansicht ist ViewGroup, darin werden View hinzugefügt, der erste ist der Header, der zweite ist RecycleView, und die unterste Dropdown-Loading-More-Ansicht wird durch den Adapter von RecycleViw hinzugefügt.

Mit dem Gedanken daran, loszulegen:

package com.krain.srecyclerview.fruitview;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.krain.srecyclerview.R;
/**
* 由dafuShao创建于 2016/9/9 0009.
*
*/
public class ElizabethView extends FrameLayout {
private ImageView imageView;
private AnimationDrawable animationDrawable;
public ElizabethView(Context context) {
super(context);
initview(context);
}
public ElizabethView(Context context, AttributeSet attrs) {
super(context, attrs);
initview(context);
}
public ElizabethView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initview(context);
}
private void initview(Context context){
View view= LayoutInflater.from(context).inflate(R.layout.elizabeth_item, null);
imageView=(ImageView) view.findViewById(R.id.elizabeth_im);
animationDrawable= (AnimationDrawable) imageView.getBackground();
addView(view);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
//开始动画
public void startAnim(){
animationDrawable.start();
}
//停止动画
public void stopAnim(){
animationDrawable.stop();
}
}

这是头部控件很简单,里面有一个小的不倒翁眼睛,左右挤一挤的效果就不贴图了。

以下是自己定义的包含RecyclerView的控件代码如下:

package com.krain.srecyclerview.srecyclerview;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Scroller;
import android.widget.TextView;
import com.krain.srecyclerview.R;
import com.krain.srecyclerview.fruitview.ElizabethView;
public class SRecyclerView extends ViewGroup {
Context context;
RecyclerView mRecyclerView;
ElizabethView mHeaderView;
TextView mFootViewTips;//Die Textanzeige der Footview
AdapterWrapper mAdapter;
boolean mIsTop = true;//Ob gescrollt wurde bis zum oberen Ende
RecyclerView.LayoutManager mLayoutManager;
int mLastVisibleItem;
int mFirstVisibleItem;
OnRecyclerStatusChangeListener mRecyclerChangeListener;
int mStatus;//Der aktuelle Zustand
int mHeadviewHeight;//Die Höhe der Headview
Scroller mScroller;
int mFristScollerY;//Anfang des getscrolly
boolean mHasFooter;//ob die Funktion des Ziehens von oben laden unterstützt wird
boolean mShowFootVisible;//ob das FOOTERview angezeigt wird, wenn mHasFooter = true
boolean mHasRefresh = true;//ob das Ziehen von unten aktualisieren unterstützt wird
private final int DEFAULT_MIN_PAGEINDEX = 1;//Standard minimale Seitenzahl
int mMaxPage = DEFAULT_MIN_PAGEINDEX;//gesamtzahl der Seiten der Paginierung
int mCurrentPage = DEFAULT_MIN_PAGEINDEX;//aktuelle Seite, von1Start
private final int STATUS_NORMAL = 0, STATUS_REFRESH = 1, STATUS_LOAD = 2;
private final int MSG_LOAD_COMPLETE = 1, MSG_REFRESH_COMPLETE = 0;//constante des Handlers
private final int DELAY_LOAD_COMPLETE = 1000, DELAY_REFRESH_COMPLETE = 1000;//Zeit für die Freigabe des Ladevorgangs
public SRecyclerView(Context context) {
super(context);
init(context);
}
public SRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
/**
* maximale Seitenzahl einstellen
*
* @param maxPage
*/
public void setMaxPage(int maxPage) {
this.mMaxPage = maxPage;
}
/**
* oberteilt, ob das Abschicken von Laden unterstützt wird
*
* @param hasLoadmore
*/
public void setLoadmore(boolean hasLoadmore) {
mHasFooter = hasLoadmore;
}
public void setRecyclerViewLayoutManage(RecyclerView.LayoutManager mLayoutManage){
this.mLayoutManager=mLayoutManage;
}
/**
* Schließen der Funktion zum Nachladen nach unten
*/
public void disableRefresh() {
mHasRefresh = false;
}
public void setAdapter(BaseRecyclerViewAdapter adapter) {
int height = 0;
if (mMaxPage == DEFAULT_MIN_PAGEINDEX) {
mHasFooter = false;
}
mAdapter = new AdapterWrapper(context, adapter);
mRecyclerView.setAdapter(mAdapter);
}
private int getViewHeight(View view) {
int measure = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(measure, measure);
return view.getMeasuredHeight();
}
/**
* Erhalten des RecyclerView innerhalb des viewgroup
*
* @return
*/
public RecyclerView getRecyclerView() {
return mRecyclerView;
}
public void setOnRecyclerChangeListener(OnRecyclerStatusChangeListener listener) {
mRecyclerChangeListener = listener;
}
/**
* Einrichten der Animation für das Hinzufügen und Entfernen von Items im RecyclerView
*
* @param animator
*/
public void setItemAnimator(RecyclerView.ItemAnimator animator) {
mRecyclerView.setItemAnimator(animator);
}
public void notifyDataSetChanged() {
mStatus = STATUS_NORMAL;//Setzen Sie die Daten neu, um anzuzeigen, dass das Loadmore beendet ist, und kehren Sie zu einem normalen Zustand zurück
mAdapter.notifyDataSetChanged();
}
public void notifyDataInsert(int positionStart, int itemCount) {
mStatus = STATUS_NORMAL;//Setzen Sie die Daten neu, um anzuzeigen, dass das Loadmore beendet ist, und kehren Sie zu einem normalen Zustand zurück
mAdapter.notifyItemRangeInserted(positionStart, itemCount);
}
public void notifyDataRemove(int position) {
mStatus = STATUS_NORMAL;//Setzen Sie die Daten neu, um anzuzeigen, dass das Loadmore beendet ist, und kehren Sie zu einem normalen Zustand zurück
mAdapter.notifyItemRemoved(position);
}
/**
* Initialisierungsoperationen
*
* @param context
*/
void init(Context context) {
this.context = context;
mScroller = new Scroller(context);
// if (mLayoutManager != null) {
// addChildView(context, mLayoutManager);
// } else {
// addChildView(context, new LinearLayoutManager(context));
// }
addChildView(context);
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
/**
* Fügen Sie ein Kind-View hinzu
*
* @param context
*/
void addChildView(Context context, RecyclerView.LayoutManager mLayoutManager) {
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mHeaderView = new ElizabethView(context);
mRecyclerView = new RecyclerView(context);
addView(mHeaderView);
addView(mRecyclerView);
//mLayoutManager = new LinearLayoutManager(context);
// mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
// Standardanimation für das Hinzufügen und Entfernen von Items einstellen
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.addOnScrollListener(onScrollListener);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutParams(params);
}
void addChildView(Context contex) {
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mHeaderView = new ElizabethView(context);
mRecyclerView = new RecyclerView(context);
addView(mHeaderView);
addView(mRecyclerView);
//mLayoutManager = new LinearLayoutManager(context);
mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
// Standardanimation für das Hinzufügen und Entfernen von Items einstellen
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.addOnScrollListener(onScrollListener);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutParams(params);
}
/**
* Blockieren Sie die Berührungsevents der Recyclerview (während des Pull-to-Refresh)
*/
float lastY;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN:
lastY = ev.getRawY();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
return false;
case MotionEvent.ACTION_MOVE:
if (mHasRefresh && mIsTop && ev.getRawY() > lastY)
return true;
break;
}
return false;
}
float offsetY = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
offsetY = Math.abs(event.getRawY() - lastY); //Absoluter Wert der Y-Differenz
if (offsetY > 0)
scrollToOffset(offsetY);
else {
mIsTop = false;
}
break;
case MotionEvent.ACTION_UP:
if (getScrollY() <= 0) {
doRefresh();
mHeaderView.stopAnim();
mHeaderView.startAnim();
} else complete();
break;
}
return super.onTouchEvent(event);
}
/**
* Bewegung dieses Views zur Position des Fingers
*
* @param offsetY Y-Achsenverschiebung
*/
void scrollToOffset(float offsetY) {
//Wenn gerade aktualisiert wird und der aktuelle ScrollY-Wert mit dem Initialwert gleich ist, bedeutet dies, dass der Abwärtsscrollvorgang für die Aktualisierung vorbereitet ist und einmal only ausgeführt wird
if (getScrollY() == mFristScollerY && mRecyclerChangeListener != null)
mRecyclerChangeListener.startRefresh();
int value = Math.round(offsetY / 2.0F);
value = mFristScollerY - value;
scrollTo(0, value);
}
/**
* Durchführung der Aktualisierungsoperation, Bewegung zur Position des Headers, der gerade gekommen ist
*/
void doRefresh() {
mStatus = STATUS_REFRESH;
int currentY = getScrollY();
mScroller.startScroll(0, currentY, 0, (mFristScollerY - mHeadviewHeight) - currentY);
invalidate();
if (mRecyclerChangeListener != null) mRecyclerChangeListener.onRefresh();
handler.sendEmptyMessageDelayed(MSG_REFRESH_COMPLETE, DELAY_REFRESH_COMPLETE);
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == MSG_LOAD_COMPLETE) {
View footview = mAdapter.getFootView();
if (footview != null)
mRecyclerView.smoothScrollBy(0, -footview.getMeasuredHeight());
} else if (msg.what == MSG_REFRESH_COMPLETE)
complete();
}
};
/**
* Der Header kehrt an seinen ursprünglichen Ort zurück und wird vollständig ausgeblendet
*/
public void complete() {
mCurrentPage = DEFAULT_MIN_PAGEINDEX;//Nachdem es abgeschlossen ist, kehrt die aktuelle Seite zu ihrem Standardwert zurück
if (mFootViewTips != null)
mFootViewTips.setText(context.getString(R.string.loading));//Ändern Sie den Fuß-Tooltip in 'Wird geladen...'
if (mRecyclerChangeListener != null) mRecyclerChangeListener.refreshComplete();
mStatus = STATUS_NORMAL;
int currentY = getScrollY();
mScroller.startScroll(0, currentY, 0, mFristScollerY - currentY);
mHeaderView.stopAnim();
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
height += child.getMeasuredHeight();
}
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int left = getPaddingLeft();
int top = getPaddingTop();
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (i == 0) {//Center the display when it is a header
int headerLeft = getMeasuredWidth(); / 2 - child.getMeasuredWidth(); / 2;
child.layout(headerLeft, top, headerLeft + child.getMeasuredWidth(), top + child.getMeasuredHeight());
} else
child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
top += child.getMeasuredHeight();
}
mHeadviewHeight = getPaddingTop(); + mHeaderView.getMeasuredHeight();
scrollTo(0, mHeadviewHeight);//Move below the header to display the recyleview
mFristScollerY = getScrollY();
}
/**
* RecyclerView's scroll listener event
*/
RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
//gescrollt wurde zum Anfang
if (mFirstVisibleItem == 0) {
mIsTop = true;
} else {
mIsTop = false;
if (mStatus != STATUS_LOAD && mShowFootVisible && mLastVisibleItem + 1 == mAdapter.getItemCount()) {
if (mCurrentPage == mMaxPage) {
//Wenn die aktuelle Seite die letzte Seite ist
mFootViewTips = (TextView) mAdapter.getFootView().findViewById(R.id.footer_tips);
mFootViewTips.setText(context.getString(R.string.last_page_tips));
handler.sendEmptyMessageDelayed(MSG_LOAD_COMPLETE, DELAY_LOAD_COMPLETE);
} else {
mStatus = STATUS_LOAD;
if (mRecyclerChangeListener != null) {
mRecyclerChangeListener.onLoadMore();
mCurrentPage++;
}
}
}
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (mLayoutManager instanceof LinearLayoutManager) {
mLastVisibleItem = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
mFirstVisibleItem = ((LinearLayoutManager) mLayoutManager).findFirstCompletelyVisibleItemPosition();
setFootviewVisible();
} else if (mLayoutManager instanceof GridLayoutManager) {
mLastVisibleItem = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
mFirstVisibleItem = ((GridLayoutManager) mLayoutManager).findFirstCompletelyVisibleItemPosition();
setFootviewVisible();
} else if (mLayoutManager instanceof StaggeredGridLayoutManager) {
//Aufgrund der Besonderheiten von StaggeredGridLayoutManager kann es mehrere Items geben, die zuletzt angezeigt werden, daher wird ein Array zurückgegeben
//Nachdem dieses Array erhalten wurde, ist der Wert der Position im Array mit dem größten Wert die Position, die zuletzt angezeigt wird
int[] lastPositions = new int[((StaggeredGridLayoutManager) mLayoutManager).getSpanCount()];
((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(lastPositions);
mLastVisibleItem = findMax(lastPositions);
mFirstVisibleItem = ((StaggeredGridLayoutManager) mLayoutManager).findFirstVisibleItemPositions(lastPositions)[0];
setFootviewVisible();
}
}
};
void setFootviewVisible() {
//当设置了拥有上拉加载功能但是第一页的条目不足以盛满Recyclerview的时候隐藏footer
if (mHasFooter && mFirstVisibleItem == 0) {
/**
* 这里加上一个mShowFootVisible在上拉加载功能启用的情况下生效,从来控制item数量不足铺满
* recyclerview的高度时刻隐藏footview,在item数量超过view高度的情况下显示
*/
if (mLastVisibleItem + 1 == mAdapter.getItemCount()) {
mShowFootVisible = false;
} else mShowFootVisible = true;
notifyDataSetChanged();
}
}
private int findMax(int[] positions) {
int max = positions[0];
for (int value : positions) {
if (value > max) {
max = value;
}
}
return max;
}
private class AdapterWrapper extends RecyclerView.Adapter {
private static final int TYPE_ITEM = 0;
private static final int TYPE_FOOTER = 1;
private RecyclerView.Adapter mAdapter;
private Context mContext;
View footer;
public AdapterWrapper(Context context, RecyclerView.Adapter wrappedAdapter) {
this.mContext = context;
this.mAdapter = wrappedAdapter;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder holder = null;
switch (viewType) {
case TYPE_ITEM:
holder = mAdapter.onCreateViewHolder(parent, viewType);
break;
case TYPE_FOOTER:
footer = LayoutInflater.from(mContext).inflate(R.layout.lib_recyle_footview, null);
LinearLayout linearLayout = (LinearLayout) footer.findViewById(R.id.loading_layout);
StaggeredGridLayoutManager.LayoutParams layoutParams =
new StaggeredGridLayoutManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setFullSpan(true);
linearLayout.setLayoutParams(layoutParams);
holder = new FooterViewHolder(footer);
break;
}
return holder;
}
public View getFootView() {
return footer;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (!mHasFooter || position + 1 != getItemCount()) {
mAdapter.onBindViewHolder(holder, position);
}
}
@Override
public int getItemCount() {
return mShowFootVisible ? mAdapter.getItemCount() + 1 : mAdapter.getItemCount();
}
@Override
public int getItemViewType(int position) {
if (mShowFootVisible && position + 1 == getItemCount()) {
return TYPE_FOOTER;
} else {
return TYPE_ITEM;
}
}
private class FooterViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public TextView tvLoading;
public LinearLayout llyLoading;
public FooterViewHolder(View itemView) {
super(itemView);
progressBar = (ProgressBar) itemView.findViewById(R.id.progress_loading);
tvLoading = (TextView) itemView.findViewById(R.id.footer_tips);
llyLoading = (LinearLayout) itemView.findViewById(R.id.loading_layout);
}
}
}
}

Zuletzt gibt es noch den Code für den Adapter: }}

package com.krain.srecyclerview.srecyclerview;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
public abstract class BaseRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
private OnItemClickLisener mItemListener;
@Override
public VH onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getItemView(viewType, parent);
VH vh = getViewHolder(view);
view.setOnClickListener(new OnRecyclerAdapterclickListener(vh, viewType));
view.setOnLongClickListener(new OnRecyclerAdapterclickListener(vh, viewType));
return vh;
}
public abstract VH getViewHolder(View itemView);
/**
* Rückgabe des View des Items
*
* @return
*/
public abstract View getItemView(int viewType, ViewGroup parent);
/**
* Rückgabe der Daten jedes Items des Adapters, optional
*/
public Object getItem(int position) {
return null;
}
/**
* Item-Klickereignis-Interface
*
* @param mItemListener
*/
public void setOnItemListener(OnItemClickLisener mItemListener) {
this.mItemListener = mItemListener;
}
@Override
public abstract void onBindViewHolder(VH holder, int position);
@Override
public abstract int getItemCount();
class OnRecyclerAdapterclickListener implements View.OnClickListener, View.OnLongClickListener {
VH viewholder;
int viewType;
public OnRecyclerAdapterclickListener(VH viewholder, int viewType) {
this.viewholder = viewholder;
this.viewType = viewType;
}
@Override
public void onClick(View v) {
if (mItemListener != null && viewholder.getAdapterPosition() != RecyclerView.NO_POSITION) {
mItemListener.onItemClick(viewholder.getAdapterPosition(), viewType, viewholder, v);
}
}
@Override
public boolean onLongClick(View v) {
if (mItemListener != null && viewholder.getAdapterPosition() != RecyclerView.NO_POSITION) {
mItemListener.onItemLongClick(viewholder.getAdapterPosition(), viewType, viewholder, v);
}
return false;
}
}
}

Bitte beachten Sie:

Wenn Sie die Layout-Methode von Reciview ändern möchten, ändern Sie dies hier

void addChildView(Context contex) {
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mHeaderView = new ElizabethView(context);
mRecyclerView = new RecyclerView(context);
addView(mHeaderView);
addView(mRecyclerView);
//mLayoutManager = new LinearLayoutManager(context);
mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
// Standardanimation für das Hinzufügen und Entfernen von Items einstellen
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.addOnScrollListener(onScrollListener);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutParams(params);
}

mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); Diese Zeile ist es, ändern Sie sie entsprechend, hier wurde noch nichts verpackt, in einigen Tagen wird ein Paket erstellt.

Es muss auch darauf geachtet werden, ob es sich bei der Berührung um die letzte Zeile handelt, wenn es sich um ein Wasserfall-Layout handelt, dann muss auf die andere Weise geprüft werden

if (mLayoutManager instanceof StaggeredGridLayoutManager) {
//Aufgrund der Besonderheiten von StaggeredGridLayoutManager kann es mehrere Items geben, die zuletzt angezeigt werden, daher wird ein Array zurückgegeben
//Nachdem dieses Array erhalten wurde, ist der Wert der Position im Array mit dem größten Wert die Position, die zuletzt angezeigt wird
int[] lastPositions = new int[((StaggeredGridLayoutManager) mLayoutManager).getSpanCount()];
((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(lastPositions);
mLastVisibleItem = findMax(lastPositions);
mFirstVisibleItem = ((StaggeredGridLayoutManager) mLayoutManager).findFirstVisibleItemPositions(lastPositions)[0];
setFootviewVisible();
}

由于 StaggeredGridLayoutManager 的特殊性可能导致最后显示的 item 存在多个,因此这里取到的是一个数组。得到这个数组后再取到数组中 position 值最大的那个就是最后显示的 position 值了,然后再设置最后一行加载更多的显示。

以上所述是小编为大家介绍的 Android RecyclerView 上拉加载更多及下拉刷新功能的实现方法,希望对大家有所帮助。如果大家有任何疑问,欢迎留言,小编会及时回复。在此也非常感谢大家对呐喊教程网址的支持!

声明:本文内容来自网络,版权归原创者所有。内容由互联网用户自发贡献并自行上传,本网站不拥有所有权,未进行人工编辑处理,也不承担相关法律责任。如果您发现涉嫌版权的内容,请发送邮件至:notice#w,我们将及时回复。3codebox.com(在发送邮件时,请将#更换为@进行举报,并提供相关证据。一经查实,本站将立即删除涉嫌侵权内容。)

Empfohlene Artikel