2015-09-18 104 views
9

我的FrameLayout(抽屉布局中的容器)有问题。 FrameLayout的高度超过屏幕高度(在底部的android默认菜单按钮下方)。Android - 框架布局高度与协调器布局不匹配

<android.support.design.widget.CoordinatorLayout 
     android:id="@+id/main_content" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 

     <android.support.design.widget.AppBarLayout 
      android:id="@+id/navContainer" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content"> 

      <android.support.v7.widget.Toolbar 
       android:id="@+id/toolbar" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:minHeight="?attr/actionBarSize" 
       app:layout_scrollFlags="scroll|enterAlways" /> 

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

     <FrameLayout 
      android:id="@+id/container" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

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

Height exceeding as seen in Android Studio Designer

+1

我得到同样的问题,这是Android的协调bug或者是他们这方面的任何解决办法。 (没有把margin margin作为动作栏高度的尺寸) – DeepakPanwar

回答

4

我第一次尝试是在FrameLayout里设置android:layout_marginBottom="?attr/actionBarSize"。这就解决了无滚动视图的解决方案,该视图在没有垂直滚动内容的情况下具有“固定”高度(就像通常的具有match_parent高度的RelativeLayout一样)。将组件对齐到父级底部(android:layout_alignParentBottom="true")将产生仍然可见的元素。在Android Studio的预览器中,不会超出高度。

但是,这个marginBotton修复引入了一个新的问题,它的根视图是可滚动的(比如RecyclerView)。对于这些视图,向下滚动时,底部边距将在白色条中变为可见(如果白色是背景色)。这接缝合理,为那些享有嵌套的滚动功能会滑出工具栏 ListView with last item cut

TL;博士我工作围绕这一问题通过应用的?attr/actionBarSize为底边距非滚动片段在里面显示Framelayout。在此之前,我将工具栏的高度设置为?attr/actionBarSize

活动布局:

 <android.support.design.widget.AppBarLayout 
      android:id="@+id/navContainer" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content"> 

      <android.support.v7.widget.Toolbar 
       android:id="@+id/toolbar" 
       android:layout_width="match_parent" 
       android:layout_height="?attr/actionBarSize" 
       app:layout_scrollFlags="scroll|enterAlways" /> 

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

     <FrameLayout 
       android:id="@+id/container" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       app:layout_behavior="@string/appbar_scrolling_view_behavior" 
     /> 

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

片段布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_marginBottom="?attr/actionBarSize" 
      android:orientation="vertical"> 
      <!-- Further stuff here --> 
      <TextView android:id="@+id/label" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_alignParentBottom="true" 
      /> 
    </LinearLayout> 

我现在面临唯一的缺点是在Android Studio中的预览器中显示在创建片段布局的白色空间。

+0

这对我来说很好用!作为一个侧面提示,如果您的某个片段具有隐藏应用栏的可滚动根目录,则在导航回到先前(不可滚动)片段时无法再次显示该片段时,它将保持隐藏状态。有解决此问题的办法[可在此处](http://stackoverflow.com/q/30554824/1794631)。 – rmorrin

1

如果您在CoordinatorLayout中使用不同的Fragments,您将面临问题,即某些Fragments有可滚动内容,有些不应该滚动。你的Toolbar有滚动标志“scroll|enterAlways”,这对于以前的布局是可以的,但对于后者不好。我的解决方案是自定义AppBarLayout.Behavior,它根据自定义标记(contentShouldNotScrollTag)切换滚动标志。设置此标签的布局,这不应该滚动这样的:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:tag="@string/contentShouldNotScrollTag"> 
    <!-- my non-scrollable Fragment layout --> 
</FrameLayout> 

结果,该片段的高度不会超过屏幕的高度。下面是AppBarLayout定制行为类:

public class MyScrollBehavior extends AppBarLayout.Behavior { 
    private View content; 

    public MyScrollBehavior(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public boolean onMeasureChild(CoordinatorLayout parent, AppBarLayout appBarLayout, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) { 
     if(content == null) { 
      content = parent.findViewById(R.id.container); 
     } 

     if(content != null) { 
      boolean shouldNotScroll = content.findViewWithTag(parent.getContext().getString(R.string.contentShouldNotScrollTag)) != null; 
      Toolbar toolbar = (Toolbar) appBarLayout.findViewById(R.id.toolbar); 
      AppBarLayout.LayoutParams params = 
        (AppBarLayout.LayoutParams) toolbar.getLayoutParams(); 
      if (shouldNotScroll) { 
       params.setScrollFlags(0); 
       appBarLayout.setExpanded(true, true); 
      } else { 
       params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL 
         | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); 
      } 
     } 

     return super.onMeasureChild(parent, appBarLayout, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed); 
    } 
}