ฉันต้องรู้ว่าองค์ประกอบใดบ้างที่จะแสดงใน RecyclerView ของฉัน ไม่มีOnScrollListener.onScroll(...)
วิธีเทียบเท่ากับ ListViews ฉันพยายามทำงานด้วยView.getGlobalVisibleRect(...)
แต่แฮ็คนั้นน่าเกลียดเกินไปและก็ไม่ได้ผลเสมอไป
มีใครคิดบ้างไหม?
ฉันต้องรู้ว่าองค์ประกอบใดบ้างที่จะแสดงใน RecyclerView ของฉัน ไม่มีOnScrollListener.onScroll(...)
วิธีเทียบเท่ากับ ListViews ฉันพยายามทำงานด้วยView.getGlobalVisibleRect(...)
แต่แฮ็คนั้นน่าเกลียดเกินไปและก็ไม่ได้ผลเสมอไป
มีใครคิดบ้างไหม?
คำตอบ:
ชื่อ / LayoutManager
นามสกุลเด็กสามารถมองเห็นได้ขึ้นอยู่กับ หากคุณกำลังใช้LinearLayoutManager
หรือGridLayoutManager
คุณสามารถใช้
int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
ตัวอย่างเช่น:
GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
สำหรับLinearLayoutManager
, ครั้งแรก / ครั้งสุดท้ายขึ้นอยู่กับการสั่งซื้ออะแดปเตอร์ อย่าสอบถามเด็ก ๆ จากRecyclerView
; LayoutManager
อาจต้องการจัดวางรายการมากกว่าที่มองเห็นสำหรับการแคช
getItemCount
สามารถส่งคืน 1 และfindFirstVisibleItemPosition
-1 ในการโทรเดียวกัน
ในที่สุดฉันก็พบวิธีแก้ปัญหาที่จะรู้ว่ารายการปัจจุบันสามารถมองเห็นได้จากเหตุการณ์ onBindViewHolder ในอะแดปเตอร์
ที่สำคัญคือวิธีการคือViewPartiallyVisibleจาก LayoutManager
ในอะแดปเตอร์ของคุณคุณสามารถรับ LayoutManager จาก RecyclerView ซึ่งคุณได้รับเป็นพารามิเตอร์จากเหตุการณ์onAttachedToRecyclerView
สำหรับผู้ที่มีตรรกะที่จะใช้งานในอะแดปเตอร์ RecyclerView คุณยังสามารถใช้ @ernesto วิธีการรวมกับ on scrollListener เพื่อรับwhat you want
เป็น RecyclerView ปรึกษา ภายในอะแดปเตอร์คุณจะมีสิ่งนี้:
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if(manager instanceof LinearLayoutManager && getItemCount() > 0) {
LinearLayoutManager llm = (LinearLayoutManager) manager;
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visiblePosition = llm.findFirstCompletelyVisibleItemPosition();
if(visiblePosition > -1) {
View v = llm.findViewByPosition(visiblePosition);
//do something
v.setBackgroundColor(Color.parseColor("#777777"));
}
}
});
}
}
คุณสามารถใช้recyclerView.getChildAt()
เพื่อให้เด็ก ๆ มองเห็นได้และการตั้งค่าแท็กบางอย่างconvertview.setTag(index)
ในมุมมองเหล่านี้ในรหัสอะแดปเตอร์จะช่วยให้คุณเชื่อมโยงกับข้อมูลอะแดปเตอร์
recyclerView.getChildAt()
การRecyclerView
ทำงานปกติเท่านั้น RecyclerView
จะพยายามเก็บมุมมองชายด์เพียงไม่กี่รายการที่สามารถมองเห็นได้ในปัจจุบัน (เช่นภายในขอบเขตหน้าจอไม่ใช่การมองเห็นเป็น GONE, INVISIBLE) และพยายามรีไซเคิลมุมมองเหล่านี้เมื่อผู้ใช้เลื่อน
Linear / Grid LayoutManager
วิธีการดังต่อไปนี้สามารถใช้ในการตรวจสอบรายการที่visible
int findFirstVisibleItemPosition();
int findLastVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
และถ้าคุณต้องการติดตามis item visible on screen
เกณฑ์บางอย่างคุณสามารถอ้างถึงบล็อกต่อไปนี้
https://proandroiddev.com/detecting-list-items-perceived-by-user-8f164dfb1d05
ภาคผนวก :
ที่นำเสนอฟังก์ชั่นFindLast ... ตำแหน่ง ()ไม่ได้ทำงานอย่างถูกต้องในสถานการณ์ที่มีแถบเครื่องมือยุบในขณะที่แถบเครื่องมือที่มีการขยายตัว
ดูเหมือนว่ามุมมองรีไซเลอร์มีความสูงคงที่และในขณะที่แถบเครื่องมือถูกขยายรีไซเลอร์จะถูกย้ายลงมาจากหน้าจอบางส่วน ดังนั้นผลลัพธ์ของฟังก์ชั่นที่เสนอจึงสูงเกินไป ตัวอย่าง: ไอเท็มที่มองเห็นได้ครั้งสุดท้ายถูกบอกว่าเป็น # 9 แต่อันที่จริงแล้วไอเท็ม # 7 เป็นรายการสุดท้ายที่อยู่บนหน้าจอ
พฤติกรรมนี้เป็นสาเหตุที่ทำให้มุมมองของฉันไม่สามารถเลื่อนไปยังตำแหน่งที่ถูกต้องได้เช่น scrollToPosition () ทำงานไม่ถูกต้อง (ในที่สุดฉันก็ยุบแถบเครื่องมือโดยทางโปรแกรม)
สำหรับการStaggeredGridLayoutManager
ทำสิ่งนี้:
RecyclerView rv = findViewById(...);
StaggeredGridLayoutManager lm = new StaggeredGridLayoutManager(...);
rv.setLayoutManager(lm);
และเพื่อรับมุมมองรายการที่มองเห็นได้:
int[] viewsIds = lm.findFirstCompletelyVisibleItemPositions(null);
ViewHolder firstViewHolder = rvPlantios.findViewHolderForLayoutPosition(viewsIds[0]);
View itemView = viewHolder.itemView;
อย่าลืมตรวจสอบว่ามันว่างเปล่า
viewsIds
เป็นอาร์เรย์และอาจว่างเปล่า