1

I have two fragments: A & B.

Fragment B contains SearchView and RecyclerView.

adapter = new SearchListAdapter(items);

recyclerView = new RecyclerView(getContext());
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.addRule(BELOW, SEARCH_VIEW_ID);
addView(recyclerView, params);

@Override
public boolean onQueryTextChange(String newText)
{
    ArrayList<MyModel> filteredModelList = adapter.filter(newText);
    recyclerView.scrollToPosition(0);

    return true;
}

Implementing filtering is taken away: How to filter a RecyclerView with a SearchView

PROBLEM

1) At the beginning we are on a fragment A, then go to the fragment B is administered in SearchView more characters and get a filtered list (for example consisting of a single element).

2) Next, through getFragmentManager().popBackStack(); we return to fragment A.

3) At the same time, in the fragment B in the method of onStop(); we clean SearchView:

@Override
public void onStop()
{
    if(searchView != null)
    {
        searchView.setQuery("", false);
    }
}

4) Next, we return to the fragment B and get an error:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 1(offset:35).state:35

I've been looking at this problem and found the following:

a) Issue 77846

b) Issue 77232

c) habra

d) recyclerview layoutmanager part 1 (generateDefaultLayoutParams)

e) IndexOutOfBoundsException Invalid item position XX(XX). Item count:XX

He came to the conclusion that this is a bug recyclerview and it has not yet been fixed.

As a result, it was necessary to implement filtering without animation:

public void filter(String charText)
{
    charText = charText.toLowerCase();
    mItems = new ArrayList<MyModel>();
    if (charText.length() == 0)
    {
        mItems.addAll(mOriginalItems);
    }
    else
    {
        for (MyModel model : mOriginalItems)
        {
            String textId = model.getId().toLowerCase();
            if (textId.contains(charText))
            {
                mItems.add(model);
            }
        }
    }

    notifyDataSetChanged();
}

Is this true, and there is an error in the code?

Thank you!

UPDATE

Activity:

public class MyActivity extends AppCompatActivity

SimpleFragmentManager:

private static void moveTo(BaseFragment fragment)
{
    if(fragment != null)
    {
        FragmentManager fragmentManager = _activity.getFragmentManager();
        FragmentTransaction ft = fragmentManager.beginTransaction();
        BaseFragment currentFragment = getCurrentFragment();

        if(fragment != currentFragment)
        {
            ft.replace(_containerId, fragment, fragment.getType());
            if (currentFragment != null) ft.addToBackStack(null);
            ft.commit();
        }
    }
}

Fragment A & B:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    if(view == null)
    {
        view = new ALayout(container.getContext());
        //if fragment B then > view = new BLayout(container.getContext());
        view.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
    }

    return view;
}

ALayout & BLayout is extends RelativeLayout

BLayout with SearchView and RecycleView I showed above.

Important Notice:

1) if comment out line: recyclerView.scrollToPosition(0); - no bug! (and no scroll top :) )

2) More precise conditions for obtaining bug:

a) Go to the fragment_1 track on the fragment_2;

b) Enter a query in the search (String is present: recyclerView.scrollToPosition(0));

c) Return to fragment_1 (this time a search query to clean - no errors!);

d) We will again go to the fragment_2.

>>We get a error!

a) Go to the fragment_1 track on the fragment_2;

b) Do not enter anything in the search (String is present: recyclerView.scrollToPosition (0));

c) Go back to the fragment_1. (this time a search query to clean - no errors!);

d) Once again we are going to fragment_2.

>>No error!

Community
  • 1
  • 1
0x131313
  • 2,107
  • 2
  • 15
  • 18
  • Maybe I just need to see more code, but can I ask you how it is handled the list of items to be displayed in adapter? In `filter` method I see you are initializing `mItems`, but I don't see you pass it to the adapter. – andrea.petreri Feb 07 '16 at 08:40
  • @thetonrifles the method filter() is in adapter class. And mItems is ArrayList with models. The problem is not shown, the filter method. The problem, if you use the method with the animation of the link threads. – 0x131313 Feb 07 '16 at 11:20
  • oh yes, I see now. Looking at error you get I think this could be related to some notify method, but I'm not sure it's a bug. I would like to try reproducing your scenario. Is it possible for you to share in some way the full code? I mean, activity, fragments and adapter. – andrea.petreri Feb 07 '16 at 11:49
  • @thetonrifles updated! – 0x131313 Feb 08 '16 at 09:27
  • ok thanks! ... I'm going to check within today. I just have another question about filtering. You wrote that for having everything working you needed to disable animations. Do you mean that instead of `notifyDataSetChanged` you was using other notify methods? In case could you share code you was using in that part too? – andrea.petreri Feb 08 '16 at 09:45
  • @thetonrifles Implementing filtering is taken away: How to filter a RecyclerView with a SearchView (http://stackoverflow.com/questions/30398247/how-to-filter-a-recyclerview-with-a-searchview). And my filtering without animation working good! – 0x131313 Feb 08 '16 at 09:46
  • @thetonrifles maybe you have some news? – 0x131313 Feb 12 '16 at 10:05
  • Unfortunately not yet. I didn't have so much time for trying to reproduce the issue. I will be surely able during weekend. – andrea.petreri Feb 12 '16 at 10:06
  • I've tried to reproduce the issue but I'm having some difficulties because I don't know exactly how the full activity and fragments are implemented. I've put an implementation on [a specific branch on this repository](https://github.com/thetonrifles/android-recycler-grid/tree/so-35239448). Maybe this could be a starting point for understanding what's happening in your case. – andrea.petreri Feb 14 '16 at 20:55
  • @thetonrifles added project here: https://goo.gl/1uKqSX – 0x131313 Feb 15 '16 at 12:35
  • ok thanks... I'm going to check today (this evening I think) – andrea.petreri Feb 15 '16 at 13:17
  • 1
    Using logs and debugger it seems that when you go back and forward again, view within `FragmentC` is not null. I'm still trying to understand why, but for preventing crash you just need to override in `FragmentC` method `onDestroy` and include inside `view = null;`. Hope this could be a starting point. – andrea.petreri Feb 15 '16 at 20:17
  • @thetonrifles but I don't remove my fragment-view. I want keep it and reuse it. Added important notice on post! – 0x131313 Feb 18 '16 at 10:49
  • yes ok... what I mean is that if you debug code, problem occurs because of check `view==null` [here](https://github.com/Z-13/RecyclerViewBug/blob/master/app/src/main/java/com/thetonrifles/recyclergrid/FragmentC.java#L26). If you remove this check... everything works fine. It's like if, since you are not rebuilding your view, there is a misalignment between data and visualization. If you want to keep check on `view`, we should find another way of reloading it for avoiding eventual inconsistencies with data. – andrea.petreri Feb 18 '16 at 11:01
  • @thetonrifles And you read the Important Notice, may have any thoughts on this? – 0x131313 Feb 18 '16 at 11:05
  • Yes I read this and tried with code you shared. It occurs exactly for what I wrote you. I mean, because view is not recreated and keeps a status that seems not consistent with data. If you remove check on view, you can keep also `recyclerView.scrollToPosition(0)`. In this sense I think problem is understanding which approach you prefer to follow (or better, which behavior you want to get). You can put view = null in onDestroy or remove check view == null during creation... or find a way for restoring view initial state. – andrea.petreri Feb 18 '16 at 11:10
  • @thetonrifles ok. After testing, I came to the conclusion that the error is still due to the animation, or rather re-arrange elements (probably not true). Because without animation - there is no error. Thank you very much for your help! – 0x131313 Feb 18 '16 at 12:00
  • Glad I could help :) – andrea.petreri Feb 18 '16 at 12:02
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/103835/discussion-between-0x131313-and-thetonrifles). – 0x131313 Feb 18 '16 at 12:05

0 Answers0