เป็นไปได้ที่จะใช้รายการที่ขยายได้กับ RecyclerView ใหม่? ชอบ ExpandableListView ไหม
เป็นไปได้ที่จะใช้รายการที่ขยายได้กับ RecyclerView ใหม่? ชอบ ExpandableListView ไหม
คำตอบ:
สิ่งนี้ทำได้ง่ายด้วย LayoutManagers หุ้นทุกอย่างขึ้นอยู่กับวิธีที่คุณจัดการอะแดปเตอร์ของคุณ
เมื่อคุณต้องการขยายส่วนคุณเพียงแค่เพิ่มรายการใหม่ลงในอะแดปเตอร์ของคุณหลังส่วนหัว อย่าลืมโทรแจ้ง ITemRangeInserted เมื่อคุณทำสิ่งนี้ หากต้องการยุบส่วนคุณเพียงแค่ลบรายการที่เกี่ยวข้องออกแล้วโทรแจ้ง ITemRangeRemoved () สำหรับการเปลี่ยนแปลงข้อมูลใด ๆ ที่ได้รับแจ้งอย่างเหมาะสมมุมมองผู้รีไซเคิลจะทำให้มุมมองเคลื่อนไหว เมื่อเพิ่มรายการพื้นที่ที่จะเติมด้วยรายการใหม่จะถูกสร้างขึ้นโดยที่รายการใหม่จะจางหายไปการกำจัดจะตรงกันข้าม สิ่งที่คุณต้องทำนอกเหนือจากสิ่งต่างๆของอะแดปเตอร์คือการกำหนดรูปแบบมุมมองของคุณเพื่อถ่ายทอดโครงสร้างเชิงตรรกะไปยังผู้ใช้
อัปเดต: Ryan Brooks ได้เขียนบทความเกี่ยวกับวิธีการทำสิ่งนี้แล้ว
รับตัวอย่างการติดตั้งโค้ดจากที่นี่
ตั้งค่า ValueAnimator ภายใน onClick ของ ViewHolder
@Override
public void onClick(final View view) {
if (mOriginalHeight == 0) {
mOriginalHeight = view.getHeight();
}
ValueAnimator valueAnimator;
if (!mIsViewExpanded) {
mIsViewExpanded = true;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight, mOriginalHeight + (int) (mOriginalHeight * 1.5));
} else {
mIsViewExpanded = false;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight + (int) (mOriginalHeight * 1.5), mOriginalHeight);
}
valueAnimator.setDuration(300);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
view.getLayoutParams().height = value.intValue();
view.requestLayout();
}
});
valueAnimator.start();
}
นี่คือรหัสสุดท้าย
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView mFriendName;
private int mOriginalHeight = 0;
private boolean mIsViewExpanded = false;
public ViewHolder(RelativeLayout v) {
super(v);
mFriendName = (TextView) v.findViewById(R.id.friendName);
v.setOnClickListener(this);
}
@Override
public void onClick(final View view) {
if (mOriginalHeight == 0) {
mOriginalHeight = view.getHeight();
}
ValueAnimator valueAnimator;
if (!mIsViewExpanded) {
mIsViewExpanded = true;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight, mOriginalHeight + (int) (mOriginalHeight * 1.5));
} else {
mIsViewExpanded = false;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight + (int) (mOriginalHeight * 1.5), mOriginalHeight);
}
valueAnimator.setDuration(300);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
view.getLayoutParams().height = value.intValue();
view.requestLayout();
}
});
valueAnimator.start();
}
}
ExpandableListView
" เนื่องจากเนื้อหาที่ขยายในกรณีนั้นเป็นรายการที่มีรายการที่มาจากอะแดปเตอร์ นี่เป็นวิธีแก้ปัญหาที่เสื่อมสภาพโดยอนุญาตให้เป็นเด็กในกลุ่มได้เพียง 1 รายการเท่านั้น
https://github.com/gabrielemariotti/cardslib
ไลบรารีนี้มีการใช้งานรายการที่ขยายได้พร้อมด้วยมุมมองรีไซเคิล (อ้างอิงจากแอปสาธิตใน "CardViewNative" -> "รายการตารางและ RecyclerView" -> "การ์ดที่ขยายได้") นอกจากนี้ยังมีการ์ด / รายการที่น่าสนใจอื่น ๆ อีกมากมาย
มีคนบ่นว่าโซลูชันที่กล่าวถึงข้างต้นใช้กับ listview เป็นเนื้อหาที่ขยายไม่ได้ แต่มีวิธีง่ายๆ: สร้าง ListView และกรอก ListView นี้ด้วยตนเองกับแถวของคุณ
วิธีแก้ปัญหาสำหรับคนขี้เกียจ:มีวิธีง่ายๆหากคุณไม่ต้องการเปลี่ยนรหัสมากนัก เพียงใช้อะแดปเตอร์ของคุณด้วยตนเองเพื่อสร้างมุมมองและเพิ่มลงในไฟล์LinearLayout
.
นี่คือตัวอย่าง:
if (mIsExpanded)
{
// llExpandable... is the expandable nested LinearLayout
llExpandable.removeAllViews();
final ArrayAdapter<?> adapter = ... // create your adapter as if you would use it for a ListView
for (int i = 0; i < adapter.getCount(); i++)
{
View item = adapter.getView(i, null, null);
// if you want the item to be selectable as if it would be in a default ListView, then you can add following code as well:
item.setBackgroundResource(Functions.getThemeReference(context, android.R.attr.selectableItemBackground));
item.setTag(i);
item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// item would be retrieved with:
// adapter.getItem((Integer)v.getTag())
}
});
llExpandable.addView(item);
}
ExpandUtils.expand(llExpandable, null, 500);
}
else
{
ExpandUtils.collapse(llExpandable, null, 500);
}
ฟังก์ชันตัวช่วย: getThemeReference
public static int getThemeReference(Context context, int attribute)
{
TypedValue typeValue = new TypedValue();
context.getTheme().resolveAttribute(attribute, typeValue, false);
if (typeValue.type == TypedValue.TYPE_REFERENCE)
{
int ref = typeValue.data;
return ref;
}
else
{
return -1;
}
}
คลาสตัวช่วย: ExpandUtils
Kavin Varnan postet แล้ววิธีทำให้เค้าโครงเคลื่อนไหว ... แต่ถ้าคุณต้องการใช้ชั้นเรียนของฉันอย่าลังเลที่จะทำเช่นนั้นฉันโพสต์ส่วนสำคัญ: https://gist.github.com/MichaelFlisar/738dfa03a1579cc7338a
recyclerview
และคุณสามารถขยาย / ซ่อนอันที่ซ้อนกันนี้และใช้การเพิ่มประสิทธิภาพทั้งหมดของrecyclerview
คุณสามารถใช้ ExpandableLayout ที่เหมือนกับ CheckBox ภาพเคลื่อนไหวขยาย / ยุบได้อย่างราบรื่นดังนั้นคุณจึงสามารถใช้เป็น CheckBox ใน ListView และ RecyclerView
นี่คือโค้ดตัวอย่างสำหรับสิ่งที่@TonicArtosกล่าวถึงเพื่อเพิ่มและลบรายการและเพื่อทำให้เคลื่อนไหวในขณะที่ทำสิ่งนี้นำมาจากตัวอย่างRecyclerView AnimationsและGitHub
1)เพิ่ม Listener ภายในonCreateViewHolder ()ของคุณเพื่อลงทะเบียน onClick
2)สร้างOnClickListenerที่คุณกำหนดเองภายในอะแดปเตอร์ของคุณ
private View.OnClickListener mItemListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView tv = (TextView) v.findViewById(R.id.tvItems);
String selected = tv.getText().toString();
boolean checked = itemsList.get(recyclerView.getChildAdapterPosition(v)).isChecked();
switch (selected){
case "Item1":
if(checked){
deleteItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(false);
}else {
addItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(true);
}
break;
case "Item2":
if(checked){
deleteItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(false);
}else {
addItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(true);
}
break;
default:
//In my case I have checkList in subItems,
//checkItem(v);
break;
}
}
};
3)เพิ่ม addItem ของคุณ () และ deleteItem ()
private void addItem(View view){
int position = recyclerView.getChildLayoutPosition(view);
if (position != RecyclerView.NO_POSITION){
navDrawItems.add(position+1,new mObject());
navDrawItems.add(position+2,new mObject());
notifyItemRangeInserted(position+1,2);
}
}
private void deleteItem(View view) {
int position = recyclerView.getChildLayoutPosition(view);
if (position != RecyclerView.NO_POSITION) {
navDrawItems.remove(position+2);
navDrawItems.remove(position+1);
notifyItemRangeRemoved(position+1,2);
}
}
4) หาก RecyclerViewAdapter ของคุณไม่ได้อยู่ในกิจกรรมเช่นเดียวกับ Recycler ดูผ่านอินสแตนซ์ของrecyclerViewกับอะแดปเตอร์ขณะที่การสร้าง
5) itemList เป็น ArrayList ประเภทmObjectซึ่งช่วยรักษาสถานะของรายการ (เปิด / ปิด) ชื่อประเภทของรายการ (subItems / mainItem) และตั้งค่า Theme ตามค่า
public class mObject{
private String label;
private int type;
private boolean checked;
}