Có thể sử dụng các mục danh sách có thể mở rộng với RecyclerView mới không? Thích ExpandableListView?
Có thể sử dụng các mục danh sách có thể mở rộng với RecyclerView mới không? Thích ExpandableListView?
Câu trả lời:
Điều này rất đơn giản để thực hiện với LayoutManagers có sẵn, tất cả phụ thuộc vào cách bạn quản lý bộ điều hợp của mình.
Khi bạn muốn mở rộng một phần, bạn chỉ cần thêm các mục mới vào bộ điều hợp sau tiêu đề. Hãy nhớ gọi thông báo ItemRangeInserted khi bạn làm điều này. Để thu gọn một phần, bạn chỉ cần loại bỏ các mục có liên quan và gọi thông báo SmartItemRangeRemoved (). Đối với bất kỳ thay đổi dữ liệu nào được thông báo thích hợp, chế độ xem trình tái chế sẽ tạo hoạt ảnh cho các chế độ xem. Khi thêm các mục, một khu vực được lấp đầy với các mục mới sẽ được tạo ra, với các mục mới sẽ mờ dần. Việc loại bỏ ngược lại. Tất cả những gì bạn cần làm ngoài công cụ điều hợp là tạo kiểu cho các quan điểm của bạn để truyền tải cấu trúc hợp lý cho người dùng.
Cập nhật: Ryan Brooks hiện đã viết một bài báo về cách thực hiện việc này.
Nhận triển khai mã mẫu từ đây
Đặt ValueAnimator bên trong onClick of 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();
}
Đây là mã cuối cùng
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
", bởi vì nội dung mở rộng trong trường hợp đó là một danh sách với các mục đến từ bộ điều hợp. Đây là một giải pháp thoái hóa chỉ được phép sử dụng 1 mục là trẻ em trong nhóm.
https://github.com/gabrielemariotti/cardslib
Thư viện này có triển khai danh sách có thể mở rộng với chế độ xem lại (tham khảo ứng dụng demo trong "CardViewNative" -> "Danh sách, Grid và RecyclerView" -> "Thẻ có thể mở rộng"). Nó cũng có rất nhiều kết hợp thẻ / danh sách thú vị khác.
Có người phàn nàn rằng giải pháp được đề cập ở trên không thể sử dụng được với listview là nội dung có thể mở rộng. Nhưng có một giải pháp đơn giản: tạo một listview và điền thủ công listview này vào các hàng của bạn .
Giải pháp cho những kẻ lười biếng: có một giải pháp đơn giản nếu bạn không muốn thay đổi nhiều mã của mình. Chỉ cần sử dụng thủ công bộ điều hợp của bạn để tạo chế độ xem và thêm chúng vào LinearLayout
.
Đây là ví dụ:
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);
}
chức năng trợ giúp: 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;
}
}
lớp trợ giúp: ExpandUtils
Bài đăng của Kavin Varnan đã có cách tạo hiệu ứng cho bố cục ... Nhưng nếu bạn muốn sử dụng lớp học của tôi, vui lòng làm như vậy, tôi đã đăng ý chính: https://gist.github.com/MichaelFlisar/738dfa03a1579cc7338a
recyclerview
và bạn có thể mở rộng / ẩn cái lồng nhau này và sử dụng tất cả các tối ưu củarecyclerview
Bạn có thể sử dụng ExpandableLayout giống như một CheckBox hoạt ảnh mở rộng / thu gọn mượt mà, vì vậy bạn có thể sử dụng nó như CheckBox trong ListView và RecyclerView.
Đây là mã mẫu cho những gì được đề cập bởi @TonicArtos để thêm và xóa các Mục và để tạo hoạt ảnh trong khi thực hiện, mã này được lấy từ mẫu RecyclerView Animations và GitHub
1) Thêm Trình xử lý bên trong onCreateViewHolder () của bạn để đăng ký onClick
2) Tạo OnClickListener tùy chỉnh của bạn bên trong Bộ điều hợp của bạn
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) Thêm addItem () và deleteItem () của bạn
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) Nếu RecyclerViewAdapter của bạn không có cùng Hoạt động với Recycler View , hãy chuyển phiên bản của recyclerView vào Bộ điều hợp trong khi tạo
5) itemList là ArrayList kiểu mObject giúp duy trì trạng thái của item (Open / Close), tên, loại Item (subItems / mainItem) và đặt Theme dựa trên các giá trị
public class mObject{
private String label;
private int type;
private boolean checked;
}