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>
3 Réponses :
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); } });
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
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.
Changez la hauteur de
swipelayout
enwrap_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">
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.
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 votreLinearLayout
. 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.