Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AppBarLayout] liftOnScroll not detecting scrolling on top of nested horizontal RecyclerView #4394

Open
BenjyTec opened this issue Nov 22, 2024 · 1 comment
Assignees
Labels

Comments

@BenjyTec
Copy link

BenjyTec commented Nov 22, 2024

Description:

I have a CoordinatorLayout with an AppBarLayout and a NestedScrollView. In the NestedScrollView, I have a horizontally scrolling RecyclerView surrounded by two dummy Views.

I have set liftOnScroll="true" and it is working when I scroll on dummy Views in the NestedScrollView, But when I vertically scroll on top of the horizontal RecyclerView, while the NestedScrollView correctly scrolls vertically, the AppBarLayout seems not to detect it, and does not update its lifted state. When I fling on top of the RecyclerView with a lot of velocity, it seems to work correctly most of the time. However it never works correctly when slowly dragging on top of the RecyclerView.

liftonscroll(1)

Expected behavior:

The liftOnScroll should update the AppBarLayout when the NestedScrollView is scrolled, no matter where exactly the vertical scroll gesture was started inside of the NestedScrollView.

Source code:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        getWindow().setNavigationBarColor(SurfaceColors.SURFACE_2.getColor(this));

        RecyclerView recyclerView = findViewById(R.id.recyclerView);
        LinearLayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setHasFixedSize(false);
        recyclerView.setAdapter(new StatsAdapter());
    }
}

activity_main.xml

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/mainBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        app:liftOnScroll="true">
        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:gravity="center" />
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/nestedScrollViewStats"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/linearLayoutStats"
            android:orientation="vertical"
            android:layout_gravity="center_horizontal">
            <View
                android:layout_width="match_parent"
                android:layout_height="400dp" />
            <androidx.recyclerview.widget.RecyclerView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#F44336"
                android:id="@+id/recyclerView" />
            <View
                android:layout_width="match_parent"
                android:layout_height="400dp" />
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

StatsAdapter.java

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

    public StatsAdapter() {}

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public TextView textViewCalc;

        public ViewHolder(View itemView) {
            super(itemView);
            this.textViewCalc = itemView.findViewById(R.id.textViewCalc);
        }
    }

    @Override
    public StatsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View listItem = layoutInflater.inflate(R.layout.stats_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(listItem);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.textViewCalc.setText(
                position + " x " + position + "\n" + position + " x " + position + "\n" + position + " x " + position
        );
    }

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

stats_item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/statsItem"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_margin="8dp">

    <TextView
        android:id="@+id/textViewCalc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        tools:text="X x Y"
        android:textSize="16sp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Minimal sample app repro:

https://github.com/BenjyTec/TopBarRepro

Android API version:

API35, but also reproduced back until API21.

Material Library version:

Issue reproduced on 1.12.0 and 1.13.0-alpha08

Device:

Google Pixel 4a, and Emulator

Attachments:

liftonscroll.mp4
@imhappi
Copy link
Contributor

imhappi commented Nov 26, 2024

@hunterstich do you know why this would be happening?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants