8

Ich habe eine Fragment mit einer SwipeRefreshLayout und dann RecyclerView als Kind. Wenn das Fragment festgeschrieben ist, beginnt es mit einem Server zu sprechen, um einige Daten abzurufen und einen CustomAdapter zu füllen, der den RecyclerView bedient.SwipeRefreshLayout ist auf leeren RecyclerView versteckt

Der Benutzer kann den Inhalt aktualisieren, indem er nach unten wischt oder eine Taste auf der ActionBar drückt. Im letzteren Fall rufe ich manuell swipeRefreshLayout.setRefreshing(true). Also keine Probleme bis jetzt.

Das Problem tritt auf, wenn ich den Aktualisierungsstatus beim ersten Laden des RecyclerView manuell aufrufen (onStart()). Die Fortschrittsanzeige wird nicht angezeigt und ich nehme an, weil der RecyclerView noch leer ist, da es einige Sekunden benötigt, um alle Daten abzurufen ...

Ich überlasse Ihnen etwas Code.

Fragment Code:

public class MyFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { 


    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

     View mView = inflater.inflate(R.layout.fragment_stop, container, false); 
     mRecyclerView = (RecyclerView) mView.findViewById(R.id.recyclerView1); 
     mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), 
      DividerItemDecoration.VERTICAL_LIST)); 
     mRecyclerView.setHasFixedSize(true); 
     mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
     mRecyclerView.setItemAnimator(new DefaultItemAnimator()); 

     //SwipeRefreshLayout retrieved and configured 
     swipeLayout = (SwipeRefreshLayout) mView.findViewById(R.id.swipe_container); 
     swipeLayout.setOnRefreshListener(this); 
     swipeLayout.setColorSchemeResources(
      R.color.primaryColor, 
      R.color.cyan_500, 
      R.color.light_green_500, 
      R.color.amber_500); 

     return mView; 


    } 

    ... 
    @Override 
     public void onStart() { 
      super.onStart(); 
      executeSchedule(); //First execution and data loading. 
     } 
     ... 

    @Override 
    public void onRefresh() { 
     executeSchedule(); 
    } 
    ... 
    public void executeSchedule() { 
     new Schedule().execute(); 
    } 



    private class Schedule extends AsyncTask<Void, Void, Void> { 

     ... 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      if(!swipeLayout.isRefreshing()) { 
       swipeLayout.setRefreshing(true); //set refresh state 
      } 
     } 

     @Override 
     protected Void doInBackground(Void... params) { 
     ... 
     } 

     @Override 
     protected void onPostExecute(Void result) { 
      adap = new CustomAdapter(getActivity(), ...); 
      mRecyclerView.setAdapter(adap); 
      swipeLayout.setRefreshing(false); 
     } 

} 

XML-Code:

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

    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <TextView 
      android:id="@+id/section_label" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content"/> 

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

      <android.support.v7.widget.RecyclerView 
       android:id="@+id/recyclerView1" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:paddingLeft="4dp" 
       android:paddingRight="4dp" 
       android:paddingBottom="2dp" 
       android:layout_marginTop="5dp" 
       android:divider="#e0e0e0" 
       tools:context=".MyFragment" /> 

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

Was wäre die beste Praxis, diese Situation zu verbessern? Einen zweiten Dummy hinzufügen SwipeRefreshLayout? Sofort einen leeren Adapter erzwingen?

Antwort

0

Sie müssen die Measure-Methode vor dem Aufruf setRefreshing(true) aufrufen.
Werfen Sie einen Blick auf: SwipeRefreshLayout no animation on fragment creation. Vielleicht kann es hilfreich sein.

+0

Vielen Dank. Das wusste ich nicht. Sicherlich ist es eine weitaus bessere Lösung als den Aufruf von 'setProgressViewOffset()' – Emanuele

11

Ich hatte ein Problem mit SwipeRefreshLayout nicht mit einem leeren Recycler arbeiten, so dass ich einen sehr einfachen leeren Adapter erstellt.

public class EmptyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 
    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     return null; 
    } 

    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 

    } 

    @Override 
    public int getItemCount() { 
     return 0; 
    } 
}