Android 带有 RecyclerView 的可扩展列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26419161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Expandable list with RecyclerView?
提问by Dariusz Rusin
It's possible to use expandable list items with new RecyclerView? Like ExpandableListView?
可以在新的 RecyclerView 中使用可扩展的列表项吗?喜欢 ExpandableListView?
回答by Tonic Artos
This is simple to do with the stock LayoutManagers, it all depends on how you manage your adapter.
这对于库存 LayoutManagers 来说很简单,这完全取决于您如何管理适配器。
When you want to expand a section you just add new items to your adapter after the header. Remember to call notifyItemRangeInserted when you do this. To collapse a section you simply remove the relevant items, and call notifyItemRangeRemoved(). For any data changes that are appropriately notified, the recycler view will animate the views. When adding items, an area to be filled with the new items is made, with the new items fading in. Removal is the opposite. All you need to do besides the adapter stuff is to style your views to convey the logical structure to the user.
当您想要扩展一个部分时,您只需在标题之后向您的适配器添加新项目。请记住在执行此操作时调用 notifyItemRangeInserted。要折叠一个部分,您只需删除相关项目,然后调用 notifyItemRangeRemoved()。对于适当通知的任何数据更改,回收器视图将为视图设置动画。添加项目时,会创建一个区域以填充新项目,新项目淡入。删除则相反。除了适配器之外,您需要做的就是设置视图样式以将逻辑结构传达给用户。
Update: Ryan Brooks has now written an articleon how to do this.
回答by Kavin Varnan
Get the sample code implementation from here
从这里获取示例代码实现
Set ValueAnimator inside onClick of ViewHolder
在 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();
}
Here is the final code
这是最终的代码
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();
}
}
回答by Xinzz
https://github.com/gabrielemariotti/cardslib
https://github.com/gabrielemariotti/cardslib
This library has an implementation of an expandable list with a recyclerview (refer to the demo app under "CardViewNative" --> "List, Grid, and RecyclerView" --> "Expandable cards"). It also has a lot of other cool combinations of cards/lists.
这个库有一个带有回收视图的可扩展列表的实现(请参阅“CardViewNative”-->“列表、网格和RecyclerView”->“可扩展卡片”下的演示应用程序)。它还有很多其他很酷的卡片/列表组合。
回答by prom85
Someone complained about that the above mentioned solution is not usable with a listview as expandable content. But there's a simple solution: create a listview and fill this listview manually with your rows.
有人抱怨上述解决方案不适用于列表视图作为可扩展内容。但是有一个简单的解决方案:创建一个列表视图并用您的行手动填充此列表视图。
Solution for the lazy ones:there's a simple solution if you don't want to change your code to much. Just manually use your adapter to create viewsand add them to the LinearLayout
.
懒人的解决方案:如果您不想对代码进行太多更改,有一个简单的解决方案。只需手动使用您的适配器创建视图并将它们添加到LinearLayout
.
Here's the example:
这是示例:
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);
}
helper functions: getThemeReference
辅助函数: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;
}
}
helper class: ExpandUtils
辅助类:ExpandUtils
Kavin Varnan postet already how to animate a layout... But if you want to use my class, feel free to do so, I posted a gist: https://gist.github.com/MichaelFlisar/738dfa03a1579cc7338a
Kavin Varnan postet 已经如何为布局设置动画...但是如果你想使用我的课程,请随意使用,我发布了一个要点:https: //gist.github.com/MichaelFlisar/738dfa03a1579cc7338a
回答by user2914737
You can use ExpandableLayout that like a smooth expand/collapse animation CheckBox, so you can use it as CheckBox in ListView and RecyclerView.
您可以使用像平滑展开/折叠动画 CheckBox 的 ExpandableLayout,因此您可以将其用作 ListView 和 RecyclerView 中的 CheckBox。
回答by Ujju
This is the sample code for what is mentioned by @TonicArtosto add and remove Items and to animate it while doing, this is taken from RecyclerView Animationsand GitHub sample
这是@TonicArtos提到的用于添加和删除项目并在执行时为其设置动画的示例代码,这取自RecyclerView Animations和GitHub 示例
1)Add Listener inside your onCreateViewHolder()to register for onClick
1)在onCreateViewHolder( ) 中添加监听器来注册 onClick
2)Create your custom OnClickListenerinside your Adapter
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)Add your addItem() and deleteItem()
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)If your RecyclerViewAdapter is not in the same Activity as Recycler View, pass instance of recyclerViewto the Adapter while creating
4)如果您的 RecyclerViewAdapter 与 Recycler View 不在同一个 Activity 中,则在创建时将recyclerView 的实例传递给 Adapter
5)itemList is a ArrayList of type mObjectwhich helps maintain states of item (Open/Close) , name, type of Item(subItems/mainItem) and set Theme based on values
5)itemList中是类型的ArrayList的mObject这有助于基于值维持(打开/关闭))项的状态,名称,类型项目的(子项/ mainItem和集主题
public class mObject{
private String label;
private int type;
private boolean checked;
}