代码之家  ›  专栏  ›  技术社区  ›  Sira Lam

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

  •  4
  • Sira Lam  · 技术社区  · 8 年前

    我想做什么

    在一个 BottomSheetDialogFragment ,我想膨胀一个始终停留在屏幕底部的视图,无论发生什么 state (collapsed / expanded) 这个 BottomSheetBehavior 已加入。

    我所做的

    在的子类中 BottomSheetDialogFragment ,我从XML膨胀视图,并将其添加为 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);
    }
    

    代码运行时没有错误。
    当我使用布局检查器查看视图层次时,视图结构也是正确的:

    Layout Inspector Screenshot

    也可以下载布局检查器结果 here ,并使用您自己的Android Studio打开它。

    问题所在

    但是,即使它是作为 协调人布局 ,它仍被 BottomSheetDialogFragment .
    当我慢慢滚动 BottomSheetDialogFragemnt 向下(从折叠状态到隐藏状态),我终于可以看到我想在片段后面膨胀的视图。

    View blocked

    为什么会这样?

    答案是

    正如@GoodDev正确指出的那样,这是因为根视图(design\u bottom\u sheet)被设置为Z平移 BottomSheetDialog .
    这提供了一个重要信息- 不仅视图层次中的序列将决定其可见性,还将决定其Z平移。

    最好的方法是获得 design_bottom_sheet 并将其设置为底部栏布局。

    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);
    }
    
    2 回复  |  直到 8 年前
        1
  •  2
  •   goodev    8 年前

    编辑2

    好的,现在我知道你的要求了,试试这个:

    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);
    }
    

    编辑:

    好的,我检查一下你的布局 BottomSheetDialogFragment 源代码,找到原因:

    在里面 BottomSheetDialogFragment 使用 BottomSheetDialog 对话框,方法 setContentView 在里面 BottomSheetDialog 使用 wrapInBottomSheet 将内容视图放入 R.id.design_bottom_sheet 布局所以你需要重写 BottomSheetDialogFragment public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 解决您的问题。

    或者,更改 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);
    }
    

    在你的 item_selection_bar 布局文件,更改高度和layout\u重力:

    <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 文件上写着:模态底片。这是DialogFragment的一个版本,它使用 底部工作表对话框 而不是浮动对话框。

    所以 BottomSheetDialogFragment 是一个 Dialog , 对话 是浮动视图,因此将覆盖活动内容 BottomSheetDialogFragment 正在显示。

        2
  •  1
  •   CoXier    8 年前

    @古德夫给出了一个很好的回答。

    你的问题

    视图的 Z 位置导致此问题。 虽然文本视图是最后一个位置,但您仍然无法看到它。

    enter image description here enter image description here

    如何解决

    您可以设置 design_sheet_bottom's Z 至文本视图。

     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);
    }
    

    而且我觉得上面的方式很无聊,你能把你的两种观点 RecyclerView TextView 进入布局?然后您可以在 onCreateView() 方法