安卓 - 应用在后台时 Recycler view 改变大小

10

我在我的应用中遇到了一个非常奇怪的bug。每次我打开我的应用时,视图都可以完美地工作,但是当我尝试将应用程序放在后台并再次打开它时,我的回收站视图会改变大小。

这里有一张图片来更好地描述它:

这是正确的图片:

enter image description here

这是导致我的recyclerview混乱的图片,当应用在后台运行,然后我再次打开它时:

enter image description here

有时候我的recyclerview中所有的图片都消失了。这是一个截图:

enter image description here

这是我的onResume()代码:

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();

   }
 }

这是我的视图翻页布局:

<?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>

这是我的列表布局:

<?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>

你认为这里的问题是什么?

附注:该故障仅在某些手机上发生。并非全部。我们已在三星Galaxy s8+上进行了测试,结果良好。


你能把你的onResume代码发给我们吗?谢谢。 - JA Arce
@JAArce 我已经添加了我的 onResume 代码以及我的布局。 - PinoyStackOverflower
你为什么将RecyclerView的高度和宽度设置为0dp?@PinoyStackOverflower - TheLittleNaruto
@TheLittleNaruto 因为我正在使用 ConstraintLayout,所以我已经将 RecyclerView 锚定到父级,并将高度和宽度设置为 0,以匹配约束条件。如果我做错了,请告诉我,我很乐意听取您的意见。谢谢。 - PinoyStackOverflower
@yunard - 我不这么认为。它是不同的。 - PinoyStackOverflower
显示剩余11条评论
6个回答

2

我通过分解包含的布局来解决了这个问题。因此,我没有添加一个包含的布局,而是将所有包含的内容转移到了主XML布局中。

虽然这样修复了问题,但我仍然不知道为什么出现了这个错误。


1
如果您只使用单个子视图,最好使用FrameLayout。然后在RecyclerView中使用match_parent参数的layout属性,这样您的代码应该如下所示:
<?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>

顺便说一下,我调试类似情况的最佳方法是在每个视图中编写android:background="#0000FF",以查看它如何膨胀。

谢谢你关于如何调试的提示,但我已经这样做了。我也尝试使用FrameLayout,但它没有任何作用。 - PinoyStackOverflower
ScrollView 可能会干扰 RecyclerView,尝试获取 RecyclerView 子项的高度总和并将其设置为 RecyclerView 的高度。您可以在此答案中找到如何完成:https://dev59.com/il4d5IYBdhLWcg3wLf_P#28498247 - Equa
抱歉,我觉得你误以为我在HorizontalScrollView里面有一个RecyclerView。事实并非如此。我已经编辑了我的问题和信息以便更清楚明了。 - PinoyStackOverflower
哦,抱歉我搞错了。你尝试过分离然后再附加片段而不是替换它吗?像这样:getSupportFragmentManager().beginTransaction().detach(this).attach(this).commit(); - Equa
其实,我已经做过了。我们刚刚用 replaced() 替换了它。你可以在我的 onResume() 代码中查看。 - PinoyStackOverflower
显示剩余4条评论

0
  • 如果你要调用replace(R.id.container_id, newFragment);,就不需要先删除旧的片段。
  • 在每次更改(remove(), replace()等)后不需要调用commit(),应该把所有变化都执行完毕后再以commit()结束。
  • 如果你的活动没有失去或改变其状态(例如旋转),那么你只是无缘无故地删除和添加同一个片段。
  • if语句中,你正在检查是否为MenuFragment,但是,奇怪的是,如果条件成立,你会重新添加MenuFragment,当然,如果不是MenuFragment,你应该替换它。

    if (!(fragment instanceof MenuFragment)) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        Fragment menuFragment = new MenuFragment();
        // 传递任何数据...
        transaction.replace(R.id.fragment_container, menuFragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }
    

在你的onResume()onPause()中添加Log.d(TAG, "method name")可能会帮助你了解发生了什么。

此外,在工具 > 布局检查器中检查视图层次结构也可能有所帮助。

在模拟器上启用设置 > 开发者选项 > 显示布局边界也可能有所帮助。

如果我有任何错误,请告诉我。同时,如果这些方法对你有用,请告诉我。


0
首先,以更具体的方式声明您的布局,而不是使用肯定不会使用的根元素。
以下是列表布局:
<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"/>

其次,如果你没有太多需要实现的内容,onPause 主要负责自动保存应用程序状态。最好删除 onResume 并让它自行处理。


0

在编写代码时,应该使用android.support.v4.app.FragmentStatePagerAdapter的子类来加载Fragments,而不是将代码放在onResume()方法中。

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;
    }

}

每个片段的新实例方法必须是:
public static Fragment1 newInstance() {
    return new Fragment1 ();
}

在你的活动中,在onCreate方法中编写以下内容:
PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
//rtlViewPager -- object of RtlViewPager
rtlViewPager.setAdapter(pagerAdapter);
rtlViewPager.setOffscreenPageLimit(4);

0

recyclerview的宽度保持为match_parent,高度保持为wrap_content, 然后,对于您的项目布局,请将高度和宽度设置为固定值,例如50dp70dp,这可以在任何模式下保持项目的高度和宽度相同。 我希望这可以帮助您,如果这个答案没有帮助到您,请忽略这个答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接