Sim*_*mon 12 android android-viewpager floating-action-button
我正在尝试做一些非常简单的事情.
我希望FAB只显示在我的TabLayout中的一个选项卡上,并在导航到另一个选项卡时隐藏.因此,例如,一个选项卡允许您在FAB中添加新项目,但下一个选项卡不允许您添加项目.
我遵循了"典型的"XML设计布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
xmlns:tools="http://schemas.android.com/tools"
>
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways">
<LinearLayout
android:id="@+id/search_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/search_view"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="@android:color/transparent"
android:gravity="center_vertical"
android:hint="Search"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:paddingLeft="2dp"
android:singleLine="true"
android:textColor="#ffffff"
android:textColorHint="#b3ffffff" />
<ImageView
android:id="@+id/search_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:src="@drawable/ic_action_cancel" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:tabMode="scrollable"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.example.simon.behaviours.PatchedScrollingViewBehavior"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
app:borderWidth="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_new"
android:layout_margin="16dp"
android:layout_gravity="bottom|right"
app:layout_anchor="@+id/viewPager"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="com.example.simon.behaviours.ScrollingFABBehavior"
android:visibility="gone"
app:fabSize="normal">
</android.support.design.widget.FloatingActionButton>
</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)
我对FAB使用了以下行为.这导致任何upscrolls导致FAB消失,并将在缩减滚动时返回到屏幕上:
public class ScrollingFABBehavior extends FloatingActionButton.Behavior {
private int toolbarHeight;
public ScrollingFABBehavior(Context context, AttributeSet attrs) {
super();
this.toolbarHeight = getToolbarHeight(context);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
return super.layoutDependsOn(parent, fab, dependency) || (dependency instanceof AppBarLayout);
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
boolean returnValue = super.onDependentViewChanged(parent, fab, dependency);
if (dependency instanceof AppBarLayout) {
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
int fabBottomMargin = lp.bottomMargin;
int distanceToScroll = fab.getHeight() + fabBottomMargin;
float ratio = (float)dependency.getY()/(float)toolbarHeight;
fab.setTranslationY(-distanceToScroll * ratio);
}
return returnValue;
}
public static int getToolbarHeight(Context context) {
final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(
new int[]{R.attr.actionBarSize});
int toolbarHeight = (int) styledAttributes.getDimension(0, 0);
styledAttributes.recycle();
return toolbarHeight;
}
}
Run Code Online (Sandbox Code Playgroud)
我添加了一个viewpager addOnPageChangeListener:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (position == 0) {
FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setVisibility(View.VISIBLE);
}
else
{
FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setVisibility(View.GONE);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
Run Code Online (Sandbox Code Playgroud)
我只希望FAB出现在第一页上,并在所有其他页面上消失.
代码可以工作但是当我向下滑动下一页时,即使可见性设置为消失,FAB也会出现.我认为它与FAB的行为设置有关.有没有人知道为什么如果能见度设定消失,FAB仍然会在向下滑动时变得可见?
这并不是我想在我的应用程序中实现的东西,但我确实设法找到答案,最后通过查看他们如何在wordpress应用程序上实现相同的东西得到一些帮助.
在wordpress应用程序中,我们在应用程序的第一页上看到一个浮动操作按钮,如果您滑动到viewpager上的任何其他页面,它会消失:
他们通过以下代码执行此操作 - 这是包含viewpager的Activity的代码.您可以在onPageScrolled方法下查看代码的相关部分,该方法包含每次滚动页面时发布事件的事件总线.该事件只包含一个名为positionOffset的变量,它是一个从0到1的整数值.如果滚动并且页面位于两个视图之间的中间位置,则positionOffset为0.5,您会明白:
WPMainActivity.java
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
AppPrefs.setMainTabIndex(position);
switch (position) {
case WPMainTabAdapter.TAB_NOTIFS:
new UpdateLastSeenTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
break;
}
trackLastVisibleTab(position);
}
@Override
public void onPageScrollStateChanged(int state) {
// noop
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// fire event if the "My Site" page is being scrolled so the fragment can
// animate its fab to match
if (position == WPMainTabAdapter.TAB_MY_SITE) {
EventBus.getDefault().post(new MainViewPagerScrolled(positionOffset));
}
}
});
Run Code Online (Sandbox Code Playgroud)
在包含以下代码的片段中拾取事件.该事件将触发translateY方法,该方法在页面滚动时根据positionOffset确定的页面滚动视图的距离垂直地动画FAB:
MySiteFragment
/*
* animate the fab as the users scrolls the "My Site" page in the main activity's ViewPager
*/
@SuppressWarnings("unused")
public void onEventMainThread(CoreEvents.MainViewPagerScrolled event) {
mFabView.setTranslationY(mFabTargetYTranslation * event.mXOffset);
}
Run Code Online (Sandbox Code Playgroud)
最后,my_site_fragment.xml中的布局显示FAB实际上放在片段xml而不是活动xml中.
<!-- this coordinator is only here due to https://code.google.com/p/android/issues/detail?id=175330 -->
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_marginRight="@dimen/fab_margin"
android:src="@drawable/gridicon_create_light"
app:borderWidth="0dp"
app:rippleColor="@color/fab_pressed" />
</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)
嘿,我遇到了和你完全一样的问题。
我找到了两种对我有用的方法。
方法一:
在 MainActivity: 中添加一个静态标志
public static boolean fabVisible;。
我注意到您有一个侦听器viewPager可以检测当前片段页面,因此您可以添加以下内容:
public void onPageSelected(int position) {
switch (position) {
case 0:
fabVisible = true;
mFloatingActionButton.show();
break;
default:
fabVisible = false;
mFloatingActionButton.hide();
break;
}
}
Run Code Online (Sandbox Code Playgroud)
在您的自定义 fab 行为中,添加以下代码:
if (dyConsunmed > 0 && child.getVisibility() == View.VISIBLE ) {
child.hide();
} else if (dyConsunmed < 0 && child.getVisibility() != View.VISIBLE && MainActivity.fabVisible) {
child.show();
}
Run Code Online (Sandbox Code Playgroud)
此方法的重点是确保在实现隐藏和显示方法之前 fab 应该是可见的。
方法二:
您不再需要添加任何标志,例如“fabVisible” MainActivity。尽管此方法确实需要您在 中将 设置viewPager为静态MainActivity,因为我们需要能够在我们的自定义 fab 行为类中访问它。
在您的ScrollAwareFABBehavior类中,添加以下代码:
if (MainActivity.viewPager.getCurrentItem() == 0) {
if (dyConsunmed > 0 && child.getVisibility() == View.VISIBLE ) {
child.hide();
} else if (dyConsunmed < 0 && child.getVisibility() != View.VISIBLE) {
child.show();
}
}
Run Code Online (Sandbox Code Playgroud)
这个方法的关键点是,当你在你想要的片段中时,只执行显示和隐藏方法(在我的例子中它是片段一,所以当前项 == 0)。当然,为了删除第二个片段中的 fab,您仍然需要将它隐藏在您的 viewPager 侦听器中。
如果您仍然对实现感到困惑,请随时查看我在 GitHub 上的存储库并使用代码。地址为:https : //github.com/Anthonyeef/FanfouDaily
虽然提要内容全是中文,但代码全是英文。
| 归档时间: |
|
| 查看次数: |
19874 次 |
| 最近记录: |