10

I have this very weird bug on my app. Every time I open my app my view works perfectly, but when I try to put my app in background and open my app again, my recycler view resizes.

Here's an image to describe it properly:

This is the correct image:

enter image description here

This is the image that messes up my recyclerview when the app is on background, then I open it again.

enter image description here

There are also times that all images in my recyclerview are gone. Here's a screenshot:

enter image description here

This is my onResume() code:

public void onResume()
 {
   Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
   if (fragment instanceof MenuFragment)
   {
     FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
     transaction.remove(fragment);
     transaction.commit();
     transaction = getSupportFragmentManager().beginTransaction();
     transaction.replace(R.id.fragment_container, fragment);
     transaction.addToBackStack(null);
     transaction.commit();

   }
 }

This is my view pager layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/app_background">
    <android.support.constraint.ConstraintLayout
        android:id="@+id/action_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <include
            android:id="@+id/nav_bar"
            layout="@layout/home_screen_navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </android.support.constraint.ConstraintLayout>

    <com.yotadevices.widget.RtlViewPager
        android:id="@+id/menuFragment_viewPager"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/transparent"
        app:layout_constraintBottom_toTopOf="@+id/buttons"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/nav_bar"/>
    <include
        android:id="@+id/buttons"
        layout="@layout/navigation_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/menuFragment_viewPager" />
</android.support.constraint.ConstraintLayout>

Here's my list layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent"
    android:orientation="vertical">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>

What do you think is the problem here?

PS: The bug occurs only on selected phones. Not all. We've tested this on Samsung Galaxy s8+ and it works well.

Hardik Vasani
  • 828
  • 1
  • 8
  • 13
PinoyStackOverflower
  • 4,622
  • 13
  • 50
  • 113

6 Answers6

2

I have solved the problem by breaking part the included layouts. So instead of adding an included layout, I just transferred all the included in to the main XML layout.

Even though this fixed the problem, i still do not know why the bug occurred in the first place.

PinoyStackOverflower
  • 4,622
  • 13
  • 50
  • 113
1

If you are using only single child view, it's better to use FrameLayout. Then in RecyclerView use match_parent parameters in layout attribute, so your code should look like this:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

By the way my best method to debug scenarios like this is to write android:background="#0000FF" in every view, to see how it inflates.

Equa
  • 54
  • 5
  • Thanks for the tip on how to debug, but I already did that. I also did using FrameLayout, but it doesn't do anything. – PinoyStackOverflower Apr 23 '18 at 08:39
  • Does it allow to scroll at least a bit inside recyclerview? – Equa Apr 23 '18 at 08:42
  • Yes it does scroll. If the view is still visible, it can be scrolled. Hope this helps. – PinoyStackOverflower Apr 23 '18 at 08:44
  • `ScrollView` probably messes up with `RecyclerView` try to get `RecyclerView` items height sum and then set it to `RecyclerView`, you can find how its done in this answer: https://stackoverflow.com/a/28498247/9389798 – Equa Apr 23 '18 at 08:46
  • Is a ViewPager considered a ScrollView? If that is not the case, then I don't have a RecyclerView inside a ScrollView. – PinoyStackOverflower Apr 23 '18 at 08:51
  • `app:layout_constraintTop_toBottomOf="@+id/activity_menu_hScrollView"` Have you tried changing this constraint inside `ViewPager` to parrent? – Equa Apr 23 '18 at 08:55
  • Sorry, I think you thought I have a RecyclerView inside the HorizontalScrollView. That is not the case. I have edited my question and information for clarity. – PinoyStackOverflower Apr 23 '18 at 09:00
  • Oh sorry I mistaken. Have you tried detaching and then attaching fragment instead of replacing it? Like so: `getSupportFragmentManager().beginTransaction().detach(this).attach(this).commit();` – Equa Apr 23 '18 at 09:11
  • Actually, I already did that. We just replaced that with `replaced()`. You can check that on my `onResume()` code. – PinoyStackOverflower Apr 23 '18 at 09:19
0
  • You don't need to first remove the old fragment if you are going to call replace(R.id.container_id, newFragment);
  • You don't need to call commit after every change (remove(), replace(), etc.), call all your changes then end it with a commit()
  • If your activity did not lose/change its state (e.g. rotate), then you are just removing and adding the same fragment for no reason
  • You are checking if it is a MenuFragment in the if statement, then, oddly enough, if the condition holds, you go and re-add the MenuFragment, when you should probably replace it if it's not a MenuFragment

    if (!(fragment instanceof MenuFragment)) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        Fragment menuFragment = new MenuFragment();
        // pass any data...
        transaction.replace(R.id.fragment_container, menuFragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }
    

Adding Log.d(TAG, "method name") in your onResume(), onPause() might help you know what's happening.

Also, checking the view hierarchy in Tools > Layout Inspector might also help.

Enabling Settings > Developer Options > Show Layout Bounds on your emulator might also help.

Let me know if I had anything wrong. Also let me know if any of this works for you.

Ace
  • 689
  • 6
  • 21
0

To start off, declare your layouts in a more specific way rather than using root elements that are certainly not used.

Here's the list layout:

<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Second, the onPause is mainly responsible for saving the app state automatically if you don't have much to implement. It is best to remove the onResume and let it take care of itself.

Lucem
  • 2,423
  • 2
  • 16
  • 29
0

keep width of recyclerview as match_parent and height as wrap_content, after that ,for your item layout,put height and width as a fixed value,such as 50dp or 70dp, which can keep the item's height and width same in any mode u want. i hope this helps,if this answer is not helpful,please ignore this answer.

0

You must use a subclass of android.support.v4.app.FragmentStatePagerAdapter to load Fragments rather then putting code in on resume.

public class PagerAdapter extends FragmentStatePagerAdapter {

    private static final int ITEMS = 4;

    PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        switch (i) {
            case 0:
                return Fragment1.newInstance();
            case 1:
                return Fragment2.newInstance();
            case 2:
                return Fragment3.newInstance();
            case 3:
                return Fragment4.newInstance();
        }

        return null;
    }

    @Override
    public int getCount() {
        return ITEMS;
    }

}

The new instance method of each fragment must be:

public static Fragment1 newInstance() {
    return new Fragment1 ();
}

In your activity write following in onCreate method:

PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
//rtlViewPager -- object of RtlViewPager
rtlViewPager.setAdapter(pagerAdapter);
rtlViewPager.setOffscreenPageLimit(4);
ANUJ TAYAL
  • 106
  • 5