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

تحقيق تحميل المزيد عند سحب Android RecyclerView والتحديث السريع عند سحب لأسفل

RecyclerView كان موجودًا منذ فترة طويلة، ولكن في المشاريع السابقة كنت أستخدم ListView، ولكن في المشاريع الجديدة التي بدأت مؤخرًا، تم استخدام RecycleView بشكل كبير. خاصة في تحديثات السحب للأسفل في تدفق الماء، لم أجد ما هو مناسب على الإنترنت، لذا قمت بجمع بعض النقاط.

دعنا نبدأ بوضع الصورة لرؤيتها:

 

 

استخدام RecyclerView لتحقيق وظائف تحميل المزيد عند سحب لأعلى و التحديث السريع للأسفل لديني طريقتان:

1. استخدام SwipeRefreshLayout المدمج في النظام Android.support.v4.widget.SwipeRefreshLayout هذا العنصر.

2. العنصر المخصص الذي يحتوي على RecyleView.

استخدام RecycleView سيء جدًا لتحديد الرأس، من قبل في استخدامه في ListView كان بإمكاني إضافة الرأس والسفلية، ولكن يبدو أن RecycleView ليس سهلًا في التشغيل. بالنسبة للطريقة الأولى التي يتم تنفيذها باستخدام SwipeRefreshLayout المدمج في النظام Android.support.v4.widget.SwipeRefreshLayout، فهي جيدة أيضًا، ولكن لا يفضل المنتج هذا النوع من التحديثات السريعة للأسفل، من أجل أن يبدو أكثر روعة، يفضل أن يكون لديه تحديث خاص به يحتوي على رسوم متحركة، مما يجعله غير جيد جدًا. لذا، يجب استخدام الطريقة 2 فقط.

بشكل عام، ذكر طريقة تنفيذ الطريقة 2، واجهة التخطيط الأم هي ViewGroup، وأضف أول عنصر إلى واجهة التخطيط هذه هو التحكم في الرأس، والثاني هو RecycleView، بالنسبة إلى العنصر في الأسفل للتحميل المزيد من البيانات، يتم إضافته من خلال واجهة التخطيط RecycleViw.

بمجرد أن لديك فكرة، استمر في العمل:

package com.krain.srecyclerview.fruitview;
استيراد اندرويد كونتكس;
import android.graphics.drawable.AnimationDrawable;
استيراد اندرويد يول تايتل;
استيراد اندرويد فيو انلوفتر;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
استيراد كوم كرين اسريكفيكو آر;
/**
* تم إنشائه بواسطة dafuShao في 2016/9/9 0009.
*
*/
public class ElizabethView extends FrameLayout {
private ImageView imageView;
private AnimationDrawable animationDrawable;
public ElizabethView(Context context) {
super(السياق);
initview(context);
}
public ElizabethView(Context context, AttributeSet attrs) {
super(السياق, attrs);
initview(context);
}
public ElizabethView(Context context, AttributeSet attrs, int defStyleAttr) {
super(السياق, 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) فيو جيت باكجراوند();
أضف فيو;
}
@Override
protected void onMeasure(int عرضMeasureSpec, int طولMeasureSpec) {
سوبر إن ميسور ويدث ميسور، هيتث ميسور;
}
//بدء التحريك
بببولك فون سStarتنيم;
animationDrawable.start();
}
//توقيف التحريك
بببولك فون سTopانيم;
animationDrawable.stop();
}
}

هذا هو التحكم في الرأس بسيط للغاية، يحتوي على عين صغيرة مدمجة، ويمكنك سحبها في اليسار واليمين، لا أقوم بتحميل الصورة.

هذا الكود الخاص بتحكم RecyclerView مخصص كما يلي:

package com.krain.srecyclerview.srecyclerview;
استيراد اندرويد كونتكس;
استيراد اندرويد او اس هندلر;
استيراد اندرويد او اس مايجس;
استيراد اندرويد سبيكت فيو موتشنيون كومپات;
استيراد اندرويد سبيكت فيو ديفولت ايتيم انيميتور;
استيراد اندرويد سبيكت فيو جريد لاين مدير;
استيراد اندرويد سبيكت فيو لين لاين مدير;
import android.support.v7.widget.RecyclerView;
استيراد اندرويد سبيكت فيو موتشنيون كومپات;
استيراد اندرويد يول تايتل;
استيراد اندرويد فيو انلوفتر;
استيراد اندرويد فيو موتشنيون;
import android.view.View;
import android.view.ViewGroup;
استيراد اندرويد ويدجت لين لاين;
استيراد اندرويد ويدجت بروغريس بار;
استيراد اندرويد ويدجت سكرولر;
استيراد اندرويد ويدجت تيكسيت فيو;
استيراد كوم كرين اسريكفيكو آر;
import com.krain.srecyclerview.fruitview.ElizabethView;
public class SRecyclerView extends ViewGroup {
Context context;
RecyclerView mRecyclerView;
ElizabethView mHeaderView;
TextView mFootViewTips;//footview的文字显示
AdapterWrapper mAdapter;
boolean mIsTop = true;//是否滑动到了最顶部
RecyclerView.LayoutManager mLayoutManager;
int mLastVisibleItem;
int mFirstVisibleItem;
OnRecyclerStatusChangeListener mRecyclerChangeListener;
int mStatus;//当前状态
int mHeadviewHeight;//headview的高度
Scroller mScroller;
int mFristScollerY;//最开始的getscrolly
boolean mHasFooter;//是否有上拉加载的功能
boolean mShowFootVisible;//是否显示FOOTERview在mHasFooter为true的时候生效
boolean mHasRefresh = true;//是否支持下拉刷新
private final int DEFAULT_MIN_PAGEINDEX = 1;//默认最小的页数
int mMaxPage = DEFAULT_MIN_PAGEINDEX;//分页的总页数
int mCurrentPage = DEFAULT_MIN_PAGEINDEX;//当前的页数,从1开始
private final int STATUS_NORMAL = 0, STATUS_REFRESH = 1, STATUS_LOAD = 2;
private final int MSG_LOAD_COMPLETE = 1, MSG_REFRESH_COMPLETE = 0;//handle的常量
private final int DELAY_LOAD_COMPLETE = 1000, DELAY_REFRESH_COMPLETE = 1000; // وقت التجميد لإعادة التشغيل بعد التحميل أو التحديث
public SRecyclerView(السياق) {
super(السياق);
init(السياق);
}
public SRecyclerView(السياق, AttributeSet attrs) {
super(السياق, attrs);
init(السياق);
}
public SRecyclerView(السياق, AttributeSet attrs, int defStyleAttr) {
super(السياق, attrs, defStyleAttr);
init(السياق);
}
/**
* تعيين عدد الصفحات القصوى
*
* @param maxPage
*/
public void setMaxPage(int maxPage) {
this.mMaxPage = maxPage;
}
/**
* هل يدعم التحميل السحبي
*
* @param hasLoadmore
*/
public void setLoadmore(boolean hasLoadmore) {
mHasFooter = hasLoadmore;
}
public void setRecyclerViewLayoutManage(RecyclerView.LayoutManager mLayoutManage){
this.mLayoutManager=mLayoutManage;
}
/**
* إغلاق وظيفة التحديث السحبي
*/
public void disableRefresh() {
mHasRefresh = لا;
}
public void setAdapter(BaseRecyclerViewAdapter adapter) {
عدد طول = 0;
إذا (mMaxPage == DEFAULT_MIN_PAGEINDEX) {
mHasFooter = لا;
}
mAdapter = new AdapterWrapper(السياق, الموجه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();
}
/**
* الحصول على RecyclerView داخل viewgroup
*
* @return
*/
public RecyclerView getRecyclerView() {
return mRecyclerView;
}
public void setOnRecyclerChangeListener(OnRecyclerStatusChangeListener listener) {
mRecyclerChangeListener = listener;
}
/**
* تعيين حركة RecyclerView لاضافة أو حذف العناصر
*
* @param animator
*/
public void setItemAnimator(RecyclerView.ItemAnimator animator) {
mRecyclerView.setItemAnimator(animator);
}
public void notifyDataSetChanged() {
mStatus = STATUS_NORMAL;// تعيين البيانات مرة أخرى يعني انتهاء تحميل المزيد، عند هذا الوقت يرجع إلى الحالة العادية
mAdapter.notifyDataSetChanged();
}
public void notifyDataInsert(int positionStart, int itemCount) {
mStatus = STATUS_NORMAL;// تعيين البيانات مرة أخرى يعني انتهاء تحميل المزيد، عند هذا الوقت يرجع إلى الحالة العادية
mAdapter.notifyItemRangeInserted(positionStart, itemCount);
}
public void notifyDataRemove(int position) {
mStatus = STATUS_NORMAL;// تعيين البيانات مرة أخرى يعني انتهاء تحميل المزيد، عند هذا الوقت يرجع إلى الحالة العادية
mAdapter.notifyItemRemoved(position);
}
/**
* عملية التكوين
*
* @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();
}
}
/**
* إضافة View فرعي
*
* @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);
// إعداد الرسوم المتحركة الافتراضية لزيادة إزالة العناصر
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);
// إعداد الرسوم المتحركة الافتراضية لزيادة إزالة العناصر
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.addOnScrollListener(onScrollListener);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutParams(params);
}
/**
* تمرير لمس Recyclerview (عند التمرير لأسفل للتحديث)
*/
float lastY;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN:
lastY = ev.getRawY();
break;
حالة MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
return false;
حالة MotionEvent.ACTION_MOVE:
if (mHasRefresh && mIsTop && ev.getRawY() > lastY)
return true;
break;
}
return false;
}
float offsetY = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
الانتقال (event.getAction()) {
حالة MotionEvent.ACTION_MOVE:
offsetY = Math.abs(event.getRawY() - lastY); // قيمة الانحراف في المحور y النسبية
إذا (offsetY > 0)
scrollToOffset(offsetY);
آخره {
mIsTop = false;
}
break;
حالة MotionEvent.ACTION_UP:
إذا (getScrollY() <= 0)
doRefresh();
مقدمة_الرأس.توقفعن_الحركة();
mHeaderView.startAnim();
} آخره();
break;
}
return super.onTouchEvent(event);
}
/**
* تمرير هذا العنصر إلى موقع السحب
*
* @param offsetY قيمة الانحراف في المحور y
*/
void scrollToOffset(float offsetY) {
// إذا كان هناك تحديث يجري الآن وأساسي scrolly هو نفس القيمة، فهذا يعني أننا مستعدون للسحب للأسفل للبدء في التحديث، وأداء only مرة واحدة
إذا (getScrollY() == mFristScollerY && mRecyclerChangeListener != null)
mRecyclerChangeListener.startRefresh();
int value = Math.round(offsetY / 2.0F);
value = mFristScollerY - value;
scrollTo(0, value);
}
/**
* تنفيذ عملية التحديث، انتقال إلى موقع العنوان عند ظهوره
*/
void doRefresh() {
mStatus = STATUS_REFRESH;
عدد الحالية_السحب = الحصولعلى_السحب();
mScroller.startScroll(0, currentY, 0, (mFristScollerY - mHeadviewHeight) - currentY);
无效化();
إذا (mRecyclerChangeListener != null) mRecyclerChangeListener.onRefresh();
handler.sendEmptyMessageDelayed(MSG_REFRESH_COMPLETE, DELAY_REFRESH_COMPLETE);
}
Handler مدير = new Handler() {
@Override
public void handleMessage(Message msg) {
الأسلاف.معالجةالرسالة(msg);
إذا (msg.what == MSG_LOAD_COMPLETE) {
View القدم = المدمج.الحصولعلى_القدم();
إذا (القدم != null)
المجلس_النسيج.التحركالمتواضع(0, -طول_القدم.قياس();
} آخرا إذا (msg.what == MSG_REFRESH_COMPLETE)
الإنهاء();
}
};
/**
* العنوانيعودإلىمكانهويتمإخفاءهكليًا
*/
public void complete() {
الصفحة_الحالية = DEFAULT_MIN_PAGEINDEX;//بعدالإنهاءاستعادةالصفحةالحاليةإلىالقيمةالافتراضية
إذا (مقدمة_القدم.النص != null)
مقدمة_القدم.إعدادالنص(السياق.getString(R.string.loading));//تغييرمقدمةالقدمالنصالإشارةإلىتحميل
إذا (مستمع_المكبس_النفايات != null) مستمع_المكبس_النفايات.تحديثالإنهاء();
موضع = STATUS_NORMAL;
عدد الحالية_السحب = الحصولعلى_السحب();
المجلس.البدايةالتحرك(0, الحالية_السحب, 0, المرة_الأولى_المجلس - الحالية_السحب);
مقدمة_الرأس.توقفعن_الحركة();
无效化();
}
@Override
protected void onMeasure(int عرضMeasureSpec, int طولMeasureSpec) {
عدد عرض = MeasureSpec.getSize(عرضMeasureSpec);
عدد طول = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
قياسطفان (طفان, عرضMeasureSpec, طولMeasureSpec);
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) {//عندما يكون الـ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);//تحريك إلى أسفل الـheader لعرض recycleview
mFristScollerY = getScrollY();
}
/**
* حدث الاستماع إلى اللمس في RecyclerView
*/
RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);}}
إذا كان newState == RecyclerView.SCROLL_STATE_IDLE) {
//滑动到了顶部
إذا كان mFirstVisibleItem == 0) {
mIsTop = true;
} else {
mIsTop = false;
إذا كان mStatus != STATUS_LOAD && mShowFootVisible && mLastVisibleItem + 1 == mAdapter.getItemCount()) {
إذا كان mCurrentPage == mMaxPage) {
//当前页面是最后一页的时候
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;
إذا كان mRecyclerChangeListener != null) {
mRecyclerChangeListener.onLoadMore();
mCurrentPage++;
}
}
}
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
إذا كان mLayoutManager من نوع 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) {
// بسبب خاصية StaggeredGridLayoutManager قد يؤدي إلى وجود عدة items معروضة في النهاية، لذا يتم الحصول هنا على مجموعة
// حصول هذا المجموعة بعد ذلك الحصول على أكبر قيمة position في المجموعة هو position الأخير المعروض
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);
}
}
}
}

آخر شيء هو كود 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);
/**
* 返回item的view
*
* @return
*/
public abstract View getItemView(int viewType, ViewGroup parent);
/**
* 返回Adapter每个itemn的数据 可选
*/
public Object getItem(int position) {
return null;
}
/**
* item点击事件接口
*
* @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;
}
}
}

لاحظ أن:

إذا كنت ترغب في تغيير طريقة ترتيب Reciview هنا يتم التعديل

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);
// إعداد الرسوم المتحركة الافتراضية لزيادة إزالة العناصر
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.addOnScrollListener(onScrollListener);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutParams(params);
}

mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); هذا السطر هو الذي يتم تغييره لتكون متوافقًا، لم يتم تعبئة هذا الكود بعد بضعة أيام سيتم تعبئته

يجب أن نلاحظ أيضًا في التمرير ما إذا كانت السطر الأخير، إذا كانت في شكل منسق فيجب أن نلاحظ طريقة التحكم في الطريقة المختلفة

if (mLayoutManager instanceof StaggeredGridLayoutManager) {
// بسبب خاصية StaggeredGridLayoutManager قد يؤدي إلى وجود عدة items معروضة في النهاية، لذا يتم الحصول هنا على مجموعة
// حصول هذا المجموعة بعد ذلك الحصول على أكبر قيمة position في المجموعة هو position الأخير المعروض
int[] lastPositions = new int[((StaggeredGridLayoutManager) mLayoutManager).getSpanCount()];
((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(lastPositions);
mLastVisibleItem = findMax(lastPositions);
mFirstVisibleItem = ((StaggeredGridLayoutManager) mLayoutManager).findFirstVisibleItemPositions(lastPositions)[0];
setFootviewVisible();
}

بسبب خاصية StaggeredGridLayoutManager، قد يؤدي إلى وجود عدة items تظهر في النهاية، لذا يتم أخذ مجموعة من البيانات هنا، بعد الحصول على مجموعة البيانات، يتم أخذ position الأكبر في مجموعة البيانات هذا هو position النهائي الذي يتم عرضه، ثم يتم تعيين عرض تحميل المزيد في الخط الأخير.

ما ذكرته أعلاه هو طريقة تنفيذ ميزة تحميل المزيد عند سحب لأعلى و刷新 السحب للأسفل في RecyclerView الخاص بـ Android، آمل أن تكون مفيدًا لك، إذا كان لديك أي أسئلة، فنرجو منك ترك تعليق، وسأقوم بالرد عليك في أقرب وقت، وأشكرك أيضًا على دعمك لموقع呐喊 التعليمات!

البيان: محتوى هذا المقال تم جمعه من الإنترنت، ويحق للمالك الأصلي الحصول عليه، ويتم جمعه من قبل المستخدمين على الإنترنت ويتم تحميله بشكل مستقل، هذا الموقع لا يملك حقوق الملكية، ولا يتم تعديل المحتوى بشكل يدوي، ولا يتحمل أي مسؤولية قانونية مرتبطة بذلك. إذا كنت قد وجدت محتوى يشتبه في انتهاك حقوق النسخ، فنرجو منك إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (يرجى استبدال #بـ @ عند إرسال البريد الإلكتروني) لتقديم الشكوى، وقدم الأدلة ذات الصلة، وإذا تم التحقق من صحة الشكوى، سيتم حذف المحتوى المزعوم فورًا.

مفضل لك