尊重劳动成果,转载请注明出处:http://blog.youkuaiyun.com/growth58/article/details/48754869
关注新浪微博:@于卫国
邮箱:yuweiguocn@gmail.com
Google在2015 I/O大会上公布了Material Design Support Library,使用它可以创建materail应用在API 19以下突然变得很容易。在这个系列中,我们将使用RSS阅读器应用,我们用于Material系列的基础应用,重写让它完全使用新的Design Support Library。在这篇文章中我们将添加一个Floating Action Button or FAB 。
在开始之前值得注意的是这个应用根本不需要一个FAB 因为这没有动作可执行。然而,为了展示目前添加一个FAB 有多么容易,我从Douglas Adams获得一点灵感:
“Arthur Dent:如果我按下这个按钮会发生什么?
Ford Prefect:我不知道。
Arthur Dent:Oh.
Ford Prefect:发生了什么?
Arthur Dent:亮起一个标志,说‘请不要再按这个按钮’。”
——Douglas Adams, The Original Hitchhiker Radio Scripts
因此我们将会添加一个FAB,当按下时弹出一个Snackbar 说“请不要再按这个按钮” 。
首先我们需要添加一个FloatingActionButton 到我们布局文件:
res/layout/include_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"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<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.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingLeft="@dimen/home_offset"
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="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/ic_block" />
</android.support.design.widget.CoordinatorLayout>
做其它事情之前,我们先看一下效果:
Oh noes!我们的FAB是白色的并且看起来相当丑陋。还记得在我们的TabLayout 中我们遇到 indicator bar 的颜色的问题,我们设置了它为白色来匹配文字?你猜怎么着?accent 颜色同样被用来FAB 的颜色。然而它很容易被修复,让我们使用accent 颜色让它在这两种情况都能工作:
res/values/colors.xml
<resources>
<color name="sa_green">#1E9618</color>
<color name="sa_green_dark">#146310</color>
<color name="sa_green_transparent">#201E9618</color>
<color name="sa_accent">#4EE147</color>
</resources>
res/values/styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Base.AppTheme" />
<style name="Base.AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/sa_green</item>
<item name="colorPrimaryDark">@color/sa_green_dark</item>
<item name="colorAccent">@color/sa_accent</item>
<item name="colorControlHighlight">@color/sa_green_transparent</item>
</style>
</resources>
这样看起来还不错:
剩下就是在我们的Activity中写上OnClickListener :
public class MainActivity extends AppCompatActivity implements ArticlesConsumer {
private static final String DATA_FRAGMENT_TAG = DataFragment.class.getCanonicalName();
private static final int MENU_GROUP = 0;
private DrawerLayout drawerLayout;
private NavigationView navigationView;
private ViewPager viewPager;
private TabLayout tabLayout;
private FloatingActionButton fab;
private Articles articles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
viewPager = (ViewPager) findViewById(R.id.viewpager);
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
fab = (FloatingActionButton) findViewById(R.id.fab);
setupToolbar();
setupNavigationView();
setupDataFragment();
setupFab();
}
private void setupFab() {
fab.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar.make(v, R.string.fab_press, Snackbar.LENGTH_LONG).show();
}
});
}
}
现在我们可以尝试看一下效果:
注意到FAB是怎样随着Snackbar向上移动的吗?我们没有做任何事情获取这个行为,所以发生了什么?它是我们的朋友CoordinatorLayout 又一次在后台做的处理。
当Snackbar 被创建时我们通过参考一个View ——在这种情况下它是FAB 生成onClick()调用。Snackbar 查看这个View 的父布局,如果它发现一个CoordinatorLayout 并且用CoordinatorLayout 注册了它的行为。FloatingActionButton 也用CoordinatorLayout 注册了它自己的行为,它依赖于Snackbar 的行为,当Snackbar 进出时CoordinatorLayout 会传递相关的信息。它甚至是很智能的,在大屏幕上Snackbar 不会拉伸至全宽,它不会移动FAB 因为不需要。
相当整洁,并且我们不需要做任何事情!
为了证明CoordinatorLayout 的执行逻辑,简单地通过CoordinatorLayout 之外的View 调用Snackbar.make()方法,你会看到这个漂亮的行为停止了。
这有一个真的需要提及的问题。如果你在Android 4.x 设备上运行这个代码FAB 的渲染相当难看的:
这有一个很简单的变通办法,在布局文件中添加app:borderWidth=”0dp” 属性到FloatingActionButton ,一切看起来都好了:
这个解决办法来自于 Chris Banes via Sebastiano Poggi 因此我猜测它将会在未来的design support library版本中被修复。多亏了Seb & Chris 提供给我如此简单的变通办法。
随着这个最后的问题,所有的示例图片和视频已经完成从Lollipop 设备上并且我们期待一个完全material 体验,但是怎么做才能很好地运行在旧版本的Android设备上呢?在下一篇文章我们将学习关于向后兼容的技巧。
源代码可以从这下载。
请我喝杯咖啡,请使用支付宝扫描下方二维码: