使用RecyclerView展开列表?
新的RecyclerView可以使用可扩展列表项吗? 像ExpandableListView?
这对于布局pipe理员来说很简单,这完全取决于你如何pipe理你的适配器。
当你想扩展一个部分时,只需在标题后添加新的项目到你的适配器。 请记住在执行此操作时调用notifyItemRangeInserted。 要折叠某个部分,只需删除相关的项目,然后调用notifyItemRangeRemoved()。 对于适当通知的任何数据更改,回收站视图将为视图添加animation。 添加项目时,将填充新项目的区域,新项目消失。移除是相反的。 除了适配器之外,您所需要做的只是devise您的视图以将逻辑结构传达给用户。
更新:瑞安布鲁克斯现在写了一篇关于如何做到这一点的文章 。
从这里获取示例代码实现
在ViewHolder的onClick中设置ValueAnimator
@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(); } }
https://github.com/gabrielemariotti/cardslib
这个库有一个带有recyclerview的可扩展列表实现(参考“CardViewNative” – >“List,Grid和RecyclerView” – >“扩展卡”下的演示程序)。 它也有很多卡/列表的其他很酷的组合。
有人抱怨说,上面提到的解决scheme不能用作可扩展内容的列表视图。 但是有一个简单的解决scheme: 创build一个列表视图,并用你的行手动填充这个列表视图 。
对懒惰的解决scheme:如果你不想改变你的代码,有一个简单的解决scheme。 只需手动使用您的适配器来创build视图并将其添加到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已经如何animation布局…但是,如果你想使用我的课程,请随时这样做,我张贴了一个要点: https : //gist.github.com/MichaelFlisar/738dfa03a1579cc7338a
您可以使用ExpandableLayout,就像一个平滑的展开/折叠animationcheckbox,所以你可以在ListView和RecyclerView中使用它作为checkbox。
这是@TonicArtos提到的用于添加和删除项目的示例代码,并在执行时为其设置animation,这取自RecyclerViewanimation和GitHub示例
1)添加监听器在你的onCreateViewHolder()注册onClick
2)在适配器内部创build自定义的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 View不在同一个Activity中 ,请在创build时将recyclerView的实例传递给适配器
5) itemList是一个types为mObject的ArrayList,它帮助维护项目(Open / Close),名称,Item的types(subItems / mainItem)的状态,并根据值设置Theme
public class mObject{ private String label; private int type; private boolean checked; }