【问题标题】:Scrolling fragment comes on top of Activity cause below activity view to scroll滚动片段位于 Activity 顶部,导致 Activity 视图下方滚动
【发布时间】:2019-05-10 07:51:18
【问题描述】:

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

refer to this

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

这是我的活动布局

活动布局

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

HotelDetailActivity

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" 设置为片段的根布局,这通常用于停止在布局后面注册点击。似乎在滚动时它不会那样工作。

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

【问题讨论】:

  • 您的&lt;include layout="@layout/content_scrolling" /&gt; 布局文件中有什么内容?你在用这个吗?
  • 滚动内容是 NestedScrollView 作为根布局,其中 ConstraintLayout 包含所有其他元素。
  • 好的,正如答案中突出显示的那样,我怀疑问题是您的框架布局,它会使片段漂浮在无人区。您希望嵌套滚动视图中的 all 内容。然后在内容滚动中移动嵌套滚动视图内的片段,然后行为应该起作用。
  • 您不希望您的 appBarLayout 与片段 recyclerview 滚动发生反应,或者您不希望您的 content_scrolling 布局在片段 recyclerview 滚动时滚动。
  • 当片段可见时,我不希望我的 appBarLayout 对片段回收器视图滚动做出反应。

标签: android android-fragments android-coordinatorlayout


【解决方案1】:

这是我的解决方案

我已经运行了一个演示,这可行!是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);
                }

            }
        });
    }

【讨论】:

  • 我在问题中添加了活动和片段代码。你能解释一下这个“代码块 2”中的 mRecyclerView 是什么吗?据我了解,它应该在我的 onClickHotelAmenityExpandContainer() 方法中。如果mRecyclerView我的回收站视图在片段中,我怎样才能获得对它的引用?请检查添加的 Java 代码。
  • @ChathurangaShanJayarathna 我已经更新了我的答案,在你的项目中添加一些逻辑,看看。
  • 成功了。我在这个问题上被困了 2 天。谢谢。
  • @ChathurangaShanJayarathna 干杯伙伴!如果您将赏金奖励给我的回答,我将不胜感激
  • 我做了并弹出消息,它将在 18 小时后应用。
【解决方案2】:

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

您的框架正上方有一个&lt;include/&gt; 布局,我怀疑这将具有正确的布局属性,因此您的框架布局有点“浮动”在无人区。

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

您可能希望框架布局位于&lt;NestedScrollView&gt; 中,然后我猜您可能没有使用包含,所以只需删除它即可。像这样的:

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

【讨论】:

  • 不过,两个视图都一起向下和向上滚动。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多