web-dev-qa-db-fra.com

Recyclerview ne défile pas dans Nested ScrollView

J'ai Recyclerview qui est sous Coordinatorlayout> NestedScrollview> ViewPager et ViewPager a 3 fragments, on a une galerie d'images qui fonctionne avec l'aide de Recyclerview. Chaque fois que j'ai essayé de faire défiler vers le haut ou vers le bas, cela ne défile pas du tout. J'ai déjà mis photosRecycler.setNestedScrollingEnabled(false); et dès que je supprime cette ligne, je reçois le défilement fonctionnant uniquement vers le bas et quand j'ai essayé de remonter, il monte avec le parent Nestedscrollview.

Mon gestionnaire de mise en page affiche également StaggeredGrid en tant que grille dont j'ai besoin pour obtenir ce type de mise en page

enter image description here

Voici ma mise en page parent pour Nestedscrollview

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:background="?android:attr/colorBackground"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <com.google.Android.material.appbar.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" >

        <com.google.Android.material.appbar.CollapsingToolbarLayout
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:fitsSystemWindows="true"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways">

            <androidx.constraintlayout.widget.ConstraintLayout


                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:background="?android:colorBackground">


                <ImageView

                    Android:layout_width="match_parent"
                    Android:layout_height="500dp"
                    Android:src="@color/custom_transparent_colorBlack"
                    Android:scaleType="centerCrop"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintHorizontal_bias="0.0"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    />

                <de.hdodenhof.circleimageview.CircleImageView

                    Android:layout_width="128dp"
                    Android:layout_height="128dp"
                    app:layout_constraintBottom_toBottomOf="@+id/coverPhoto"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="@+id/coverPhoto"
                    app:layout_constraintVertical_bias="0.44"
                    tools:srcCompat="@tools:sample/avatars" />



            </androidx.constraintlayout.widget.ConstraintLayout>
        </com.google.Android.material.appbar.CollapsingToolbarLayout>
    </com.google.Android.material.appbar.AppBarLayout>
    <androidx.core.widget.NestedScrollView
        Android:id="@+id/up_NestedScrollView"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:overScrollMode="never"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"

        >
        <RelativeLayout
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:paddingLeft="5dp"
            Android:paddingRight="5dp"
            >
            <com.google.Android.material.tabs.TabLayout
                Android:id="@+id/tabItemes"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                app:tabGravity="fill"
                app:tabPaddingBottom="0dp"
                app:tabPaddingEnd="0dp"
                app:tabPaddingStart="0dp"
                app:tabPaddingTop="0dp"
                app:tabIndicatorHeight="0dp"
                app:tabMode="fixed"
                app:tabTextColor="@color/black"
                app:tabSelectedTextColor="@color/primary"
                app:tabIndicatorColor="@color/primary_light">

                <com.google.Android.material.tabs.TabItem
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:text="About" />

                <com.google.Android.material.tabs.TabItem
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:text="Media" />

                <com.google.Android.material.tabs.TabItem
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:text="Con" />
            </com.google.Android.material.tabs.TabLayout>

            <androidx.viewpager.widget.ViewPager

                Android:layout_below="@id/tabItemes"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent" />
        </RelativeLayout>
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Fragment de galerie d'images

public class UserPhoto_fragment extends Fragment {
    public static final String TAG="### USER PHOTO ####";
    RecyclerView photosRecycler;
    fetchPhoto_Adapter adapter;
    StaggeredGridLayoutManager layoutManager;
    ArrayList<String> ImageList;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.userprofile_photos,container,false);
        setRetainInstance(true);
        photosRecycler=view.findViewById(R.id.userPhotos_recycler);
        layoutManager= new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
        layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
        ImageList=new ArrayList<>();
        SpacesItemDecoration itemDecoration = new SpacesItemDecoration(16);
        photosRecycler.addItemDecoration(itemDecoration);
        photosRecycler.setLayoutManager(layoutManager);
        photosRecycler.setHasFixedSize(true);
        photosRecycler.setNestedScrollingEnabled(false);

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume: User Photo Fragment "+getView()+ ImageList.size() );
        if (ImageList.size()==0){
            new fetch_photo().execute();
        }
    }

    public class fetchPhoto_Adapter extends RecyclerView.Adapter<fetchPhoto_Adapter.ViewHolder>{

        @NonNull
        @Override
        public fetchPhoto_Adapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            LayoutInflater inflater= (LayoutInflater) viewGroup.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View v = inflater.inflate(R.layout.userprofile_photogallery,viewGroup,false);
            return new ViewHolder(v);
        }

        @Override
        public void onBindViewHolder(fetchPhoto_Adapter.ViewHolder viewHolder, int i) {
            Glide.with(getActivity()).load(ImageList.get(i)).apply(new RequestOptions().centerCrop()).into(viewHolder.image);
        }

        @Override
        public int getItemCount() {
            if (ImageList!=null && ImageList.size()>0){
                return ImageList.size();
            }else {
                return 0;
            }
        }

        public class ViewHolder extends RecyclerView.ViewHolder {
            ImageView image;
            public ViewHolder(View itemView) {
                super(itemView);
                image = itemView.findViewById(R.id.UserProfile_photoThumb);
            }
        }

    }

}

Fichier de mise en page pour la galerie d'images

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_marginTop="20dp"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        Android:id="@+id/userPhotos_recycler"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        Android:scrollbars="vertical">

    </androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>

Je suis confronté à 2 problèmes avec ce code

  1. Recyclerview ne fonctionne pas dans nestedscrollview.
  2. StaggeredGridLayoutManager affiche des images comme GridLayoutManager

S'il vous plaît, aidez-moi à résoudre ces problèmes.Merci

11
androidXP
  1. Puisque c'est viewPager qui est directement dans votre CoordinatorLayout et non votre recyclerView, viewPager doit avoir scrolling_layout_behaviour et non votre recyclerview

    <androidx.viewpager.widget.ViewPager
       Android:layout_below="@id/tabItemes"
       Android:layout_width="match_parent"
       Android:layout_height="match_parent" 
       app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
  2. Configurez votre StaggeredGridLayoutManager comme ceci

    StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, LinearLayoutManager.VERTICAL);
    recyclerView.setLayoutManager(staggeredGridLayoutManager); // set LayoutManager to RecyclerView
    

Pour que StaggeredGridLayout fonctionne, vous ne devez pas définir votre scaletype imageView sur cropCenter et la hauteur de votre cardView contenant l'élément imageView doit être définie pour envelopper le contenu et non fixe.

<Android.support.v7.widget.cardview 
   Android:layout_height="wrap_content" 
   Android:layout_width="match_parent"
   app:cardcornerradius="4dp" 
   app:cardusecompatpadding="true">

  <linearlayout 
    Android:background="@color/colorPrimary" 
    Android:layout_height="match_parent"
    Android:layout_width="match_parent"
    Android:orientation="vertical">

      <imageview
       Android:adjustviewbounds="true" 
       Android:id="@+id/placePic" 
       Android:layout_height="match_parent" 
       Android:layout_width="match_parent" 
       Android:scaletype="fitXY" />

   </linearlayout>
</Android.support.v7.widget.cardview>
0
Stack Fox

J'ai fait face à la même exigence mais je l'ai résolue d'une manière différente,

app:layout_behavior="@string/appbar_scrolling_view_behavior"

Définissez cet attribut sur la mise en page de contenu principale de votre CoordinatorLayout.

    <string name="appbar_scrolling_view_behavior" translatable="false">com.google.Android.material.appbar.AppBarLayout$ScrollingViewBehavior</string>

La mise en page ressemble à

    <androidx.coordinatorlayout.widget.CoordinatorLayout >

    <com.google.Android.material.appbar.AppBarLayout>

        <androidx.appcompat.widget.Toolbar>

            <androidx.constraintlayout.widget.ConstraintLayout>

                <ImageView />
                //Header content

            </androidx.constraintlayout.widget.ConstraintLayout>

        </androidx.appcompat.widget.Toolbar>

        <com.google.Android.material.tabs.TabLayout />

    </com.google.Android.material.appbar.AppBarLayout>

    <LinearLayout

        app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <androidx.viewpager.widget.ViewPager
                Android:id="@+id/viewPager"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:background="@color/light_gray">

            </androidx.viewpager.widget.ViewPager>

    </LinearLayout>


</androidx.coordinatorlayout.widget.CoordinatorLayout>

Et la vue parent des fragments principaux doit être une vue de défilement imbriquée avec app:layout_behavior

Remarque: mon fragment contient une mise en page linéaire, je viens donc d'utiliser wrap_content si vous utilisez la vue recycleur, vous devez l'aplatir à l'intérieur du fragment

0
Deejayen