简体   繁体   English

视图位于父级的最后位置,但仍被阻止

[英]View is in the last position of parent, but still being blocked

What I want to do 我想做的事

In a BottomSheetDialogFragment , I want to inflate a view that always stick at the bottom of the screen, no matter what state (collapsed / expanded) the BottomSheetBehavior is in. BottomSheetDialogFragment ,无论BottomSheetBehavior处于什么状态(折叠/展开) ,我都想要一个始终粘在屏幕底部的视图。

What I have done 我做了什么

In a subclass of BottomSheetDialogFragment , I inflate a view from XML and add it as a child of CoordinatorLayout (which is BottomSheetDialogFragment 's parent's parent): BottomSheetDialogFragment的子类中,我从XML中BottomSheetDialogFragment了一个视图,并将其添加为CoordinatorLayout的子项(这是BottomSheetDialogFragment的父项的父项):

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    setupBottomBar(getView());
}

private void setupBottomBar (View rootView) {
    CoordinatorLayout parentView = (CoordinatorLayout) ((FrameLayout)rootView.getParent()).getParent();
    parentView.addView(LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false), -1);
}

The code runs without error. 代码运行没有错误。
And when I use Layout Inspector to look at the View hierarchy, the view structure is also correct: 当我使用Layout Inspector查看View层次结构时,视图结构也是正确的:

布局检查器截图

You can also download the layout inspector result here , and open it using your own Android Studio. 您也可以在此处下载布局检查器结果,并使用您自己的Android Studio打开它。

The problem 问题

However, even though it is inserted as the last child of the CoordinatorLayout , it is still being blocked by the BottomSheetDialogFragment . 但是,即使它作为CoordinatorLayout的最后一个子项插入,它仍然被BottomSheetDialogFragment阻止。
When I slowly scroll the BottomSheetDialogFragemnt downwards (from collapsed state to hidden state), I can finally see the view that I want to inflate behind the fragment. 当我慢慢向下滚动BottomSheetDialogFragemnt (从折叠状态到隐藏状态)时,我终于可以看到我想在片段后面膨胀的视图。

查看已屏蔽

Why is this happening? 为什么会这样?

The answer 答案

As @GoodDev pointed out correctly, it is because the root view (design_bottom_sheet) has been set a Z translation by BottomSheetDialog . 正如@GoodDev正确指出的那样,这是因为根视图(design_bottom_sheet)已被BottomSheetDialog设置为Z转换。
This provides an important information that - not only sequence in a View hierarchy will determine its visibility, but also its Z translation. 这提供了一个重要信息 - 不仅View层次结构中的序列将决定其可见性,还会确定其Z转换。

The best way is to get the Z value of design_bottom_sheet and set it to the bottom bar layout. 最好的方法是获取design_bottom_sheet的Z值并将其设置为底栏设置。

private void setupBottomBar (View rootView) {
    CoordinatorLayout parentView = (CoordinatorLayout) (rootView.getParent().getParent());
    View barView = LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false);
    ViewCompat.setTranslationZ(barView, ViewCompat.getZ((View)rootView.getParent()));
    parentView.addView(barView, -1);
}

EDIT 2 编辑2

Ok, now I see your requirement, try this one: 好的,现在我看到你的要求,试试这个:

private void setupBottomBar (View rootView) {
    CoordinatorLayout parentView = (CoordinatorLayout) ((FrameLayout)rootView.getParent()).getParent();
    View view = LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false);
    // using TranslationZ to put the view on top of bottom sheet layout
    view.setTranslationZ(100);
    parentView.addView(view, -1);
}

EDIT: 编辑:

OK, I check your layout and check the BottomSheetDialogFragment source code, found the reason: 好的,我检查你的布局并检查BottomSheetDialogFragment源代码,找到原因:

In BottomSheetDialogFragment using BottomSheetDialog dialog, the method setContentView in BottomSheetDialog using wrapInBottomSheet to put the content view in R.id.design_bottom_sheet layout. BottomSheetDialogFragment使用BottomSheetDialog对话框,该方法setContentViewBottomSheetDialog使用wrapInBottomSheet投入在内容视图R.id.design_bottom_sheet布局。 So you need override the BottomSheetDialogFragment 's public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) to fix your problem. 因此,您需要覆盖BottomSheetDialogFragmentpublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)来修复您的问题。

Or, change your setupBottomBar method to: 或者,将setupBottomBar方法更改为:

private void setupBottomBar (View rootView) {
    FrameLayout frame = (FrameLayout)rootView.getParent();
    frame.addView(LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, frame, false), -1);
}

and in your item_selection_bar layout file, change height and layout_gravity: 并在您的item_selection_bar布局文件中,更改高度和layout_gravity:

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_gravity="bottom"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

BottomSheetDialogFragment doc says: Modal bottom sheet. BottomSheetDialogFragment doc说:模态底页。 This is a version of DialogFragment that shows a bottom sheet using BottomSheetDialog instead of a floating dialog. 这是DialogFragment的一个版本,它使用BottomSheetDialog而不是浮动对话框显示底部工作表。

So the BottomSheetDialogFragment is a Dialog , Dialog is a floating view, so will cover the Activity content when BottomSheetDialogFragment is showing. 因此BottomSheetDialogFragment是一个DialogDialog是一个浮动视图,因此当BottomSheetDialogFragment显示时将覆盖Activity内容。

@goodev has give a nice answer. @goodev给出了一个很好的答案。

Your problem 你的问题

View's Z position causes this problem. 查看Z位置会导致此问题。 Although the TextView is the last position you still can not see it. 虽然TextView是最后一个位置,但您仍然无法看到它。

在此输入图像描述在此输入图像描述

How to solve 怎么解决

You can set design_sheet_bottom's Z to TextView. 您可以将design_sheet_bottom's Z设置为TextView。

 private void setupBottomBar (View rootView) {
    CoordinatorLayout parentView = (CoordinatorLayout) ((FrameLayout)rootView.getParent()).getParent();
    View view = LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false);
    view.setZ(((View)rootView.getParent()).getZ());
    parentView.addView(view, -1);
}

And I think above way is very boring, can you put your two view RecyclerView and TextView into a layout ? 我认为上面的方式很无聊,你能把你的两个视图RecyclerViewTextView放到一个布局中吗? Then you can inflate theme together in onCreateView() method. 然后你可以在onCreateView()方法中一起膨胀主题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM