0
votes

SwipeRefreshLayout avec RecyclerView ne fonctionne pas dans Fragment

J'ai un recyclerview à l'intérieur de SwipeRefreshLayout dans un fragment. J'ai implémenté AsyncTask pour récupérer des données pour recyclerview. Le problème est que SwipeRefreshLayout ne s'affiche pas du tout et que les données ne sont donc pas remplies dans recyclerview. J'ai fait la même chose pour Activity et cela fonctionne très bien mais pas en fragments. Quelqu'un peut-il me guider sur ce que je fais de mal? Voici le fichier de mise en page pour fragment:

public class FeaturedFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
    private RecyclerView mRecyclerView;
    private SwipeRefreshLayout mSwipeLayout;
    public FeaturedFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_featured_captions, container, false);
        mRecyclerView = view.findViewById(R.id.recyclerView);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        mSwipeLayout = view.findViewById(R.id.refresh_layout);
        mSwipeLayout.setOnRefreshListener(this);
        return view;
    }

    @Override
    public void onRefresh() {
        new FetchFeedTask().execute((Void) null);
    }


    private class FetchFeedTask extends AsyncTask<Void, Void, Boolean> {
        @Override
        protected void onPreExecute() {
            mSwipeLayout.setRefreshing(true);
        }

        @Override
        protected Boolean doInBackground(Void... voids) {
            //things to do in background
        }

        @Override
        protected void onPostExecute(Boolean success) {
            mSwipeLayout.setRefreshing(false);
            mRecyclerView.setAdapter(/*adapter*/);
            //things to do at the end
        }
    }

}

Et voici ce que j'ai fait dans la classe fragment.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".FeatureFragment">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        </androidx.recyclerview.widget.RecyclerView>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

</LinearLayout>


10 commentaires

Ajoutez SwipeRefreshLayout tant que disposition racine.


@MehulSolanki Je ne veux pas parce que j'ai quelques vues à ajouter ci-dessus SwipeRefreshLayout


vous ne pouvez pas avoir des choses au-dessus du balayage pour actualiser la mise en page, il faut que ce soit la racine. vous pouvez avoir des "choses" au-dessus de la vue du recycleur, mais pas au-dessus du swiperefresh


@JoachimHaglund ce n'est probablement pas vrai. Je l'ai testé et vous pouvez avoir des vues ci-dessus SwipeRefreshLayout.


Pouvez-vous essayer d'ajouter android:clickable="true" dans votre LinearLayout . cela peut aider


@MehulSolanki non, cela n'aide pas.


@DineshNeupane une solution?


@SagarMaiyad Non. J'ai fini par créer une vue de chargement personnalisée


@DineshNeupane puis-je savoir comment tu as fait ça?


@SagarMaiyad a configuré une vue de chargement et une vue de recyclage, définissez sa visibilité comme GONE lorsque les données sont chargées.


3 Réponses :


0
votes

Puisse votre code ne fonctionne pas à cause de ReacyclerView scroll Listener Essayer ci - dessous ciselée.

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



    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mRecyclerView = view.findViewById(R.id.recyclerView);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        mSwipeLayout = view.findViewById(R.id.refresh_layout);
        mSwipeLayout.setOnRefreshListener(this);
   }

Ajoutez également vos éléments d'initialisation dans onViewCreated() comme ci-dessous

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        int topRowVerticalPosition =
                (recyclerView == null || recyclerView.getChildCount() == 0) ? 0 : recyclerView.getChildAt(0).getTop();
        mSwipeLayout.setEnabled(topRowVerticalPosition >= 0);

    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
    }
});


0 commentaires

-3
votes

Essayez d'utiliser l'extrait ci-dessous:

Utilisez toujours les widgets de la bibliothèque de support. au lieu de ceux-ci:

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

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

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

et

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout

Donc:

<androidx.recyclerview.widget.RecyclerView


1 commentaires

la bibliothèque de support est dépréciée, androidX est la nouvelle façon de faire les choses et fonctionnellement, ce n'est pas différent.



0
votes

Changez la hauteur de swipelayout en wrap_content

Solution 1 :)

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

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

Solution 2 :) Utilisez la mise en page par balayage et la vue du recycleur à l'aide de la bibliothèque de conception

 <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

1 commentaires

J'ai déjà essayé la première solution, pas de chance. Pour la seconde, comme je suis déjà passé à androidx, je ne peux pas utiliser les bibliothèques de support.