滚动片段出现在 Activity 之上导致 activity 视图下方滚动

Scrolling fragment comes on top of Activity cause below activity view to scroll

我有一个 activity,其中 CoordinatorLayout 作为根布局。在其中,有一个隐藏的 FrameLayout 布局,并以编程方式设置了一个片段,该片段在单击按钮时从底部显示。该片段由一个可滚动的网格 RecyclerView 组成。

refer to this

如果您专注于工具栏,您可以看到后视图向下滚动并在网格视图滚动内容结束时显示后视图图像。

这是我的布局 activity

Activity布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinator_layout"
    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:fitsSystemWindows="true"
    android:focusableInTouchMode="true"
    tools:context=".activities.hotels.HotelDetailActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:layout_behavior="android.support.design.widget.AppBarLayout$Behavior">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:toolbarId="@+id/toolbar"
            app:expandedTitleTextAppearance="@style/TransparentText"
            app:collapsedTitleTextAppearance="@style/ExpandedAppBar"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:titleEnabled="true">

            <ImageView
                android:id="@+id/main_hotel_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                android:src="@drawable/temp_hotel"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

                <android.support.constraint.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:id="@+id/tool_bar_title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:fontFamily="@font/roboto_medium"
                        android:text="Hotel Name"
                        android:singleLine="true"
                        android:textColor="@android:color/white"
                        android:textSize="16sp"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent" />

                    <TextView
                        android:id="@+id/tool_bar_sub_title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Thu, 10 Jan 2019 - Sat, 12 Jan 2019"
                        android:textColor="@color/white"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toBottomOf="@+id/tool_bar_title" />

                </android.support.constraint.ConstraintLayout>

            </android.support.v7.widget.Toolbar>

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

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

    <include layout="@layout/content_scrolling" />

    <FrameLayout
        android:id="@+id/more_detail_fragment_holder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:visibility="gone"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_marginTop="56dp"
        android:layout_marginBottom="56dp"
        android:clickable="true"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_photo_library"
        app:backgroundTint="@color/white"
        app:fabSize="mini"
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="bottom|end" />


    <android.support.constraint.ConstraintLayout
        android:id="@+id/bottom_message_container"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="@drawable/clickable_bottom_bar_background"
        android:layout_gravity="bottom"
        android:gravity="bottom">

        <android.support.constraint.ConstraintLayout
            android:id="@+id/bottom_message_container_child"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/price_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginBottom="8dp"
                android:fontFamily="@font/roboto_regular"
                android:text="LKR 0"
                android:textColor="@android:color/white"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"/>

            <TextView
                android:id="@+id/detail_titel_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:layout_marginStart="8dp"
                android:fontFamily="@font/roboto_light"
                android:text="Starting From"
                android:textColor="@android:color/white"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent" />

            <FrameLayout
                android:id="@+id/continue_button"
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginTop="8dp"
                android:background="@drawable/secondary_button_background"
                android:clickable="true"
                android:paddingEnd="8dp"
                android:paddingStart="8dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent">

                <TextView
                    android:id="@+id/button_color"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:fontFamily="@font/roboto_medium"
                    android:text="Continue"
                    android:textColor="@android:color/white"
                    android:textSize="16sp" />

            </FrameLayout>

        </android.support.constraint.ConstraintLayout>

    </android.support.constraint.ConstraintLayout>

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

片段布局

<LinearLayout 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".fragments.hotels.AllHotelAmenitiesFragment"
    android:orientation="vertical"
    android:background="@color/white"
    android:clickable="true">

    <TextView
        android:id="@+id/hotel_amenities_title_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:fontFamily="@font/roboto_medium"
        android:text="Hotel Amenities"
        android:textColor="@color/textColorPrimary"
        android:textSize="14sp"
        android:layout_marginStart="16dp" />

    <View
        android:id="@+id/divider"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="8dp"
        android:background="@color/divider"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/recycler_view_expand_layout"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/main_hotel_amenities_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:clickable="true"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="16dp"/>


</LinearLayout>

酒店详情Activity

public class HotelDetailActivityEdit extends AppCompatActivity{

    @BindView(R.id.toolbar)
    Toolbar toolbar;

    @BindView(R.id.more_detail_fragment_holder)
    FrameLayout allHotelAmenityHolder;

    @BindView(R.id.app_bar)
    AppBarLayout appBarLayout;

    @BindView(R.id.recycler_view_expand_layout)
    FrameLayout recyclerViewExpandLayout;

    private boolean allAmenitiesFragmentIsHidden;

    private Animation revealFromBottom;
    private Animation unRevealFromBottom;
    private AllHotelAmenitiesFragment allHotelAmenitiesFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hotel_detail);
        ButterKnife.bind(this);

        initialization();
        onClickHotelAmenityExpandContainer();
    }

    private void initialization() {

        revealFromBottom = AnimationUtils.loadAnimation(this, R.anim.slide_in_bottom);
        unRevealFromBottom = AnimationUtils.loadAnimation(this, R.anim.slide_out_bottom);

        allAmenitiesFragmentIsHidden = true;

        allHotelAmenitiesFragment = new AllHotelAmenitiesFragment();

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map_fragment);

    }


    private void onClickHotelAmenityExpandContainer() {
        recyclerViewExpandLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (allAmenitiesFragmentIsHidden) {
                    allHotelAmenityHolder.startAnimation(revealFromBottom);
                    allHotelAmenityHolder.setVisibility(View.VISIBLE);
                    appBarLayout.setExpanded(false);
                    allAmenitiesFragmentIsHidden = false;
                    invalidateOptionsMenu();
                }

            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        if (!allAmenitiesFragmentIsHidden)
            getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_close);
        else {
            getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_arrow_back);
        }

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                break;
        }

        return true;
    }

    @Override
    public void onBackPressed() {

        if (!allAmenitiesFragmentIsHidden) {
            allHotelAmenityHolder.startAnimation(unRevealFromBottom);
            allHotelAmenityHolder.setVisibility(View.GONE);
            appBarLayout.setExpanded(true);
            allAmenitiesFragmentIsHidden = true;
            invalidateOptionsMenu();
        } else {
            finish();
        }
    }

}

AllHotelAmenitiesFragment

public class AllHotelAmenitiesFragment extends Fragment {


    @BindView(R.id.main_hotel_amenities_recycler_view)
    RecyclerView mainHotelAmenitiesRecyclerView;


    private MainHotelAmenitiesListAdapter mainHotelAmenitiesListAdapter;

    public AllHotelAmenitiesFragment() {
        // Required empty public constructor
    }

    public void setArguments(ArrayList<HotelAmenitiesImageObject> hotelAmenitiesWithImages) {

        Bundle args = new Bundle();
        args.putParcelableArrayList("hotel_amenities", hotelAmenitiesWithImages);
        this.setArguments(args);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_all_hotel_amenities, container, false);
        ButterKnife.bind(this, view);

        initialization();

        return view;
    }

    private void initialization() {

        ArrayList<HotelAmenitiesImageObject> mainHotelAmenities = getArguments().getParcelableArrayList("hotel_amenities");

        mainHotelAmenitiesListAdapter = new MainHotelAmenitiesListAdapter(mainHotelAmenities);

        GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 4);
        GridRecyclerViewDivider gridRecyclerItemDecorator = new GridRecyclerViewDivider(4, 16, true, 0);
        mainHotelAmenitiesRecyclerView.addItemDecoration(gridRecyclerItemDecorator);
        mainHotelAmenitiesRecyclerView.setLayoutManager(gridLayoutManager);
        mainHotelAmenitiesRecyclerView.setAdapter(mainHotelAmenitiesListAdapter);

    }

}

如您所见,我已将 android:clickable="true" 设置为片段的根布局,这是通常用来停止在后面布局上注册点击的操作。好像滚动的时候不是这样的。

我不希望我的片段后面的 activity 视图在我的片段可见时对滚动做出反应。请给我一个修复此错误的建议。

要使折叠工具栏和滚动行为在 CoordinatorLayout 中正常工作,您需要在内容布局中定义 layout_behaviour

你的框架正上方有一个 <include/> 布局,我怀疑这会有正确的布局属性,所以你的框架布局有点像 "floating" 在 no-man 的土地上.

<include layout="@layout/content_scrolling" />

<FrameLayout
    android:id="@+id/more_detail_fragment_holder"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:visibility="gone"
    android:layout_gravity="center"
    android:gravity="center"
    android:layout_marginTop="56dp"
    android:layout_marginBottom="56dp"
    android:clickable="true"/>

您可能希望框架布局位于 <NestedScrollView> 内,然后我猜您可能没有使用 include,所以只需删除它即可。像这样:

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <FrameLayout
        android:id="@+id/more_detail_fragment_holder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:visibility="gone"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_marginTop="56dp"
        android:layout_marginBottom="56dp"
        android:clickable="true"/>

</android.support.v4.widget.NestedScrollView>

这是我的解决方案

我有 运行 一个演示,这很有效!这是 Gif links

如果此解决方案对您有帮助,请采纳此答案。

  • 代码块一

disable the AppBarLayout scroll event to expand or collapse

  • 代码块二

disable the recyclerview scroll event to expand or collapse AppBarLayout

you can use scroll flag to disable it too, which i have comment, but this way will expand the AppBarLayout first

您可以使用这两个代码块来获得您想要的。

您应该为您的项目修改这些代码

当片段可见时,ViewCompat.setNestedScrollingEnabled(mRecyclerView, false) 禁用片段的回收视图而不是 content_scrolling 布局回收视图。

private int state = STATE_APPBAR;
private static final int STATE_APPBAR = 1;
private static final int STATE_CONTENT = 2;


CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
params.setBehavior(new AppBarLayout.Behavior());
AppBarLayout.Behavior appBarBehavior = (AppBarLayout.Behavior) params.getBehavior();
//code block one
if (appBarBehavior != null) {
    appBarBehavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
        @Override
        public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
            return state == STATE_APPBAR;
        }
    });
}

//code block two
mButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (state == STATE_APPBAR) {
            state = STATE_CONTENT;
            //setAppbarLayoutScrollFlag(AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP);
            ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);
        } else {
            state = STATE_APPBAR;
            //setAppbarLayoutScrollFlag(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
            ViewCompat.setNestedScrollingEnabled(mRecyclerView, true);
        }
    }
});


private void setAppbarLayoutScrollFlag(int flags) {
    AppBarLayout.LayoutParams lp = (AppBarLayout.LayoutParams) mToolbarLayout.getLayoutParams();
    lp.setScrollFlags(flags);
    mToolbarLayout.setLayoutParams(lp);
}

在您的项目中应用代码

  1. AllHotelAmenitiesFragment中添加一个获取recyclerview的方法
public class AllHotelAmenitiesFragment extends Fragment {


    @BindView(R.id.main_hotel_amenities_recycler_view)
    RecyclerView mainHotelAmenitiesRecyclerView;


    private MainHotelAmenitiesListAdapter mainHotelAmenitiesListAdapter;

    public AllHotelAmenitiesFragment() {
        // Required empty public constructor
    }

    public RecyclerView getRecyclerView() {
       return mainHotelAmenitiesRecyclerView;
    }

  1. 在您的 HotelDetailActivityEdit 中添加块逻辑
private void onClickHotelAmenityExpandContainer() {
        recyclerViewExpandLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (allAmenitiesFragmentIsHidden) {
                    allHotelAmenityHolder.startAnimation(revealFromBottom);
                    allHotelAmenityHolder.setVisibility(View.VISIBLE);
                    appBarLayout.setExpanded(false);
                    allAmenitiesFragmentIsHidden = false;
                    invalidateOptionsMenu();

                    //add block logic
                    RecyclerView recyclerview = allHotelAmenitiesFragment.getRecyclerView();
                    ViewCompat.setNestedScrollingEnabled(recyclerview, false);
                }

            }
        });
    }