10

I have Recyclerview which is under Coordinatorlayout > NestedScrollview > ViewPager and ViewPager has 3 fragment, one has image gallery which is working with the help of Recyclerview. Whenever i tried to scroll up or down it doesn't scroll at all. I have already set photosRecycler.setNestedScrollingEnabled(false); and as soon as i remove this line i am getting scroll working only down side and when i tried to move back up it move up with parent Nestedscrollview.

My layout manager is also showing StaggeredGrid as Grid i need to get this kind of layout

enter image description here

Here is my parent layout for 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>

Image Gallery Fragment

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);
            }
        }

    }

}

Layout file for image gallery

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

I am facing 2 issue with this code

  1. Recyclerview not working in nestedscrollview.
  2. StaggeredGridLayoutManager is showing images like GridLayoutManager

Please help me to resolve these issue.Thanks

androidXP
  • 1,692
  • 3
  • 27
  • 58
  • Please share a sample project which reproduces the same problems that you are facing – Sahil Manchanda May 27 '20 at 18:33
  • @SahilManchanda i shared almost complete code.It's a same code and i am still trying to fix it. – androidXP May 28 '20 at 02:52
  • can we remove the nested scroll view from coordinator layout and put view pager directly ? – Abdul May 30 '20 at 08:44
  • and one thing more, can you make your item 1 and then check if item click listener is working or not. I was facing same problem, i might have a solution then. – Abdul May 30 '20 at 08:45
  • @Abdul i only depends on view pager for scroll events then it kills the purpose of `CoordinatorLayout` – androidXP May 31 '20 at 14:01

6 Answers6

1

You need NestedScrollableHost to scroll in RecyclerView

Works for me with following layout tree

activity.xml

<androidx.constraintlayout.widget.ConstraintLayout
    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"
    tools:context=".view.MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/vp_views"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" />

</androidx.constraintlayout.widget.ConstraintLayout>

fragment.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:constraint="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        ...

        <com.anatoli.thebattleofcards.fabric.NestedScrollableHost
            android:id="@+id/rv_items_host"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            constraint:layout_constraintEnd_toEndOf="parent"
            constraint:layout_constraintStart_toStartOf="parent"
            constraint:layout_constraintTop_toTopOf="parent">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv_items"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"      <!-- change orientation if needs -->
                android:paddingStart="@dimen/layout_padding_small"
                android:paddingEnd="@dimen/layout_padding_small"
                app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

        </com.anatoli.thebattleofcards.fabric.NestedScrollableHost>

        ...

    </androidx.constraintlayout.widget.ConstraintLayout>

</ScrollView>
anatoli
  • 1,663
  • 1
  • 17
  • 43
0

I think you should put you tabLayout in the appBar:

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

        <android.support.design.widget.CollapsingToolbarLayout
        .
        .
        .
        />

            <ImageView
                .
                .
                .
                />

        </android.support.design.widget.CollapsingToolbarLayout>

        <android.support.design.widget.TabLayout
        .
        .
        .
             />
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>

and put nestedScrolling in your fragments. Read this post: CollapsingToolbar with ViewPager and fragments

Sina
  • 2,683
  • 1
  • 13
  • 25
0

Perhaps your nestedScrollView hasn't covered the entire screen. Try adding this in your nestedScrollView

android:fillViewport="true"
elbert rivas
  • 1,464
  • 1
  • 17
  • 15
0

After setting the adapter try putting this line.

ViewCompat.setNestedScrollingEnabled(recyclerView, false);
shruity
  • 178
  • 1
  • 2
  • 16
0

I have faced the same requirement but have solved it in a different manner,

app:layout_behavior="@string/appbar_scrolling_view_behavior"

Set this attribute to the main content layout in your CoordinatorLayout.

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

The layout looks like

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

And the main fragments parent view must be nested scroll view with app:layout_behavior

Note: My fragment contains linear layout, so I just used wrap_content if you are using recycler view you should flatten it out inside the fragment

Krishna Sony
  • 1,286
  • 13
  • 27
Deejayen
  • 23
  • 1
  • 8
0
  1. Since it's viewPager that's directly inside your CoordinatorLayout and not your recyclerView, viewPager shoud have scrolling_layout_behaviour and not your 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. Set up your StaggeredGridLayoutManager like this

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

In order for StaggeredGridLayout to work, you must not set your imageView scaletype to cropCenter and height of your cardView containing the imageView element should be set to wrap content and not fixed.

<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>
Stack Fox
  • 1,201
  • 9
  • 14