Android 底部粘滞按钮在滚动时上下移动
Android Bottom Sticky Button moves up down on scroll
我有一个选项卡式布局,我想在底部有一个粘滞按钮。
当布局大于屏幕大小时,我可以向上滚动,工具栏也会向上滚动以将选项卡对齐为最顶部的元素。当我滚动时,按钮也会向上滚动,因为我在底部有一个填充以在启动时保持它的状态。
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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="io.sampleapp.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
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:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
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>
fragment_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="io.sampleapp.MainActivity$PlaceholderFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/mRecyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/bottomButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="54dp"
android:background="#555555"
android:text="dummy"
android:textColor="#ffffff" />
</RelativeLayout>
将按钮放在 RecyclerView 之外。
我能说的是,您可能试图在不遵循正确的 material 设计指南的情况下实现用例。
为什么不使用 FAB 又名 FloatingActionButton?
我认为 Button 应该在 CoordinatorLayout
标签之外,尝试从 fragment_main.xml
中删除 Button 并将其添加到 activity_main.xml
,例如:
<android.support.v4.view.ViewPager
... />
<android.support.design.widget.AppBarLayout
<android.support.design.widget.CoordinatorLayout
...
</android.support.design.widget.CoordinatorLayout>
<Button
android:id="@+id/bottomButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="54dp"
android:background="#555555"
android:text="dummy"
android:textColor="#ffffff" />
</android.support.design.widget.AppBarLayout>
在其他片段中,如果您不需要该按钮,可以将其设置为不可见。
我建议,删除按钮的边距底部,并将边距底部添加到高度与按钮高度相同的回收站视图
我不想让浮动按钮在片段持有者或回收站之外,无论视图是什么,正如上面的回复所建议的那样。但是我想把按钮放在Fragment中,并用屏幕逻辑来维护它。
这就是我可以实现的。如果我们假设我们有一个 AppBarLayout
,并且在它里面我们有一个 CollapsingToolbarLayout
,并且这些视图被包裹在一个 CoordinatorLayout
.
中
我创建了一个 BaseFragment
和一个名为 setOffsetChanged
的 public 函数:
public void setOffsetChanged(AppBarLayout appBarLayout, int verticalOffset){
//Empty function
}
并在 MainActivity
中添加创建对 AppBarLayout
的引用的对象:
private AppBarLayout appBar;
protected void onCreate(Bundle savedInstanceState){
appBar = findViewById(R.id.appBar);
appBar.addOnOffsetChangedListener(this);
}
实施侦听器AppBarLayout.OnOffsetChangedListener
。
public class MainActivity extends AppCompatActivity
implements AppBarLayout.OnOffsetChangedListener{}
并添加其功能:
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments()
.get(getSupportFragmentManager().getFragments().size() - 1);
fragment.setOffsetChanged(appBarLayout, verticalOffset);
}
好的,现在我们只需要在我们有 "floating" 按钮的片段中的 BaseFragment
添加这个函数:
@Override
public void setOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
super.setOffsetChanged(appBarLayout, verticalOffset);
ConstraintLayout.LayoutParams buttonParams = (ConstraintLayout.LayoutParams) buttonHolder.getLayoutParams();
int marginBottomDP = (int) (SCALE * 100 + 0.5f); //100 because that is the space needed to appear besides the collapsed AppBarLayout
buttonParams.bottomMargin = ((verticalOffset * -1) - marginBottomDP) * -1;
buttonHolder.setLayoutParams(buttonParams);
}
就是这样。现在,我们的始终浮动按钮位于屏幕底部。
我有一个选项卡式布局,我想在底部有一个粘滞按钮。 当布局大于屏幕大小时,我可以向上滚动,工具栏也会向上滚动以将选项卡对齐为最顶部的元素。当我滚动时,按钮也会向上滚动,因为我在底部有一个填充以在启动时保持它的状态。
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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="io.sampleapp.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
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:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
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>
fragment_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="io.sampleapp.MainActivity$PlaceholderFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/mRecyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/bottomButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="54dp"
android:background="#555555"
android:text="dummy"
android:textColor="#ffffff" />
</RelativeLayout>
将按钮放在 RecyclerView 之外。
我能说的是,您可能试图在不遵循正确的 material 设计指南的情况下实现用例。
为什么不使用 FAB 又名 FloatingActionButton?
我认为 Button 应该在 CoordinatorLayout
标签之外,尝试从 fragment_main.xml
中删除 Button 并将其添加到 activity_main.xml
,例如:
<android.support.v4.view.ViewPager
... />
<android.support.design.widget.AppBarLayout
<android.support.design.widget.CoordinatorLayout
...
</android.support.design.widget.CoordinatorLayout>
<Button
android:id="@+id/bottomButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="54dp"
android:background="#555555"
android:text="dummy"
android:textColor="#ffffff" />
</android.support.design.widget.AppBarLayout>
在其他片段中,如果您不需要该按钮,可以将其设置为不可见。
我建议,删除按钮的边距底部,并将边距底部添加到高度与按钮高度相同的回收站视图
我不想让浮动按钮在片段持有者或回收站之外,无论视图是什么,正如上面的回复所建议的那样。但是我想把按钮放在Fragment中,并用屏幕逻辑来维护它。
这就是我可以实现的。如果我们假设我们有一个 AppBarLayout
,并且在它里面我们有一个 CollapsingToolbarLayout
,并且这些视图被包裹在一个 CoordinatorLayout
.
我创建了一个 BaseFragment
和一个名为 setOffsetChanged
的 public 函数:
public void setOffsetChanged(AppBarLayout appBarLayout, int verticalOffset){
//Empty function
}
并在 MainActivity
中添加创建对 AppBarLayout
的引用的对象:
private AppBarLayout appBar;
protected void onCreate(Bundle savedInstanceState){
appBar = findViewById(R.id.appBar);
appBar.addOnOffsetChangedListener(this);
}
实施侦听器AppBarLayout.OnOffsetChangedListener
。
public class MainActivity extends AppCompatActivity
implements AppBarLayout.OnOffsetChangedListener{}
并添加其功能:
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments()
.get(getSupportFragmentManager().getFragments().size() - 1);
fragment.setOffsetChanged(appBarLayout, verticalOffset);
}
好的,现在我们只需要在我们有 "floating" 按钮的片段中的 BaseFragment
添加这个函数:
@Override
public void setOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
super.setOffsetChanged(appBarLayout, verticalOffset);
ConstraintLayout.LayoutParams buttonParams = (ConstraintLayout.LayoutParams) buttonHolder.getLayoutParams();
int marginBottomDP = (int) (SCALE * 100 + 0.5f); //100 because that is the space needed to appear besides the collapsed AppBarLayout
buttonParams.bottomMargin = ((verticalOffset * -1) - marginBottomDP) * -1;
buttonHolder.setLayoutParams(buttonParams);
}
就是这样。现在,我们的始终浮动按钮位于屏幕底部。