Material Design: NavigationView FlaotingActionBar SnackBar的使用,navigationview

来源:互联网 发布:淘宝民族风女装品牌大全 编辑:程序博客网 时间:2024/05/18 00:43

Material Design: NavigationView FlaotingActionBar SnackBar的使用,navigationview


转载自:明桑Android 

上篇文章中主要介绍了Design Support Library的引入 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar..).今天则重点介绍其中三个控件:NavigationView和 FloatingActionBar以及 SnackBar的基本用法。

作为三者的综合练习,我们最终要实现的效果:

这里写图片描述

1,NavigationView

在未引入Design Support Library以前,想想我们要实现上面的导航效果,需要怎么做?

我们需要在DrawerLayout里面通过ListView来设置导航条目,然后通过设置ListView的ItemOnclickListener设置相应的点击事件;其实NavigationView的源码也是通过这种方式实现的,唯一复杂的地方就是ListView里的Item很多时候视图并不一样。

但我们今天的主角是NavigationView,所以就不展开讲这种实现方法了,对通过ListView实现有兴趣的可以参考下面两篇文章:

Android 自己实现 NavigationView [Design Support Library(1)]

Android Sliding Menu using Navigation Drawer

官方引入的NavigationView有什么好处

它主要是将这部分的布局简化了,通过NavigationView中的app:headerLayoutapp:menu属性将侧换导航中的头部和菜单布局分离出来(如图):

这里写图片描述

所以它的原理非常简单,我们首先需要一个主布局,然后需要为headerLayout以及menu布局,然后在代码中通过NavigationView的setNavigationItemSelectedListener()设置点击各个menu对应的响应事件。理解了上面所说,我们来完成上述效果:

1.引入Design Support Library

如何下载更新Design Support Library上篇文章中讲过,不再赘述:拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar..)

build.gradle中添加:

    compile 'com.android.support:design:22.2.0'

2.完成布局res/layout/activity_main.xml

<android.support.v4.widget.DrawerLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:id="@+id/drawer_layout"    android:layout_height="match_parent"    android:layout_width="match_parent"    android:fitsSystemWindows="true">    <!-- 主界面-->    <RelativeLayout        android:id="@+id/parent_layout"        android:layout_width="match_parent"        android:layout_height="match_parent">        <ImageView            android:id="@+id/image"            android:src="@mipmap/bg_default"            android:layout_centerInParent="true"            android:padding="5dp"            android:layout_width="match_parent"            android:layout_height="match_parent" />    </RelativeLayout>    <!-- 侧滑导航-->    <android.support.design.widget.NavigationView        android:id="@+id/navigation"        android:layout_gravity="start"        android:layout_width="match_parent"        android:layout_height="match_parent"        app:headerLayout="@layout/drawer_header"        app:menu="@menu/drawer_menu"/>    </android.support.v4.widget.DrawerLayout>

headerLayout布局res/layout/drawer_header.xml

<?xml version="1.0" encoding="utf-8"?>    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:background="@mipmap/bg_header"    android:paddingLeft="20dp"    android:paddingBottom="15dp"    android:layout_width="match_parent"    android:layout_height="180dp">    <ImageView        android:id="@+id/photo"        android:src="@mipmap/photo"        android:layout_above="@+id/desc"        android:layout_marginBottom="20dp"        android:layout_width="80dp"        android:layout_height="80dp" />    <TextView        android:id="@+id/desc"        android:layout_alignParentBottom="true"        android:text="欢迎关注个人博客 明桑Android"        android:textStyle="bold"        android:textColor="#ffffff"        android:textSize="20sp"        android:layout_marginBottom="2dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    </RelativeLayout>

menu的布局:

res/menu/drawer_menu.xml

<?xml version="1.0" encoding="utf-8"?>    <menu xmlns:android="http://schemas.android.com/apk/res/android">    <group>        <item android:id="@+id/navigation_item1"            android:checkable="true"            android:title="热门图片"            android:icon="@mipmap/icon_hot"/>        <item android:id="@+id/navigation_item2"            android:checkable="true"            android:title="联系人"            android:icon="@mipmap/icon_people"/>        <item android:id="@+id/navigation_item3"            android:checkable="true"            android:title="图库"            android:icon="@mipmap/icon_photos"/>    </group>    <item android:id="@+id/navigation_sub"        android:title="新增功能">        <menu>            <item android:id="@+id/navigation_sub_item1"                android:checkable="true"                android:title="地图导航"                android:icon="@mipmap/icon_local"/>            <item android:id="@+id/navigation_sub_item2"                android:checkable="true"                android:title="最近热门"                android:icon="@mipmap/icon_event"/>            <item android:id="@+id/navigation_sub_item3"                android:checkable="true"                android:title="社交圈子"                android:icon="@mipmap/icon_communities"/>        </menu>    </item>    </menu>

3.设置Theme:编辑res/values/styles.xml

<resources>    <!-- Base application theme. -->    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->    </style>    <style name="DemoTheme" parent="Theme.AppCompat.Light.NoActionBar">        <item name="colorPrimary">#38A4DE</item>        <item name="colorPrimaryDark">#1B88CA</item>        <item name="colorAccent">#1B88CA</item>    </style></resources>

至于colorPrimary,colorPrimaryDark,以及colorAccent属性各代表什么含义,我偏不说,大家不妨给每个设置不同的颜色值,然后看看有什么变化,你就明白它们所代表的意义了,O(∩_∩)O~

之后在Manifest.xml中将当前主题设置为DemoTheme

<application ...    android:theme="@style/DemoTheme" >

4.为NavigationView添加事件监听:现在我们已经完成上面的布局效果了,然后需要在MainActivity中为NavigationView添加响应事件:

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private DrawerLayout drawerLayout;    private ImageView imageView;    private NavigationView navigationView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        drawerLayout= (DrawerLayout) findViewById(R.id.drawer_layout);        imageView= (ImageView) findViewById(R.id.image);        navigationView= (NavigationView) findViewById(R.id.navigation);        //navigationView选中Item处理,为了代码整齐些,就放在一个函数里了        handNavigationView();    }    private void handNavigationView() {        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {            //用于辨别此前是否已有选中条目            MenuItem preMenuItem;            @Override            public boolean onNavigationItemSelected(MenuItem menuItem) {                //首先将选中条目变为选中状态 即checked为true,后关闭Drawer,以前选中的Item需要变为未选中状态                if(preMenuItem!=null)                    preMenuItem.setChecked(false);                menuItem.setChecked(true);                drawerLayout.closeDrawers();                preMenuItem=menuItem;                //不同item对应不同图片                switch (menuItem.getItemId()){                    case R.id.navigation_item1:                        imageView.setImageResource(R.mipmap.bg_one);                        break;                    case R.id.navigation_item2:                        imageView.setImageResource(R.mipmap.bg_two);                        break;                    case R.id.navigation_item3:                        imageView.setImageResource(R.mipmap.bg_three);                        break;                    case R.id.navigation_sub_item1:                        imageView.setImageResource(R.mipmap.bg_four);                        break;                    case R.id.navigation_sub_item2:                        imageView.setImageResource(R.mipmap.bg_five);                        break;                    case R.id.navigation_sub_item3:                        imageView.setImageResource(R.mipmap.bg_default);                        break;                }                return true;            }        });    }}

完成效果

这里写图片描述

2,FloatingActionBar(FAB)

FlaotingActionBar继承自ImageView,除了继承自ImageView的属性,它自身还有些跟动画、阴影相关的属性;重点熟悉下以下几个属性:

  fabSize="normal|mini" //FloatingActionBar的两种大小

这里写图片描述

   rippleColor="" //按下状态的波纹颜色

比如设置成白色:

这里写图片描述

elevation="6dp"pressedTranslationZ="12dp"backgroundTint="#ffffff"

evelation用来显示阴影,pressedTranslationZ用来控制按下状态阴影的变化;backgroundTint用来填充背景颜色;

borderWidth="0dp"

这个属性很关键,因为如果你不设置这个属性等于0dp,默认情况下borderWidth会将阴影遮挡住,你就看不到阴影了,看起来FloatingActionBar就不Floating了,而像贴上去的。

like this

这里写图片描述

关于Floating Action Menu:android-floating-action-button这是一个很流行的第三方库,实现的是弹出效果,有兴趣的可以研究下!

这里写图片描述

我们这次简单模仿下,不过只是通过点击下方FAB显示其它两个FAB,没有考虑弹出动画等效果。FAB的事件监听很简单,通过OnClickListener()即可。下面是具体实现步骤。

1.在主界面布局中res/layout/activity.xml中添加FloatingActionBar:总共三个FAB,刚开始我们让其它两个FAB不显示(通过Visibility=”gone”

<android.support.v4.widget.DrawerLayout    ...>    <!-- 主界面-->    <RelativeLayout        ...>        <ImageView            ... />        <!-- FloatingActonBar-->        <android.support.design.widget.FloatingActionButton            android:id="@+id/fab"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@mipmap/ic_add_white_24dp"            app:fabSize="normal"            android:layout_alignParentBottom="true"            android:layout_alignParentRight="true"            android:layout_marginBottom="70dp"            android:layout_marginRight="20dp"            app:rippleColor="#79BD4C"            app:elevation="6dp"            app:borderWidth="0dp"            app:pressedTranslationZ="12dp"/>        <android.support.design.widget.FloatingActionButton            android:id="@+id/fab_local"            android:visibility="gone"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@mipmap/ic_room_white_24dp"            app:fabSize="normal"            android:layout_above="@+id/fab"            android:layout_marginBottom="20dp"            android:layout_alignParentRight="true"            android:layout_marginRight="20dp"            app:backgroundTint="#79BD4C"            app:rippleColor="#ffffff"            app:elevation="6dp"            app:borderWidth="0dp"            app:pressedTranslationZ="12dp"/>        <android.support.design.widget.FloatingActionButton            android:id="@+id/fab_favorite"            android:visibility="gone"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@mipmap/ic_favorite_white_24dp"            app:fabSize="normal"            android:layout_above="@+id/fab_local"            android:layout_marginBottom="20dp"            android:layout_alignParentRight="true"            android:layout_marginRight="20dp"            app:backgroundTint="#FF4081"            app:rippleColor="#ffffff"            app:elevation="6dp"            app:borderWidth="0dp"            app:pressedTranslationZ="12dp"/>    </RelativeLayout>    <!-- 侧滑导航-->    <android.support.design.widget.NavigationView        .../></android.support.v4.widget.DrawerLayout>

2.完成MainActivity部分:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{    ...    private FloatingActionButton fab,fabLocal,fabFavorite;    //标识FloatingActionBar的打开状态    private  int FAB_STATE=1;    @Override    protected void onCreate(Bundle savedInstanceState) {        ....        fab= (FloatingActionButton) findViewById(R.id.fab);        fabLocal= (FloatingActionButton) findViewById(R.id.fab_local);        fabFavorite= (FloatingActionButton) findViewById(R.id.fab_favorite);        fab.setOnClickListener(this);        fabLocal.setOnClickListener(this);        fabFavorite.setOnClickListener(this);    }    /**     * Called when a view has been clicked.     *     * @param v The view that was clicked.     */    @Override    public void onClick(View v) {        switch(v.getId()){    //            点击fab弹出上面两个FAB,通过FAB_STATE判断当前fab的打开状态            case R.id.fab:                //如果没有打开,则弹出                if(FAB_STATE==1){                    fab.setImageResource(R.mipmap.ic_clear_white_24dp);                    fabLocal.setVisibility(View.VISIBLE);                    fabFavorite.setVisibility(View.VISIBLE);                    FAB_STATE=0;                    break;                }                //已经在打开状态,则关闭                if(FAB_STATE==0){                    fab.setImageResource(R.mipmap.ic_add_white_24dp);                    fabLocal.setVisibility(View.GONE);                    fabFavorite.setVisibility(View.GONE);                    FAB_STATE=1;                    break;                }                break;            case R.id.fab_local:                //弹出SnackBar,                break;            case R.id.fab_favorite:                break;        }    }}

实现效果

这里写图片描述

3,SnackBar

SnackBar的使用非常简单,只不过比Toast多了个Action监听,可以在未到消失时间之前通过用户点击而撤销,如果你对Toast的使用也不熟悉可以看看我以前写的这篇文章:

Android消息提示:AlertDialog、Toast、Notification的使用

//Snackbarmake(View view, CharSequence text, int duration)    第一个参数代表父布局,第二个代表显示的文本消息,第三个参数代表显示时长    //Snackbar.setAction(CharSequence text, View.OnClickListener listener)    第一个参数代表Action显示的文本,第二个参数代表动作监听    //可以通过setActionTextColor()设置Action文本颜色,如果不设置,默认颜色跟当前主题有关Snackbar.make(parentLayout,"你点击了FAB_LOCAL",Snackbar.LENGTH_LONG)                        .setAction("换个美女", new View.OnClickListener() {                    @Override                     public void onClick(View v) {                      //这里的单击事件代表点击消除Action后的响应事件,比如换掉背景图片                                imageView.setImageResource(R.mipmap.bg_six);                            }                        })                        .show();

显示效果:

这里写图片描述

4,完成我们的练习

综上我们已经掌握了NavigationViewFloatingActionBar Snakcbar的基本用法,可以完成我们最终的效果了:

MainActivity.java完整代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private DrawerLayout drawerLayout;    private RelativeLayout parentLayout;    private FloatingActionButton fab,fabLocal,fabFavorite;    private ImageView imageView;    private NavigationView navigationView;    //标识FloatingActionBar的打开状态    private  int FAB_STATE=1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        drawerLayout= (DrawerLayout) findViewById(R.id.drawer_layout);        parentLayout= (RelativeLayout) findViewById(R.id.parent_layout);        imageView= (ImageView) findViewById(R.id.image);        fab= (FloatingActionButton) findViewById(R.id.fab);        fabLocal= (FloatingActionButton) findViewById(R.id.fab_local);        fabFavorite= (FloatingActionButton) findViewById(R.id.fab_favorite);        navigationView= (NavigationView) findViewById(R.id.navigation);        //navigationView选中Item处理,为了代码整齐些,就放在一个函数里了        handNavigationView();        fab.setOnClickListener(this);        fabLocal.setOnClickListener(this);        fabFavorite.setOnClickListener(this);    }    private void handNavigationView() {        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {            //用于辨别此前是否已有选中条目            MenuItem preMenuItem;            @Override            public boolean onNavigationItemSelected(MenuItem menuItem) {                //首先将选中条目变为选中状态 即checked为true,后关闭Drawer,以前选中的Item需要变为未选中状态                if(preMenuItem!=null)                    preMenuItem.setChecked(false);                menuItem.setChecked(true);                drawerLayout.closeDrawers();                preMenuItem=menuItem;                //不同item对应不同图片                switch (menuItem.getItemId()){                    case R.id.navigation_item1:                        imageView.setImageResource(R.mipmap.bg_one);                        break;                    case R.id.navigation_item2:                        imageView.setImageResource(R.mipmap.bg_two);                        break;                    case R.id.navigation_item3:                        imageView.setImageResource(R.mipmap.bg_three);                        break;                    case R.id.navigation_sub_item1:                        imageView.setImageResource(R.mipmap.bg_four);                        break;                    case R.id.navigation_sub_item2:                        imageView.setImageResource(R.mipmap.bg_five);                        break;                    case R.id.navigation_sub_item3:                        imageView.setImageResource(R.mipmap.bg_default);                        break;                }                return true;            }        });    }    /**     * Called when a view has been clicked.     *     * @param v The view that was clicked.     */    @Override    public void onClick(View v) {        switch(v.getId()){    //            点击fab弹出上面两个FAB,通过FAB_STATE判断当前fab的打开状态            case R.id.fab:                //如果没有打开,则弹出                if(FAB_STATE==1){                    fab.setImageResource(R.mipmap.ic_clear_white_24dp);                    fabLocal.setVisibility(View.VISIBLE);                    fabFavorite.setVisibility(View.VISIBLE);                    FAB_STATE=0;                    break;                }                //已经在打开状态,则关闭                if(FAB_STATE==0){                    fab.setImageResource(R.mipmap.ic_add_white_24dp);                    fabLocal.setVisibility(View.GONE);                    fabFavorite.setVisibility(View.GONE);                    FAB_STATE=1;                    break;                }                break;            case R.id.fab_local:                //弹出SnackBar,仅仅显示文字消息的SnackBar                //注意第一个参数,需要一个合适的父视图                Snackbar.make(parentLayout,"你点击了FAB_LOCAL",Snackbar.LENGTH_LONG)                        .setAction("换个美女", new View.OnClickListener() {                            @Override                            public void onClick(View v) {                                //这里的单击事件代表点击消除按钮后的响应事件,比如换掉背景图片                                imageView.setImageResource(R.mipmap.bg_six);                            }                        })                        .show();                break;            case R.id.fab_favorite:                //设置字体颜色                Snackbar.make(parentLayout,"你点击了FAB_FAVORITE",Snackbar.LENGTH_LONG)                        .setAction("Undo", new View.OnClickListener() {                            @Override                            public void onClick(View v) {                                //                            }                        }).setActionTextColor(R.color.action_text_color)                        .show();                break;        }    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.menu_main,menu);        return super.onCreateOptionsMenu(menu);    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        return super.onOptionsItemSelected(item);    }}

总结:

简单介绍了官方在Design Support Library中引入的NavigationView FloatingActionBar SnackBar控件的的用法,各个控件的高级属性和用法还需大家自己去研究,在以后的使用中尽量多引入Material Design,多参考官方文档!

参考资料:

Android Design Support Library

Design Support Library (II): Floating Action Button

Defining Custom Animations

0 0