5

Mam działanie składające się z paska narzędzi i widoku stronicowania. Jego układ jest następujący:SwipeRefreshLayout inside ViewPager

<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:orientation="vertical"> 

<android.support.v4.view.ViewPager 
    android:id="@+id/pager" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingTop="112dp" 
    android:layout_gravity="bottom" 
    tools:context=".Rhino68PanelActivity" /> 

<LinearLayout 
    android:id="@+id/toolbarContainer" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical"> 

    <include 
     android:id="@+id/app_bar" 
     layout="@layout/app_bar" /> 

    <include 
     android:id="@+id/tap_strip" 
     layout="@layout/tab_strip" /> 

</LinearLayout> 

I następnie załadować dwa fragmenty w widoku pager. Każdy fragment zawiera własny SwipeRefreshLayout. Pokażę jeden fragmenty układ:

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

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:weightSum="12" 
    tools:context=".Rhino68PanelActivity$DummySectionFragment"> 
    ...   
    <android.support.v7.widget.RecyclerView 
    android:id="@+id/recyclerView_panel_status" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:clipToPadding="false" /> 

</LinearLayout> 

Teraz kiedy uruchomić aktywność wydaje się działać. Zauważyłem jednak, że przesuwam się poziomo (tzn. Przechodzę do następnej zakładki). To wyzwala swipeRefreshLayout OnRefreshListener

 mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 
      @Override 
      public void onRefresh() { 
       mSwipeRefreshLayout.setRefreshing(true); 
       DoUpdate(); 
      } 
     }); 

Ja również doświadcza dziwne zachowanie wizualnej kiedy próbują zrobić i odświeżenia. Znak ładowania (wirujący okrąg) często się nie pokazuje, a czasami pokazuje, ale pozostaje mały. Nie jestem pewien, czy jest to również przyczyną konfliktu między dwoma widokami.

Czy jest jakiś sposób, że mogę rozwiązać ten problem. Nie jestem pewien jak. Może ograniczając SwipeRefreshLayout, aby słuchać tylko pionowych przeskoków?

Wszelkie sugestie będą bardzo mile widziane.

+1

Nie mam tego problemu w moim projekcie, który również wykorzystuje podobną strukturę. Czy możesz opublikować przykładowy projekt, który odtwarza ten problem? – corsair992

+0

Czy chcesz udostępnić swój układ? Z pewnością te dwa układy będą się ze sobą ingerować? Jeśli nawet po prostu nagrałem "SwipeRefreshLayout", to wyzwolił on 'OnRefresh()' – Zapnologica

+1

Istnieje przedział niechlujstwa zanim którykolwiek z tych "ViewGroup' przejmie zdarzenie dotykowe, i zależy od tego, czy przeciągnięcie było bardziej pionowe czy poziome . Gdy zdarzenie dotykowe zostanie przejęte przez "ViewGroup", kontynuuje obsługę zdarzenia bez zakłóceń (za pomocą metody 'requestDisallowInterceptTouchEvent()'). Moja aplikacja i układ są dość skomplikowane, a także poufne, pomogłoby, gdyby można było opublikować minimalny przykładowy projekt z tym problemem (aby móc go debugować). – corsair992

Odpowiedz

1

Dzieje się tak, ponieważ w SwipeRefreshLayout jest błąd! Błąd: "onRefresh nie działa poprawnie, jeśli funkcja onMeasure nie jest nazywana" Powinieneś rozszerzyć SwipeRefreshLayout w ten sposób!

public class SwipeRefreshLoading extends SwipeRefreshLayout { 
    public SwipeRefreshLoading(Context context) { 
     super(context, null); 
    } 

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

    private boolean mMeasured = false; 
    private boolean mPreMeasureRefreshing = false; 

    @Override 
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     if (!mMeasured) { 
      mMeasured = true; 
      setRefreshing(mPreMeasureRefreshing); 
     } 
    } 


    @Override 
    public void setRefreshing(boolean refreshing) { 
     if (mMeasured) { 
      super.setRefreshing(refreshing); 
     } else { 
      mPreMeasureRefreshing = refreshing; 
     } 
    } 
} 
+0

Dziękujemy! Mam RefreshLayout wewnątrz ViewPager i 'setRefreshing' inside" page "(był to fragment w moim przypadku) nie działa z jakichś powodów. Nawiasem mówiąc, używam fragmentu kodu i mam małą niewłaściwą pozycję odświeżającego spinnera. Jeśli przeniesiesz logikę z metody 'onMeasure' do metody' onLayout', pozycja będzie poprawna. – IlyaEremin

+0

@IlyaEremin Mam problem w vievpager z refreshlayout - gdy triger onrefresh * setrefresg (false) w pierwszym fragmencie viewpagera to animacja zniknęła (jest ok) - ale w drugiej animacji fragmentu wciąż gra nawet ja nazywam setrefreshinng (false) - Rozszerzyłem układ jak wyżej - również przeniesiono do onlayout, ale wciąż żaden efekt również nie post opóźnił się na układzie - może powinienem dodać setrefresh do rozłożenia? – ceph3us

+0

@TomaszBest to głupie pytanie, ale pytam. Czy nazwałeś 'setRefreshing (false)' dla drugiego fragmentu 'SwipeRefreshLayout'? – IlyaEremin

3

Też miałem ten głupi problem. Wygląda na to, że jest to błąd w SwipeRefreshLayout. Aby obejść ten problem, musiałem usunąć wszystkie widoki podrzędne w metodzie Fragment.onDestroyView().

public SwipeRefreshLayout mSwipeRefreshLayout; 
... 

@Override public void onDestroyView() { 
    mSwipeRefreshLayout.removeAllViews(); 
    super.onDestroyView(); 
}