Подтвердить что ты не робот

Когда фрагмент фрагмента с SwipeRefreshLayout во время обновления, фрагмент замерзает, но на самом деле все еще работает

ОБНОВЛЕНИЕ: Я думал, что он работает правильно. Но после того, как все еще существуют проблемы с тестированием * sniff *

Затем я сделал более простую версию, чтобы увидеть, что именно происходит, и я узнаю, что освежающий фрагмент, который должен был быть отсоединен, все же остался там. Или точно, вид старого фрагмента остался там поверх более нового фрагмента. Поскольку фон RecyclerView моего оригинального приложения не прозрачен, так получилось, что я сказал раньше.

КОНЕЦ ОБНОВЛЕНИЯ


У меня есть MainActivity с компоновкой вроде этого:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_height="match_parent">

    <!-- As the main content view, the view below consumes the entire
         space available using match_parent in both dimensions. -->
    <FrameLayout android:id="@+id/container" android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- android:layout_gravity="start" tells DrawerLayout to treat
         this as a sliding drawer on the left side for left-to-right
         languages and on the right side for right-to-left languages.
         If you're not building against API 17 or higher, use
         android:layout_gravity="left" instead. -->
    <!-- The drawer is given a fixed width in dp and extends the full height of
         the container. -->
    <fragment android:id="@+id/navigation_drawer"
        android:layout_width="@dimen/navigation_drawer_width" android:layout_height="match_parent"
        android:layout_gravity="start" tools:layout="@layout/fragment_navigation_drawer" />

</android.support.v4.widget.DrawerLayout>

Фрагмент ContentView, который я использую для заполнения @id/container, настроен как:

<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
    android:id="@+id/tweet_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/grey_300"/>

</android.support.v4.widget.SwipeRefreshLayout>

И вот onCreateView() of ContentView

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View inflatedView = inflater.inflate(R.layout.fragment_content, container, false);

    mRecyclerView = (RecyclerView) inflatedView.findViewById(R.id.tweet_list);
    mRecyclerView.setHasFixedSize(false);

    mLinearLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
    mRecyclerView.setLayoutManager(mLinearLayoutManager);

    mTweetList = new ArrayList<Tweet>;
    mAdapter = new TweetAdapter(mTweetList);
    mRecyclerView.setAdapter(mAdapter);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    mSwipeRefreshLayout = (SwipeRefreshLayout) inflatedView.findViewById(R.id.contentView);
    mSwipeRefreshLayout.setOnRefreshListener(
        ...
    );
    return inflatedView;
}

Затем в MainActivity я переключаю содержимое, отображаемое, переключая разные ContentView. Все выглядит хорошо, кроме одного: когда я переключаю фрагменты ContentView ВО ВРЕМЯ обновления в навигационном ящике, содержимое замораживается. Но на самом деле все работает как обычно, если вы не видите его.

4b9b3361

Ответ 1

Ну... После некоторых боев я в конечном итоге решил эту проблему сам по себе, сложным способом...

Мне просто нужно добавить их в onPause():

@Override
public void onPause() {
    super.onPause();
    ...

    if (mSwipeRefreshLayout!=null) {
        mSwipeRefreshLayout.setRefreshing(false);
        mSwipeRefreshLayout.destroyDrawingCache();
        mSwipeRefreshLayout.clearAnimation();
    }
}

Ответ 2

Эта проблема, похоже, все еще встречается в appcompat 22.1.1. Обертка SwipeRefreshLayout внутри FrameLayout решила это для меня

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

<android.support.v4.widget.SwipeRefreshLayout

    android:id="@+id/contentView"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/tweet_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/grey_300" />

</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>

Ответ 3

В дополнение к ответу @zlm2012 я заметил, что эта проблема была воспроизведена в Support Library 21.0.0, но, похоже, сейчас исправлена ​​21.0.3

Ответ 4

Решение работает, но я думаю, что лучше просто поместить эти строки в свою собственную функцию, например:

public void terminateRefreshing() {
    mSwipeRefreshLayout.setRefreshing(false);
    mSwipeRefreshLayout.destroyDrawingCache();
    mSwipeRefreshLayout.clearAnimation();
}

и вызов при переключении фрагмента.

Fragment prevFrag = fragmentManager.findFragmentById(drawerContainerId);

if(prevFrag instanceof SwipeRefreshFragment) {
    ((SwipeRefreshFragment)prevFrag).terminateRefreshing();
}

fragmentManager.beginTransaction().replace(drawerContainerId, fragment).commit();

Ответ 5

Это работает! Просто удалите переход с замены вашего фрагмента, в моем случае я удалил из своего кода следующее:

.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)

Ответ 6

Установите clickable="true" в макет верхнего родителя... Он может решить проблему.

Ответ 7

Пока вы можете избежать проблемы:

public class FixedRefreshLayout extends SwipeRefreshLayout {

    private static final String TAG = "RefreshTag";
    private boolean selfCancelled = false;

    public FixedRefreshLayout(Context context) {
        super(context);
    }

    public FixedRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected Parcelable onSaveInstanceState()
    {
        if(isRefreshing()) {
            clearAnimation();
            setRefreshing(false);
            selfCancelled = true;
            Log.d(TAG, "For hide refreshing");
        }
        return super.onSaveInstanceState();
    }

    @Override
    public void setRefreshing(boolean refreshing) {
        super.setRefreshing(refreshing);
        selfCancelled = false;
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        if(hasWindowFocus && selfCancelled) {
            setRefreshing(true);
            Log.d(TAG, "Force show refreshing");
        }
    }
}

У этого есть дополнительное преимущество возобновления анимации, если вы решите не переключать фрагмент (из какого-то меню). Он также связан с внутренней анимацией, чтобы убедиться, что обновляющая анимация не возвращается, если обновление сети уже завершено.

Ответ 8

Завершение SwipeRefresh при каждом нажатии пункта меню навигации. Это сработало.

private void selectItem(int position) {

       mSwipeRefreshLayout.setRefreshing(false);

       /*
        Other part of the function
       */
}