我有一个"详细信息"片段有很多textview,relativelayouts等。这些片段包含在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 的底部),当我滚动浏览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;
}
}
编辑2
我现在可以解决问题:
如果我这些线路FAB按我的意愿工作:
<denis.de.meperdia.fadingactionbar.CDMObservableScrollView
android:id="@+id/fab__scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
但是我的褪色动作条的同步被摧毁......
对于那么多代码感到抱歉,但如果没有这个代码就很难理解。
答案 0 :(得分:3)
导入app
命名空间,用NestedScrollView
围绕RelativeLayout
,然后将RelativeLayout
设置为anchor
FAB
。
<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>
答案 1 :(得分:0)
替换android:layout_gravity="bottom|end"
使用此android:layout_gravity="bottom|right"
答案 2 :(得分:0)
在NestedScrollView中添加以下行。
app:layout_behavior="@string/appbar_scrolling_view_behavior"
答案 3 :(得分:0)
您可以使用“坐标布局”锚点属性轻松执行此操作,以将fab连接到任何视图节点
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能够在底部列出视图。您可以对任何其他布局/视图执行相同操作。
答案 4 :(得分:-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>
答案 5 :(得分:-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
添加到根视图中。现在它正常工作。