【问题标题】:Fragment not replacing in Volley's OnResponse()Volley 的 OnResponse() 中没有替换的片段
【发布时间】:2016-07-20 08:51:57
【问题描述】:

我正在尝试替换 Volley 的 onResponse() 中的片段。它正在被替换,但方式很奇怪。

  • 旧碎片仍然可见,而新碎片不可见。
  • 旧片段是非交互式的,点击事件由 新的碎片。

就像新的碎片在旧碎片的下面。

如果我尝试替换 Volley 的 onResponse() 之外的片段,那么一切都会按应有的方式进行:旧片段消失,显示新片段。

getNetworkManager().jsonGETRequest(new NetworkManagerRequestData(getActivity(), this,
            orderListUrl,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject jsonObject) {

                    FragmentManager fragmentManager = getSupportFragmentManager();
                    FragmentTransaction transaction = fragmentManager.beginTransaction();
                    transaction.replace(R.id.main_frame, IdleFragment.newInstance());
                    transaction.commit();
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {
              ..
        }
    }, NetworkManager.getDefaultPolicyForNonTransactions(), false));

片段是使用 FrameLayout 动态添加的。我有一个有 5-6 个碎片的活动。除了这次交易之外,一切都与动画完美配合。

这是 R.id.main_frame,它是一个空的 FrameLayout。

<FrameLayout
    android:id="@+id/main_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    ..
     />

更新 所以我尝试在 AsyncTask 中实现片段事务

new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.main_frame, IdleFragment.newInstance());
            transaction.commit();
        }
    }.execute();

这具有相同的行为。通常,在任何异步回调之外进行事务处理都可以正常工作。

这是我要替换的碎片的布局

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipe_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/pitch_grey"
        android:clickable="true"
        android:fillViewport="true">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
               .....
        </RelativeLayout>
    </ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

【问题讨论】:

  • 不建议在异步调用中发起分片事务。它可能导致 IllegalStateException。
  • 我已经进行了必要的检查。

标签: android android-fragments android-volley


【解决方案1】:

问题在于滑动刷新布局。当您在刷新时尝试替换片段时,前一个片段将冻结。这是 SwipeRefreshLayout 本身的一个问题。

您可以将 swipeRefreshLayout 包裹在 FrameLayout 中。这可能有效。

<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/pitch_grey"
    android:clickable="true"
    android:fillViewport="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
           .....
    </RelativeLayout>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>

参考:When switch fragment with SwipeRefreshLayout during refreshing, fragment freezes but actually still work

【讨论】:

    【解决方案2】:

    您不能替换静态放置在 xml 布局文件中的片段。空闲片段是静态放置的吗?您应该在布局中创建一个容器(例如 FrameLayout),然后使用 FragmentTransaction 以编程方式添加片段。

    还可以使用空的 FrameLayout 作为片段容器。避免使用 LinearLayout 或 RelativeLayout。我曾经使用 LinearLayout 遇到过这个问题,并将 LinearLayout 替换为 FrameLayout 并且效果很好。

    另一个建议,避免在异步调用中进行片段事务。它可能会导致 IllegalState 异常。如果您仍想这样做,请使用 commitAllowStateLoss 而不是 commit。

    【讨论】:

    • 编辑了问题。
    • 我最初使用的是 commitAllowingStateLoss()。认为这可能会导致一些问题,所以我恢复到 commit()。但仍然没有骰子。
    • 您的片段类是否扩展了 android.app.Fragment 或支持片段。所有片段都应该扩展支持片段类。
    • SupportFragment,全部
    • 在replace之前尝试清除fragment backstack,看看是否正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    相关资源
    最近更新 更多