ไม่จำเป็นต้องใช้ห้องสมุดบุคคลที่สาม ปรับแต่งเล็ก ๆ น้อย ๆในวิธีการที่แสดงให้เห็นในGoogle I / O 2016และไฮเซนเบิร์กในหัวข้อนี้ไม่หลอกลวง
ตั้งแต่notifyDataSetChanged()
Redraws สมบูรณ์RecyclerView
, notifyDataItemChanged()
เป็นตัวเลือกที่ดีกว่า (ไม่ได้ดีที่สุด) เพราะเรามีตำแหน่งและViewHolder
ที่จำหน่ายของเราและnotifyDataItemChanged()
เพียงวาดโดยเฉพาะอย่างยิ่งViewHolder
ในตำแหน่งที่กำหนด
แต่ปัญหาคือการหายไปก่อนกำหนดของการViewHolder
คลิกและการเกิดขึ้นจะไม่ถูกกำจัดแม้ว่าnotifyDataItemChanged()
จะถูกใช้
รหัสต่อไปนี้ไม่ได้หันไปใช้notifyDataSetChanged()
หรือnotifyDataItemChanged()
และถูกทดสอบบน API 23 และใช้งานได้อย่างมีเสน่ห์เมื่อใช้กับ RecyclerView โดยที่ ViewHolder แต่ละรายการมีCardView
รูทองค์ประกอบ:
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final boolean visibility = holder.details.getVisibility()==View.VISIBLE;
if (!visibility)
{
holder.itemView.setActivated(true);
holder.details.setVisibility(View.VISIBLE);
if (prev_expanded!=-1 && prev_expanded!=position)
{
recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.setActivated(false);
recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.findViewById(R.id.cpl_details).setVisibility(View.GONE);
}
prev_expanded = position;
}
else
{
holder.itemView.setActivated(false);
holder.details.setVisibility(View.GONE);
}
TransitionManager.beginDelayedTransition(recycler);
}
});
prev_position
เป็นจำนวนเต็มทั่วโลกเริ่มต้นที่ -1
details
เป็นมุมมองที่สมบูรณ์ซึ่งจะแสดงเมื่อขยายและปิดบังเมื่อยุบ
ดังที่ได้กล่าวแล้วองค์ประกอบรากของViewHolder
คือCardView
ด้วยforeground
และstateListAnimator
แอตทริบิวต์ที่กำหนดไว้อย่างที่ Heisenberg กล่าวไว้ในหัวข้อนี้
UPDATE:การสาธิตด้านบนจะยุบรายการที่ขยายออกไปก่อนหน้าหากหนึ่งในรายการนั้นขยาย ในการปรับเปลี่ยนพฤติกรรมนี้และเก็บรายการที่ขยายไว้เหมือนเดิมแม้ว่าจะมีการขยายรายการอื่นคุณจะต้องใช้รหัสต่อไปนี้
if (row.details.getVisibility()!=View.VISIBLE)
{
row.details.setVisibility(View.VISIBLE);
row.root.setActivated(true);
row.details.animate().alpha(1).setStartDelay(500);
}
else
{
row.root.setActivated(false);
row.details.setVisibility(View.GONE);
row.details.setAlpha(0);
}
TransitionManager.beginDelayedTransition(recycler);
UPDATE:เมื่อขยายรายการสุดท้ายในรายการรายการนั้นอาจไม่สามารถมองเห็นได้อย่างสมบูรณ์เนื่องจากส่วนที่ขยายจะอยู่ด้านล่างหน้าจอ ในการรับไอเท็มเต็มหน้าจอให้ใช้รหัสต่อไปนี้
LinearLayoutManager manager = (LinearLayoutManager) recycler.getLayoutManager();
int distance;
View first = recycler.getChildAt(0);
int height = first.getHeight();
int current = recycler.getChildAdapterPosition(first);
int p = Math.abs(position - current);
if (p > 5) distance = (p - (p - 5)) * height;
else distance = p * height;
manager.scrollToPositionWithOffset(position, distance);
สำคัญ:สำหรับการสาธิตการทำงานข้างต้นเราจะต้องเก็บโค้ดไว้ในอินสแตนซ์ของ RecyclerView & เป็น LayoutManager (ภายหลังเพื่อความยืดหยุ่น)