提问者:小点点

底部工作表内的ViewPager2防止底部工作表垂直滚动


在我的主要活动中,我有一个持续的底线行为。底部工作表有一个片段容器,其中包含一个ViewPager2。问题是,ViewPager2阻止底部工作表垂直滚动。

我在示例应用程序中重新创建了该问题。正如您从此处的gif中看到的,如果垂直滚动在ViewPager2内,则垂直滚动不起作用。只有当我在ViewPager2外一直向下拖动时,它才开始避开底部工作表。这使得滚动变得尴尬。

我尝试了这里描述的解决方案,但它没有改变任何东西。活动的根视图是协调布局,片段的根视图是LinearLayoutViewPager2周围有ConstraintLayout

下面是主要的活动布局:

<?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"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="center">

        <Button
            android:id="@+id/expand_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Expand Bottom Sheet" />

    </LinearLayout>

    <FrameLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

        <FrameLayout
            android:id="@+id/fragment_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:focusable="true"
            android:focusableInTouchMode="true" />

    </FrameLayout>


</androidx.coordinatorlayout.widget.CoordinatorLayout>

下面是底部页面布局中的片段:

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

    <androidx.constraintlayout.widget.ConstraintLayout

        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/purple_500">

        <TextView
            android:id="@+id/sheet_textview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="10dp"
            android:gravity="center_horizontal"
            android:text="This is the sheet fragment"
            android:textSize="24sp"
            android:textAlignment="center"
            android:textColor="@color/white" />

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="325dp"

            android:layout_marginTop="75dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center_horizontal"
            android:text="Outside viewpager"
            android:textSize="24sp"
            android:textAlignment="center"
            android:textColor="@color/white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/view_pager"

            />
    </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

这是主要活动

package com.example.myapplication;

import android.os.Bundle;
import android.widget.Button;
import android.widget.FrameLayout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import com.google.android.material.bottomsheet.BottomSheetBehavior;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        BottomSheetBehavior<FrameLayout> bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet));
        bottomSheetBehavior.setPeekHeight(200);
        bottomSheetBehavior.setHideable(true);
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);


        Button expandButton = findViewById(R.id.expand_button);
        expandButton.setOnClickListener(view -> bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED));

        Fragment sheetFragment = new SheetFragment();
        getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, sheetFragment).commit();
    }
}

下面是< code>SheetFragment:

package com.example.myapplication;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;

public class SheetFragment extends Fragment {
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.fragment_sheet, container, false);
        ViewPager2 viewPager = contentView.findViewById(R.id.view_pager);
        ViewPagerAdapter adapter = new ViewPagerAdapter();
        viewPager.setAdapter(adapter);

        return contentView;
    }

    public class ViewPagerAdapter extends RecyclerView.Adapter<ViewPagerHolder> {
        @NonNull
        @Override
        public ViewPagerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View itemView = getLayoutInflater().inflate(R.layout.pager_item, parent, false);
            return new ViewPagerHolder(itemView);
        }

        @Override
        public void onBindViewHolder(@NonNull ViewPagerHolder holder, int position) {
            holder.bind(position);
        }

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

    private class ViewPagerHolder extends RecyclerView.ViewHolder {
        public ViewPagerHolder(@NonNull View itemView) {
            super(itemView);
        }

        public void bind(int number) {
            TextView textView = itemView.findViewById(R.id.pager_textview);
            textView.setText(String.format("Inside ViewPager\nPage #%d", number));
        }
    }
}

共1个答案

匿名用户

感谢伟大的bobekos帮助我。他的回答是:

这是因为底片只允许一个可滚动视图。因此,要使其工作,您必须禁用视图寻呼机的嵌套滚动。问题是您必须访问视图页面中的recylerview 2,目前没有get方法,并且类是最终的,因此您不能使用继承。但是您可以这样做:

//as extension function
fun ViewPager2.disableNestedScrolling() {
    (getChildAt(0) as? RecyclerView)?.apply {
        isNestedScrollingEnabled = false
        overScrollMode = View.OVER_SCROLL_NEVER
    }
}

ps.not直接测试

我把它翻译成Java:

RecyclerView innerRecyclerView = (RecyclerView) viewPager2.getChildAt(0);
if (innerRecyclerView != null) {
    innerRecyclerView.setNestedScrollingEnabled(false);
    innerRecyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
}

经过测试,运行良好。