2017-05-01 80 views
2

組合我有有很多textviews的「細節」片段,relativelayouts等。這些包裹裏面NestedScrollView:FAB與NestedScrollView

<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="?android:attr/windowBackground" 
    android:orientation="vertical" 
    android:paddingBottom="10dp"> 

    <android.support.v4.widget.NestedScrollView 
     android:id="@+id/movie_details_scroll" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     // Here are the textviews, relativelayouts etc... 
    </android.support.v4.widget.NestedScrollView> 

    <android.support.design.widget.FloatingActionButton 
     android:id="@+id/edit_movies_fab" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom|end" 
     android:layout_margin="@dimen/fab_margin" 
     android:src="@drawable/ic_edit_white_24dp" 
    /> 
</android.support.design.widget.CoordinatorLayout> 

現在我想在底部添加FAB (不在嵌套滾動視圖的底部),當我滾動瀏覽nestedscrollview時,它也向下滾動。但是通過我的代碼,FAB始終位於nestedscrollview的底部。所以當我一直向下滾動FAB出現。我想的是,FAB總是在右下角可見......

編輯

我忘了提,我用褪色的動作條(https://github.com/ManuelPeinado/FadingActionBar),但有些編輯。

相關的代碼:

m_FadingActionBarHelper.createView(getContext()); // this will create the view with header content etc. 

的CreateView的:

public final View createView(LayoutInflater inflater) { 
    // 
    // Prepare everything 

    mInflater = inflater; 
    if (mContentView == null) { 
    mContentView = inflater.inflate(mContentLayoutResId, null); // this will load my view which i already posted. 
    } 
    if (mHeaderView == null) { 
    mHeaderView = inflater.inflate(mHeaderLayoutResId, null, false); 
    } 

    // See if we are in a ListView, WebView or ScrollView scenario 

    ListView listView = (ListView) mContentView.findViewById(android.R.id.list); 
    View root; 
    if (listView != null) { 
    root = createListView(listView); 
    } else if (mContentView instanceof CDMObservableWebViewWithHeader){ 
    root = createWebView(); 
    } else { 
    root = createScrollView(); // this will be called in my example 
    } 

    if (mHeaderOverlayView == null && mHeaderOverlayLayoutResId != 0) { 
    mHeaderOverlayView = inflater.inflate(mHeaderOverlayLayoutResId, mMarginView, false); 
    } 
    if (mHeaderOverlayView != null) { 
    mMarginView.addView(mHeaderOverlayView); 
    } 

    // Use measured height here as an estimate of the header height, later on after the layout is complete 
    // we'll use the actual height 
    int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY); 
    int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY); 
    mHeaderView.measure(widthMeasureSpec, heightMeasureSpec); 
    updateHeaderHeight(mHeaderView.getMeasuredHeight()); 

    root.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
     int headerHeight = mHeaderContainer.getHeight(); 
     if ((!mFirstGlobalLayoutPerformed || (headerHeight != mLastHeaderHeight)) && headerHeight != 0) { 
     updateHeaderHeight(headerHeight); 
     mFirstGlobalLayoutPerformed = true; 
     } 
    } 
    }); 
    return root; 
} 

的createScrollView:

private View createScrollView() { 
    ViewGroup scrollViewContainer = (ViewGroup) mInflater.inflate(R.layout.fab__scrollview_container, null); 

    CDMObservableScrollView scrollView = (CDMObservableScrollView) scrollViewContainer.findViewById(R.id.fab__scroll_view); 
    scrollView.setOnScrollChangedCallback(mOnScrollChangedListener); 

    ViewGroup contentContainer = (ViewGroup) scrollViewContainer.findViewById(R.id.fab__container); 
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
      LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
    mContentView.setLayoutParams(layoutParams); 
    contentContainer.addView(mContentView); 
    mHeaderContainer = (FrameLayout) scrollViewContainer.findViewById(R.id.fab__header_container); 
    initializeGradient(mHeaderContainer); 
    mHeaderContainer.addView(mHeaderView, 0); 
    mMarginView = (FrameLayout) contentContainer.findViewById(R.id.fab__content_top_margin); 

    return scrollViewContainer; 
} 

將要加載的XML:

<denis.de.meperdia.fadingactionbar.CDMRootLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <include layout="@layout/fab__header_container"/> 

    <denis.de.meperdia.fadingactionbar.CDMObservableScrollView 
     android:id="@+id/fab__scroll_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <LinearLayout 
      android:id="@+id/fab__container" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical"> 

      <FrameLayout 
       android:id="@+id/fab__content_top_margin" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:background="@android:color/transparent"/> 
     </LinearLayout> 
    </denis.de.meperdia.fadingactionbar.CDMObservableScrollView> 

</denis.de.meperdia.fadingactionbar.CDMRootLayout> 

類CDMRootLayout:

public class CDMRootLayout extends CoordinatorLayout { 

    private View mHeaderContainer; 
    private View mListViewBackground; 
    private boolean mInitialized = false; 

    public CDMRootLayout(Context context) { 
    super(context); 
    } 

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

    public CDMRootLayout(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    } 

    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
    //at first find headerViewContainer and listViewBackground 
    if(mHeaderContainer == null) 
     mHeaderContainer = findViewById(R.id.fab__header_container); 
    if(mListViewBackground == null) 
     mListViewBackground = findViewById(R.id.fab__listview_background); 

    //if there's no headerViewContainer then fallback to standard FrameLayout 
    if(mHeaderContainer == null) { 
     super.onLayout(changed, left, top, right, bottom); 
     return; 
    } 

    if(!mInitialized) { 
     super.onLayout(changed, left, top, right, bottom); 
     //if mListViewBackground not exists or mListViewBackground exists 
     //and its top is at headercontainer height then view is initialized 
     if(mListViewBackground == null || mListViewBackground.getTop() == mHeaderContainer.getHeight()) 
     mInitialized = true; 
     return; 
    } 

    //get last header and listViewBackground position 
    int headerTopPrevious = mHeaderContainer.getTop(); 
    int listViewBackgroundTopPrevious = mListViewBackground != null ? mListViewBackground.getTop() : 0; 

    //relayout 
    super.onLayout(changed, left, top, right, bottom); 

    //revert header top position 
    int headerTopCurrent = mHeaderContainer.getTop(); 
    if(headerTopCurrent != headerTopPrevious) { 
     mHeaderContainer.offsetTopAndBottom(headerTopPrevious - headerTopCurrent); 
    } 
    //revert listViewBackground top position 
    int listViewBackgroundTopCurrent = mListViewBackground != null ? mListViewBackground.getTop() : 0; 
    if(listViewBackgroundTopCurrent != listViewBackgroundTopPrevious) { 
     mListViewBackground.offsetTopAndBottom(listViewBackgroundTopPrevious - listViewBackgroundTopCurrent); 
    } 
    } 
} 

和類CDMObservableScrollView:

public class CDMObservableScrollView extends ScrollView implements CDMObservableScrollable { 
    // Edge-effects don't mix well with the translucent action bar in Android 2.X 
    private boolean mDisableEdgeEffects = true; 

    private CDMOnScrollChangedCallback mOnScrollChangedListener; 

    public CDMObservableScrollView(Context context) { 
     super(context); 
    } 

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

    public CDMObservableScrollView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
     super.onScrollChanged(l, t, oldl, oldt); 
     if (mOnScrollChangedListener != null) { 
     mOnScrollChangedListener.onScroll(l, t); 
     } 
    } 

    @Override 
    protected float getTopFadingEdgeStrength() { 
     // http://stackoverflow.com/a/6894270/244576 
     if (mDisableEdgeEffects && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
     return 0.0f; 
     } 
     return super.getTopFadingEdgeStrength(); 
    } 

    @Override 
    protected float getBottomFadingEdgeStrength() { 
     // http://stackoverflow.com/a/6894270/244576 
     if (mDisableEdgeEffects && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
     return 0.0f; 
     } 
     return super.getBottomFadingEdgeStrength(); 
    } 

    @Override 
    public void setOnScrollChangedCallback(CDMOnScrollChangedCallback callback) { 
     mOnScrollChangedListener = callback; 
    } 
} 

EDIT 2

我可以劃現在的問題:

如果我這些行FAB按我想要的方式工作:

<denis.de.meperdia.fadingactionbar.CDMObservableScrollView 
     android:id="@+id/fab__scroll_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

但後來我的衰落操作欄的控制同步被摧毀...

對不起那麼多的代碼,但它真的複雜沒有這個理解。

+0

您可以使用包裝嵌套滾動視圖的框架佈局和FAB – Arunava

+0

已經嘗試過。不工作。 – beeb

+0

用'FrameLayout'替換'CoordinatorLayout'。它應該工作正常 – Arunava

回答

-1

最後我解決了這個問題,將FloatingActionButton從內容佈局移到了外面。

我的容器佈局是這樣的:

<?xml version="1.0" encoding="utf-8"?> 
<denis.de.meperdia.fadingactionbar.CDMRootLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <include layout="@layout/fab__header_container"/> 

    <denis.de.meperdia.fadingactionbar.CDMObservableScrollView 
     android:id="@+id/fab__scroll_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <LinearLayout 
      android:id="@+id/fab__container" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical"> 

      <FrameLayout 
       android:id="@+id/fab__content_top_margin" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:background="@android:color/transparent"/> 
     </LinearLayout> 
    </denis.de.meperdia.fadingactionbar.CDMObservableScrollView> 

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

</denis.de.meperdia.fadingactionbar.CDMRootLayout> 

我加了一個集裝箱的FloatingActionButton我從另一個文件加載它填補動態。現在解決FloatingActionButton的移動問題。還有一點問題,但我爲此打開了一個新問題。

編輯

改變了我的解決方案。我有問題,如果我想顯示一個快餐欄,FloatingActionButton沒有正確滾動。我現在以編程方式將FloatingActionButton添加到根視圖。現在它工作正常。

0

更換android:layout_gravity="bottom|end"

與此android:layout_gravity="bottom|right"

+0

沒有工作。沒有改變。 – beeb

0

添加以下行NestedScrollView。

app:layout_behavior="@string/appbar_scrolling_view_behavior" 
+0

沒有工作。 ;( – beeb

-1

嘗試這個例子:

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 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" 
    tools:context="com.internet.Main2Activity"> 

    <android.support.design.widget.AppBarLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:theme="@style/AppTheme.AppBarOverlay"> 

     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?attr/actionBarSize" 
      android:background="?attr/colorPrimary" 
      app:popupTheme="@style/AppTheme.PopupOverlay" /> 

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

    <include 
     layout="@layout/content_main2" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

    <android.support.design.widget.FloatingActionButton 
     android:id="@+id/fab" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom|end" 
     android:layout_margin="@dimen/fab_margin" 
     app:srcCompat="@android:drawable/ic_dialog_email" /> 

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

content_main2。XML

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 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:orientation="vertical" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" 
    tools:context="com.internet.Main2Activity" 
    tools:showIn="@layout/activity_main2"> 

    <android.support.v4.widget.NestedScrollView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical"> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="100dp" 
       android:text="asdds" /> 
     </LinearLayout> 
    </android.support.v4.widget.NestedScrollView> 

</LinearLayout> 
+0

試過,但我有同樣的問題... – beeb

1

導入app命名空間,環繞NestedScrollViewRelativeLayout,然後設置RelativeLayoutanchorFAB

<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto"  //Import app namespace 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="?android:attr/windowBackground" 
    android:orientation="vertical" 
    android:paddingBottom="10dp"> 

    <RelativeLayout 
     android:id="@+id/mainview" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <android.support.v4.widget.NestedScrollView 
      android:id="@+id/movie_details_scroll" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

      // Here are the textviews, relativelayouts etc... 
     </android.support.v4.widget.NestedScrollView> 

    </RelativeLayout> 

    <android.support.design.widget.FloatingActionButton 
     android:id="@+id/edit_movies_fab" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_margin="@dimen/fab_margin" 
     android:src="@drawable/ic_edit_white_24dp" 
     app:layout_anchor="@id/mainview"   //attributes of app namespace 
     app:layout_anchorGravity="bottom|end" 
    /> 
</android.support.design.widget.CoordinatorLayout> 
+0

試過,但它沒有工作。我認爲問題是圍繞內容的佈局... – beeb

0

您可以輕鬆地做到這一點與協調佈局Anchor屬性爲你的工廠連接到任何您的視圖節點

CoordinatorLayout和使用layout_anchor和layout_anchorGravity屬性。

 <ListView 
      android:id="@+id/lvToDoList" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"></ListView> 
<android.support.design.widget.FloatingActionButton 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="bottom|right" 
      android:layout_margin="16dp" 
      android:src="@drawable/ic_done" 
      app:layout_anchor="@id/lvToDoList" 
      app:layout_anchorGravity="bottom|right|end" /> 

這將使FAB到aatch列表視圖在底部。你可以做任何其他佈局/視圖。

+0

試過,但它沒有工作。沒有列表視圖,你可以看到我有一個'NestedScrollView',我認爲問題在於'FloatingActionButton'不是'CDMRootLayout'的擴展'CoordinatorLayout'的直接子類,'FloatingActionButton'在'NestedScrollView'來代替,我已經通過將FloatingActionButton移動到外面解決了這個問題。 – beeb