2015-09-18 105 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); 
    } 
}