Giter Site home page Giter Site logo

thoughtbot / expandable-recycler-view Goto Github PK

View Code? Open in Web Editor NEW
2.1K 38.0 388.0 211 KB

Custom Android RecyclerViewAdapters that collapse and expand

Home Page: https://robots.thoughtbot.com/introducing-expandablerecyclerview

License: MIT License

Java 98.87% Shell 1.13%

expandable-recycler-view's Introduction

logo

Expandable RecyclerView CircleCI

Custom RecyclerViewAdapters for expanding and collapsing groups with support for multiple view types

Download

ExpandableRecyclerView:

compile 'com.thoughtbot:expandablerecyclerview:1.4'

ExpandableCheckRecyclerView:

compile 'com.thoughtbot:expandablecheckrecyclerview:1.4'

Usage

Let's say you are a rock star 🎸 and you want to build an app to show a list of your favorite Genres with a list of their top Artists.

First, define your custom ExpandableGroup class:

public class Genre extends ExpandableGroup<Artist> {

  public Genre(String title, List<Artist> items) {
    super(title, items);
  }
}

Next up, let's create the ChildViewHolder and GroupViewHolder. These are both wrappers around regular ol' RecyclerView.ViewHolders so implement any view inflation and binding methods you may need.

public class GenreViewHolder extends GroupViewHolder {

  private TextView genreTitle;

  public GenreViewHolder(View itemView) {
    super(itemView);
    genreTitle = itemView.findViewById(R.id.genre_title);
  }

  public void setGenreTitle(ExpandableGroup group) {
    genreTitle.setText(group.getTitle());
  }
}
public class ArtistViewHolder extends ChildViewHolder {

  private TextView artistName;

  public ArtistViewHolder(View itemView) {
    super(itemView);
    artistName = itemView.findViewById(R.id.artist_name);
  }

  public void setArtistName(Artist artist) {
    artistName.setText(artist.getTitle());
  }
}

Now we are ready for the juicy part - let's make our ExpandableRecyclerViewAdapter

By including your GroupViewHolder and ChildViewHolder in the definition of the class, you'll see that the onCreateGroupViewHolder and onCreateChildViewHolder methods return the correct type πŸ‘

public class GenreAdapter extends ExpandableRecyclerViewAdapter<GenreViewHolder, ArtistViewHolder> {

  public GenreAdapter(List<? extends ExpandableGroup> groups) {
    super(groups);
  }

  @Override
  public GenreViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.list_item_genre, parent, false);
    return new GenreViewHolder(view);
  }

  @Override
  public ArtistViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.list_item_artist, parent, false);
    return new ArtistViewHolder(view);
  }

  @Override
  public void onBindChildViewHolder(ArtistViewHolder holder, int flatPosition, ExpandableGroup group, int childIndex) {
    final Artist artist = ((Genre) group).getItems().get(childIndex);
    holder.setArtistName(artist.getName());
  }

  @Override
  public void onBindGroupViewHolder(GenreViewHolder holder, int flatPosition, ExpandableGroup group) {
    holder.setGenreTitle(group);
  }
}

Lastly you'll need either an Activity or Fragment to host your adapter. Once you've got that up and running, all that's left is to instantiate your fancy new GenreAdapter with a List<Genre>

public class GenreActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {

    ...

    List<Genre> genres = getGenres(); //see sample project's GenreDataFactory.java class for getGenres() method
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    LinearLayoutManager layoutManager = new LinearLayoutManager(this);

    //instantiate your adapter with the list of genres
    GenreAdapter adapter = new GenreAdapter(genres);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(adapter);

    ...

  }
}

Saving And Restoring Expand / Collapse State

If you want to save the expand and collapse state of your adapter, you have to explicitly call through to the adapters onSaveInstanceState() and onRestoreInstanceState()in the calling Activity

public class GenreActivity extends Activity {

  ...

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    adapter.onSaveInstanceState(outState);
  }

  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    adapter.onRestoreInstanceState(savedInstanceState);
  }
}

Programmatic Expanding and Collapsing

The ExpandableRecyclerViewAdapter exposes methods to control the expanded and collapsed state.

First up we have the toggles, .toggleGroup(int) and .toggleGroup(ExpandableGroup). These are handy for when you control the states explicitly.

public class GenreActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {

    ...

    Button showAllToggle = findViewById(R.id.show_all);
    showAllToggle.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        for (int i = adapter.groups().size() - 1; i >= 0; i--) {
          adapter.toggleGroup(i);
        }
      }
    });

  }
}

We also expose explicit methods to control the expanding and collapsing of specific groups, .expandGroup() and .collapseGroup(). For example, to expand the first group immediately:

public class GenreActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {

    ...

    adapter.expandGroup(0);

  }
}

Adding Custom Expand / Collapse Animations

If you want to add a custom Drawable that animates based on a groups state, override the expand() and collapse() methods in your GroupViewHolder:

public class GenreViewHolder extends GroupViewHolder {

  ...

  @Override
  public void expand() {
    animateExpand();
  }

  @Override
  public void collapse() {
    animateCollapse();
  }
}

Listening to Expand/Collapse events

If you want register an ExpandCollapseListener outside of the adapter, you can simply call setOnGroupExpandCollapseListener on the ExpandableRecyclerViewAdapter

  adapter.setOnGroupExpandCollapseListener(new GroupExpandCollapseListener() {
    @Override
    public void onGroupExpanded(ExpandableGroup group) {

    }

    @Override
    public void onGroupCollapsed(ExpandableGroup group) {

    }
  });

Multiple Child and Group Types

The MultiTypeExpandableRecyclerViewAdapter allows subclasses to implement multiple different view types for both children and groups.

Continuing with our genre example, let's say you wanted to display regular artists differently from your favorite artists. Let's start by making a new FavoriteArtistViewHolder

public class FavoriteArtistViewHolder extends ChildViewHolder {

  private TextView favoriteArtistName;

  public FavoriteArtistViewHolder(View itemView) {
    super(itemView);
    favoriteArtistName = (TextView) itemView.findViewById(R.id.list_item_favorite_artist_name);
  }

  public void setArtistName(String name) {
    favoriteArtistName.setText(name);
  }

Just like the regular ArtistViewHolder, FavoriteArtistViewHolder must extends ChildViewHolder.

Next up, let's create a subclass of MultiTypeExpandableRecyclerViewAdapter called MultiTypeGenreAdapter and let's add two static ints representing our two artist view types:

public class MultiTypeGenreAdapter extends MultiTypeExpandableRecyclerViewAdapter<GenreViewHolder, ChildViewHolder> {


  public static final int FAVORITE_VIEW_TYPE = 3;
  public static final int ARTIST_VIEW_TYPE = 4;
  ...

Notice we started used values > 2. That's because ExpandableListPosition.CHILD and ExpandableListPositon.GROUP are 1 and 2 respectively so they are already taken.

Since we only want a single view type for groups, we only need to override getChildViewType(). As getGroupViewType() will default to ExpandableListPosition.GROUP.

  @Override
  public int getChildViewType(int position, ExpandableGroup group, int childIndex) {
    if (((Genre) group).getItems().get(childIndex).isFavorite()) {
      return FAVORITE_VIEW_TYPE;
    } else {
      return ARTIST_VIEW_TYPE;
    }
  }

Since we provided custom view types for our children, we must also override isChild()

  @Override
  public boolean isChild(int viewType) {
    return viewType == FAVORITE_VIEW_TYPE || viewType == ARTIST_VIEW_TYPE;
  }

And now, just like in any other RecyclerView.Adapter in our onCreateChildViewHolder and our onBindChildViewHolder we can use the provided parameters to switch on the different view tyeps:

  @Override
  public ChildViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
    switch (viewType) {
      case ARTIST_VIEW_TYPE:
        View artist = from(parent.getContext()).inflate(R.layout.list_item_artist, parent, false);
        return new ArtistViewHolder(artist);
      case FAVORITE_VIEW_TYPE:
        View favorite =
            from(parent.getContext()).inflate(R.layout.list_item_favorite_artist, parent, false);
        return new FavoriteArtistViewHolder(favorite);
      default:
        throw new IllegalArgumentException("Invalid viewType");
    }
  }

  @Override
  public void onBindChildViewHolder(ChildViewHolder holder, int flatPosition, ExpandableGroup group,
      int childIndex) {
    int viewType = getItemViewType(flatPosition);
    Artist artist = ((Genre) group).getItems().get(childIndex);
    switch (viewType) {
      case ARTIST_VIEW_TYPE:
        ((ArtistViewHolder) holder).setArtistName(artist.getName());
        break;
      case FAVORITE_VIEW_TYPE:
        ((FavoriteArtistViewHolder) holder).setArtistName(artist.getName());
    }
  }

Expandable Check RecyclerView

An extension of expandablerecyclerview for checking single or multiple children within a group

The setup for the single and multi check versions is very similar to the expandablerecyclerview we walked through above. Here are a few of the notable differences...

CheckedExpandableGroup

Instead of ExpandableGroup you must use CheckedExpandableGroup. CheckedExpandableGroup is a subclass of ExpandableGroup that uses a SparseBooleanArray to hold onto which of it's children are checked.

The expandablecheckrecyclerview library comes with two default implementations - SingleCheckExpandableGroup and MultiCheckExpandableGroup.

Clearing Choices

The CheckableChildRecyclerViewAdapter has a clearChoices() which un checks any currently checked children.

CheckableChildViewHolder

The CheckableChildViewHolder is a subclass of ChildViewHolder that has a Checkable widget. The Checkable interface is initially not set, so in order to see your children view states update, you must set a View that implements Checkable in your view holder.

public class SingleCheckArtistViewHolder extends CheckableChildViewHolder {

  private CheckedTextView artistName;

  public SingleCheckArtistViewHolder(View itemView) {
    super(itemView);
    artistName = (CheckedTextView) itemView.findViewById(R.id.list_item_singlecheck_artist_name);
  }

  @Override
  public Checkable getCheckable() {
    return artistName;
  }
  ...
}

Listening to Child Click Events

There is a custom callback for click events on children of a CheckedExpandableGroup which returns you the View of the row item that was clicked, the current checked state of the child, the containing CheckedExpandableGroup group and the index of the child that was clicked.

  adapter.setChildClickListener(new OnCheckChildClickListener() {
    @Override
    public void onCheckChildCLick(View v, boolean checked, CheckedExpandableGroup group,
        int childIndex) {
    }
  });

Sample App

To see the complete code for all the above examples along with unit tests for the adapters check out the sample app. The app has the following packages:

expand

An example of basic ExpandableRecyclerViewAdapter

multicheck

An example of a CheckableChildRecyclerViewAdapter using MultiCheckExpandableGroup

single check

An example of a CheckableChildRecyclerViewAdapter using SingleCheckExpandableGroup

multi type

An example of a MultiTypeExpandableRecyclerViewAdapter using two different child view holders

Contributing

See the CONTRIBUTING document. Thank you, contributors!

License

Expandable RecyclerView is Copyright (c) 2016 thoughtbot, inc. It is free software, and may be redistributed under the terms specified in the LICENSE file.

About

Expandable RecyclerView is maintained by @mandybess

thoughtbot

Expandable RecyclerView is maintained and funded by thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc.

We love open source software! See our other projects or hire us to help build your product.

expandable-recycler-view's People

Contributors

antonyhaman avatar kershan avatar mike-burns avatar rajsuvariya1 avatar toomey8 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

expandable-recycler-view's Issues

Multiple Parent View Types + MultiTypeExpandableRecyclerViewAdapter

When combining these two features the checked positions change unpredictably. I assume it is because for example, lets say that group viewholder of type A stores the information about the children's checked status, but then viewholder of type B doesn't have that information.

Latency problem

Whenever i click on one of the checkboxes-there is quite a bit of delay till it accualy checks(and i dont mean animation) and i hate it, could u please fix it? it may have something to do with that it keeps trying to reload some of the groups (under the one thats child was checked)

value of edittext inside child changed on scroll

i have two buttons and one textview in each child row. those two buttons are used as triggers to count number and then write the number in textview. my problem is, the value of textview is always changes when i scroll the recyclerview and sometimes change the textview on neighbour child row. anyone can help ? thank you.

15240072_120300000948967656_247844965_n 1

when i click + on first row (1), textview on third row(2) is also changed.

Expand groups for the first time in onCreateGroupViewHolder()

Is there any idea for expanding groups for the first time launching recyclerview, here is my code but it has problem when I click to collapse the second time, it go into animateExpand() so that my indication arrow not animate the right way:

`@Override
public ChatGroupParentVH onCreateGroupViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext)
.inflate(R.layout.item_header, parent, false);
final ChatGroupParentVH holder = new ChatGroupParentVH(itemView);
new Handler().post(new Runnable() {
@OverRide
public void run() {
holder.expand();
onGroupClick(holder.getAdapterPosition());
}
});
return holder;
}

Thank you!`

#46 Error in readme file

In the following snippet
public class GenreViewHolder extends GroupViewHolder

private TextView genreTitle;

public GenreViewHolder(View itemView) {
super(itemView);
genreTitle = itemView.findViewById(R.id.genre_title);
}

public void setGenreTitle(ExpandableGroup group) {
genreTitle.setText(group.getTitle());
}
}

There is an error at
public class GenreViewHolder extends GroupViewHolder **{**

the opening bracket is missing.

toggleGroup does not work with groups off the screen

I needed an expandable recyclerview which allows only one group to be expanded at the time. I added the follwoing code to GenreAdapter in your sample project:

`private ExpandableGroup expandedGroup;
setOnGroupExpandCollapseListener(new GroupExpandCollapseListener() {
@OverRide
public void onGroupExpanded(ExpandableGroup group) {
if (expandedGroup != null){
toggleGroup(expandedGroup);
}
expandedGroup = group;
}

  @Override
  public void onGroupCollapsed(ExpandableGroup group) {

  }
});`

It works fine when the previously expanded group is visible on the screen. If the group is off the screen, it will not collapse when calling toggleGroup on it. Unless I am doing something wrong?

Looks like there is an infinite loop:

12-23 11:46:07.395 25187-25187/com.thoughtbot.expandablerecyclerview.sample E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.thoughtbot.expandablerecyclerview.sample, PID: 25187
java.lang.StackOverflowError: stack size 8MB
at com.thoughtbot.expandablerecyclerview.models.ExpandableListPosition.getRecycledOrCreate(ExpandableListPosition.java:115)
at com.thoughtbot.expandablerecyclerview.models.ExpandableListPosition.obtain(ExpandableListPosition.java:101)
at com.thoughtbot.expandablerecyclerview.models.ExpandableList.getUnflattenedPosition(ExpandableList.java:73)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.isGroupExpanded(ExpandCollapseController.java:63)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.toggleGroup(ExpandCollapseController.java:85)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.toggleGroup(ExpandableRecyclerViewAdapter.java:172)
at com.thoughtbot.expandablerecyclerview.sample.expand.GenreAdapter$1.onGroupExpanded(GenreAdapter.java:25)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.onGroupExpanded(ExpandableRecyclerViewAdapter.java:121)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.expandGroup(ExpandCollapseController.java:44)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.toggleGroup(ExpandCollapseController.java:89)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.toggleGroup(ExpandableRecyclerViewAdapter.java:172)
at com.thoughtbot.expandablerecyclerview.sample.expand.GenreAdapter$1.onGroupExpanded(GenreAdapter.java:25)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.onGroupExpanded(ExpandableRecyclerViewAdapter.java:121)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.expandGroup(ExpandCollapseController.java:44)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.toggleGroup(ExpandCollapseController.java:89)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.toggleGroup(ExpandableRecyclerViewAdapter.java:172)
at com.thoughtbot.expandablerecyclerview.sample.expand.GenreAdapter$1.onGroupExpanded(GenreAdapter.java:25)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.onGroupExpanded(ExpandableRecyclerViewAdapter.java:121)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.expandGroup(ExpandCollapseController.java:44)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.toggleGroup(ExpandCollapseController.java:89)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.toggleGroup(ExpandableRecyclerViewAdapter.java:172)
at com.thoughtbot.expandablerecyclerview.sample.expand.GenreAdapter$1.onGroupExpanded(GenreAdapter.java:25)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.onGroupExpanded(ExpandableRecyclerViewAdapter.java:121)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.expandGroup(ExpandCollapseController.java:44)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.toggleGroup(ExpandCollapseController.java:89)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.toggleGroup(ExpandableRecyclerViewAdapter.java:172)
at com.thoughtbot.expandablerecyclerview.sample.expand.GenreAdapter$1.onGroupExpanded(GenreAdapter.java:25)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.onGroupExpanded(ExpandableRecyclerViewAdapter.java:121)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.expandGroup(ExpandCollapseController.java:44)
at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.toggleGroup(ExpandCollapseController.java:89)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.toggleGroup(ExpandableRecyclerViewAdapter.java:172)
at com.thoughtbot.expandablerecyclerview.sample.expand.GenreAdapter$1.onGroupExpanded(GenreAdapter.java:25)
at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.onGroupExpanded(ExpandableRecyclerViewAdapter.java:121)
at com.thoughtbot.expandablerecyclerview.ExpandColl

Notify child item on adapter

How to notify when removing an item or inserting an item. i want to notify only particular group section to notify when changes happen not whole adapter. If anyone have a solution than please reply

Thank you in advance

Performance issue

I have an expandable view in which I have a rotation animation similar to the code samples. On group/parent views which have few child items, there is no problem. When there are larger number of child items (i.e. 39 children in my case), the arrow animation on expanding the group is slow and jumps states. When collapsing, the animation is smooth.

Make an interface for ExpandableGroup

Maybe have IExpandableGroup that is an interface which has exact contract that ExpandableGroup has.

This would allow developers to decide what their "Group" model extends from.

In my case, I need to extend BaseModel from dbFlow. I mean, of course I can create a wrapper class that contains my model and extends ExpandableGroup, but then I'm not sure that would even be compatible with my existing client code so a lot of classes might have to adapt.

By having IExpandableGroup, I just have to implement it in my existing model class and respect its contract.

ExpandableGroup can continue being the base class that people can use.

Yes, I know that's asking a lot.. Besides, I see some classes having to change when implementing this request, for example ExpandableRecyclerViewAdapter.onBindChildViewHolder(). It's a breaking change for sure.

RecyclerView HEIGHT=WRAP_CONTENT not working (hasFixedSize=true, setNestedScrollingEnabled=false)

I'm trying to implement an expandable list using this library but I need that my RecyclerView working with WRAP_CONTENT (auto update of height attribute).

I used hasFixedSize = true and setNestedScrollingEnabled=false but the LinearLayoutManager doesn't update the RecyclerView size.

My layout hierarchy will be like this:
= FrameLayout
== LinearLayout (Vertical)
=== LinearLayout (Horizontal)
=== RecyclerView
== LinearLayout (Vertical)

There are a custom layout manager to make this work? Thanks

Expand one row of list

Hi,
I want expand only one item at a time when I click on another list item previous should automatically collapse.

onGroupExpanded bug

when the child list of every group is empty you will get:

java.lang.RuntimeException: Unknown state at com.thoughtbot.expandablerecyclerview.models.ExpandableList.getUnflattenedPosition(ExpandableList.java:80) at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.onGroupExpanded(ExpandableRecyclerViewAdapter.java:119) at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.expandGroup(ExpandCollapseController.java:44) at com.thoughtbot.expandablerecyclerview.ExpandCollapseController.toggleGroup(ExpandCollapseController.java:77) at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.onGroupClick(ExpandableRecyclerViewAdapter.java:151) at com.thoughtbot.expandablerecyclerview.viewholders.GroupViewHolder.onClick(GroupViewHolder.java:28) at android.view.View.performClick(View.java:4881) at android.view.View$PerformClick.run(View.java:19592) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5756) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) at dalvik.system.NativeStart.main(Native Method)

when you try to expand the last group item

App crashes with empty list

When you start an adapter with an empty list like:

ArrayList<GroupObject> groupObjectList = new ArrayList<GroupObject>
MyAdaper adapter = new MyAdapter(groupObjectList)

it crashes, so for example if you are downloading objects and get an empty list you have to do some workarounds to use the adapter. I think this is because the numberOfVisibleItemsInGroup in ExpandableListClass always returns 1 or more, so itΒ΄s getting a java.lang.ArrayIndexOutOfBoundsException: length=0; index=0

Problems with saving state

Hello and thanks for this nice library.

However there're several problems:

  1. App crashes in onSaveInstanceState when it tries to cast List to ArrayList<? extends Parcelable> (Android Studio warns about unsafe cast):

@Override public void onSaveInstanceState(Bundle outState) { outState.putParcelableArrayList(CHECKED_STATE_MAP, (ArrayList<? extends Parcelable>) expandableList.groups); super.onSaveInstanceState(outState); }

I tried to fix this by changing List to ArrayList where required, but there's another problem:

  1. State is not saved correctly when app is killed by Android and restored (sometimes there's blank space instead of Groups captions, sometimes children views are of incorrect type)
    I tested multi-type checked recyclerview on Android 5.0.2

Cheers!

How do i expand an item after a network call?

when i click on a group item, i need to make a network call (so dont rightaway expand that group). expand the group and POPULATE subgroup items with data, only on the success callback of that network call. is this possible?

OnClickListener for Groups

I want to have an onclicklistener for a specific group holder. However, when I add an onclicklistener - the previous group holders cannot open.

NotifyDataSetChanged for add group is not working

Hi I want add group to the list when I clicked on the button but when click on button app is crash and I received the error length 2 index 2
this is my code in MainActivity

List<CommentTitle>  commentTitles = new ArrayList<>();
        List<Comment> comments1 = new ArrayList<>();
        List<Comment> comments2 = new ArrayList<>();

        comments1.add(new Comment("1395/12/8", "moein", "hello", 0, 10, 10));
        comments1.add(new Comment("1395/12/8", "moein", "hello", 1, 10, 10));
        comments1.add(new Comment("1395/12/8", "moein", "hello", 2, 10, 10));
        commentTitles.add(new CommentTitle("comment 1", comments1));

        comments2.add(new Comment("1395/12/8", "ali", "hello", 0, 10, 10));
        comments2.add(new Comment("1395/12/8", "reza", "hello", 1, 10, 10));
        comments2.add(new Comment("1395/12/8", "hassan", "hello", 2, 10, 10));
        commentTitles.add(new CommentTitle("comment 1", comments2));

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.commentList);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        commentAdapter = new CommentAdapter(commentTitles, context);
        recyclerView.setAdapter(commentAdapter);


Button send = (Button) findViewById(R.id.button);
               send.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                     
                            List<Comment> comments3 = new ArrayList<>();
                            comments3.add(new Comment("1395/12/8", "moein","Hello World!", 0, 10, 10));
                            commentTitles.add(new CommentTitle("c", comments3));
                            commentAdapter.notifyDataSetChanged();

                        
                    }
                });


Bug in ExpandCollapseController

The method "toggleGroup" in the ExpandCollapseController should return true if the group is expanded, after the toggle, false if the group is now collapsed, but it returns true if the group was expanded before the toggle.

Does it support subgroups and subchildren?

My scenario is as follow:

I have categories and subcategories and there is not limit to the depth of subcategories. (sub sub sub sub ..etc)

I also have products for each categories, these products have sub products, too.

Reload expandable-recycler-view

Hi. Thank for great library!
I implement this expandable-recycler-view for my project, but I don't know how to reload data for it.

You can write a tutorial or sample code?

Thank so much!

Expand a group programmatically

How can I expand a group programmatically?

For example I have 3 groups. And when user opens an activity - the groups should be expanded already (without making user to expand each group manually).

Maybe something like:
recyclerView.getGroup(1).expand()

p.s. Thanks for this great lib guys!

MultiTypeExpandableRecyclerView

Is it possible to have SingleCheckExpandableGroup and MultiCheckExpandableGroup in same adapter?
Iw tried using MultiTypeExpandableRecyclerViewAdapter but single checkable groups are not working(im able to check all of the items)

Last group expand issue

When I scroll down list to the last item and click in group item the child cannot show, it out off screen. After collapsing that and clicking in another group item throw exception
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{949ddf4 position=17 id=-1, oldPos=16, pLpos:16 scrap [attachedScrap] tmpDetached no parent}

IndexOutOfBoundsException when back button pressed

This error appear even if i unsure the data is not empty or null in the onSaveInstace method
The trace of the Error :

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.thoughtbot.expandablerecyclerview.models.ExpandableGroup.writeToParcel(ExpandableGroup.java:67)
at android.os.Parcel.writeParcelable(Parcel.java:1357)

ExpandableGroup didn't have consistent setting for write and read parcelable

whether the item is null or not, it will all write an int into parcelable, in the read setting, only if the item is not null will call readInt, this will cause error in extended class

protected ExpandableGroup(Parcel in) {
title = in.readString();
if (in.readByte() == 0x01) {
int size = in.readInt();
items = new ArrayList(size);
Class type = (Class) in.readSerializable();
in.readList(items, type.getClassLoader());
} else {
items = null;
}
}

@OverRide
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
if (items == null) {
dest.writeByte((byte) (0x00));
dest.writeInt(0);
} else {
dest.writeByte((byte) (0x01));
dest.writeInt(items.size());
final Class<?> objectsType = items.get(0).getClass();
dest.writeSerializable(objectsType);
dest.writeList(items);
}
}

NotifyItemChanged does not call onBindChildViewHolder

I am clicking an item (child), opens a dialog fragment. If CANCEL is pressed then nothing happens and if OK is pressed then the background color of the childview changes.

This is notified through notifyItemChanged(). If the group is collapsed and expanded again then the data change gets reflect but it does not get reflected if the group remains expanded.

For the change to be reflected immediately I have tried the following

  1. DefaultItemAnimator animator = new DefaultItemAnimator() { @Override public boolean canReuseUpdatedViewHolder(RecyclerView.ViewHolder viewHolder) { return true; } }; rvFoodList.setItemAnimator(animator);

  2. ((DefaultItemAnimator) rvFoodList.getItemAnimator()).setSupportsChangeAnimations(false);

  3. rvFoodList.setItemAnimator(null);

  4. ((SimpleItemAnimator) rvFoodList.getItemAnimator()).setSupportsChangeAnimations(true);

None of these work.

Please tell how can I achieve this?

Examples with the XML layout files

Hello, the documentation is great for the Java part of the library. Can you provide the layout files in the docs too?
The genre_title, artist_name, list_item_genre, list_item_artist and recycler_view.
How does one talk to the other?
Or if there's another source of documentation with a full look at what the code looks like, can you point me in that direction?

Much appreciated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.