当前位置: 代码迷 >> Android >> android开发纪行:meterial design 5.0 新增控件介绍及使用方法
  详细解决方案

android开发纪行:meterial design 5.0 新增控件介绍及使用方法

热度:589   发布时间:2016-04-24 11:28:33.0
android开发游记:meterial design 5.0 新增控件介绍及使用方法

Android 5.0 Lollipop 是迄今为止最重大的一次发布,因为 material design 的存在,android的界面风格发生了新的改变,这是一门新的设计语言,它刷新了整个 Android 的用户体验。对于开发者来说,要设计出完全符合 material design 哲学的应用,是一个很大的挑战。
Android Design Support Library 对此提供了很好的支持,里面汇集了很多重要的 material design 控件,支持所有 Android 2.1 及后续版本。里面你可以看到 navigation drawer view、floating labels、floating action button、snackbar、tabs,以及一套将它们紧密结合在一起的动作与滚动框架。

这里分享一个官方demo
效果如下:

这里写图片描述 这里写图片描述 这里写图片描述

下载链接:
eclipse版本demo下载
androidstudio版本demo下载

下面解释一下相关代码和一些5.0的新增控件介绍一下

首先是侧滑导航栏,虽然在之前的版本中已经有侧滑栏了,但是在5.0后给出了使用更加便捷,并自带特效的NavigationView作为导航栏的标准。
使用方法:

首先在布局文件中使用DrawerLayout作为根布局:
在DrawerLayout 中添加NavigationView

<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">    <include layout="@layout/include_list_viewpager"/>    <android.support.design.widget.NavigationView        android:id="@+id/nav_view"        android:layout_height="match_parent"        android:layout_width="wrap_content"        android:layout_gravity="start"        android:fitsSystemWindows="true"        app:headerLayout="@layout/nav_header"        app:menu="@menu/drawer_view"/></android.support.v4.widget.DrawerLayout>

layout_gravity属性可以控制导航栏是从左边还是右边滑出
其中headerLayout属性需要给入一个作文导航头(header)的布局
menu属性需要给出一个菜单menu配置文件

在res/menu文件夹下添加: drawer_view.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">    <group android:checkableBehavior="single">        <item            android:id="@+id/nav_home"            android:icon="@drawable/ic_dashboard"            android:title="Home" />        <item            android:id="@+id/nav_messages"            android:icon="@drawable/ic_event"            android:title="Messages" />        <item            android:id="@+id/nav_friends"            android:icon="@drawable/ic_headset"            android:title="Friends" />        <item            android:id="@+id/nav_discussion"            android:icon="@drawable/ic_forum"            android:title="Discussion" />    </group>    <item android:title="Sub items">        <menu>            <item                android:icon="@drawable/ic_dashboard"                android:title="Sub item 1" />            <item                android:icon="@drawable/ic_forum"                android:title="Sub item 2" />        </menu>    </item></menu>

这样就完成了导航菜单的配置,运行就可以看到效果了。

如果菜单长度过长的话NavigationView是可以滚动的,而且默认带有滚动条。虽然NavigationView有去掉滚动条的方法但是尝试了各种方法发现并没有什么乱用,于是查看源码发现,并不是NavigationView的滚动产生的滚动条,而是NavigationView内封装了可滚动的View,这大概是一个bug。用下面的方式实测可以取消滚动条:

    NavigationView navi = (NavigationView) findViewById(R.id.navi);    navi.getChildAt(0).setVerticalScrollBarEnabled(false);

Toolbar

toolbar是一个用于去掉以前使用的actionbar的标准,他解决了actionbar无法自由控制的缺点,能根据自己的需求进行高度自定义,用法也很简单:

使用方法:

首先在布局中添加toolbar

    <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/ThemeOverlay.AppCompat.Light"            app:theme="@style/ThemeOverlay.AppCompat.ActionBar"            app:layout_scrollFlags="scroll|enterAlways" />

接下来在java代码中把它关联到activity中就ok了:

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);        toolbar.setTitle(getString(R.string.app_name));        setSupportActionBar(toolbar);

在activity中实现onCreateOptionsMenu方法也可以在toolbar的右边拓展一个下拉隐藏菜单:

    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }

在和联用的时候,通过添加ActionBarDrawerToggle 作为DrawerLayout的DrawerListener,左上角的菜单按钮会默认有一个变换动画:

    ActionBarDrawerToggle mActionBarDrawerToggle = new ActionBarDrawerToggle(this,      mDrawerLayout, toolbar, R.string.open, R.string.close);    mActionBarDrawerToggle.syncState();    mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);

TabLayout

tabLayout是一个和viewPager联用的指示页面的控件,这也是一个非常常用的功能,在以前的android版本中并没有给出官方的实现,所以就出现了许多三方的开源控件,如PagerSlidingTabStrip,现在有了官方的实现自然更好:

使用方法:

在布局中添加tablayout:

    <android.support.design.widget.TabLayout            android:id="@+id/tabs"            android:layout_width="match_parent"            android:layout_height="wrap_content" />

然后在java代码中关联相应的viewPager就行了:

        ViewPager pager = (ViewPager) findViewById(R.id.pager);        pager.setAdapter(pagerAdapter);        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);        tabLayout.setupWithViewPager(pager);

FloatingActionButton

继承于ImagButton,和button的用法几乎一样,可以通过app:layout_anchorGravity属性设置它浮动的位置,通过app:layout_anchor属性设置浮动在哪个View上面,就不详说了:

<android.support.design.widget.FloatingActionButton        android:layout_height="wrap_content"        android:layout_width="wrap_content"        app:layout_anchor="@id/appbar"        app:layout_anchorGravity="bottom|right|end"        android:src="@drawable/ic_discuss"        android:layout_margin="@dimen/fab_margin"        android:clickable="true"/>

Snackbar

用法类似于Toast,一种底部弹出式的新消息提醒机制,相比Toast可以设置点击事件,如何用户不点击,几秒之后也会消失。

使用方法:

    public void onClick(View view) {        Snackbar.make(view, "Here's a Snackbar", Snackbar.LENGTH_LONG)            .setAction("Action", null).show();    }

其中setAction中,第一个参数是按钮的文字,第二个参数可以给出一个点击监听器,来设置点击事件

CardView

CardView提供了一种类似于卡片(纸张?)风格的布局样式,可以自定义圆角度数和阴影面积等,很简单的一个控件使用非常方便,继承于FrameLayout,使用方法类似:

        <android.support.v7.widget.CardView                android:layout_width="match_parent"                android:layout_height="wrap_content"                card_view:cardElevation="5dp"                card_view:cardMaxElevation="10dp"                card_view:cardBackgroundColor="#FFFFFF"                card_view:cardCornerRadius="5dp"                card_view:contentPadding="20dp">        </android.support.v7.widget.CardView>

属性解释:
card_view:cardElevation 阴影的大小
card_view:cardMaxElevation 阴影最大高度
card_view:cardBackgroundColor 卡片的背景色
card_view:cardCornerRadius 卡片的圆角大小
card_view:contentPadding 卡片内容于边距的间隔

RecyclerView

RecyclerView是5.0新控件中权重最高的一个,也是目前讨论最多的一个,相比传统的listView,RecyclerView解决了许多用传统方式无法实现的效果,最直接的莫过于它把,列表,网格,瀑布流几种布局方式整合到一个控件里面,并由布局管理器来统一管理。同时也允许开发人员自定义布局管理器来实现自定义的布局方式,给开发人员提供了一种可高度自定义布局组件。

使用方法:

在布局中添加

    <android.support.v7.widget.RecyclerView            android:id="@+id/recyclerView"            android:layout_width="match_parent"            android:layout_height="match_parent"/>

在activity或fragment中设置布局管理器和适配器:

RecyclerView recyclerView = (RecyclerView) this.rootView.findViewById(R.id.recyclerView);//列表式布局recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext(),        LinearLayoutManager.VERTICAL, false));//网格式布局//recyclerView.setLayoutManager(new GridLayoutManager(recyclerView.getContext(), 2, //  GridLayoutManager.VERTICAL, false));//瀑布流式布局//recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, //  StaggeredGridLayoutManager.VERTICAL));//设置适配器List<Cheese> results = new ArrayList<Cheese>();adapter = new MyRecyclerViewAdapter(getActivity(), R.layout.item_main, results);recyclerView.setAdapter(adapter);

其中Cheese是一个实体对象,自行添加。通过setLayoutManager可以设置不同布局方式的布局管理器,这里给出了3种,修改布局方式只需要设置不同的布局管理器就可以了。

下面给出MyRecyclerViewAdapter的代码:

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder>{    private Context context;    private int srcId;    private List<Cheese> results;    //get & set    public List<Cheese> getResults() {        return results;    }    public MyRecyclerViewAdapter(Context context,int srcId,List<Cheese> results){        this.context = context;        this.results = results;        this.srcId = srcId;    }    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(parent.getContext()).inflate(srcId, parent, false);        return new MyViewHolder(view);    }    @Override    public void onBindViewHolder(MyViewHolder holder, int position) {        holder.img_header.setImageResource(R.drawable.cheese_1);        holder.text_title.setText(results.get(position).getTitle());    }    @Override    public int getItemCount() {        return results.size();    }    public class MyViewHolder extends RecyclerView.ViewHolder{        public ImageView img_header;        public TextView text_title;        public MyViewHolder(View itemView) {            super(itemView);            img_header = (ImageView) itemView.findViewById(R.id.img_header);            text_title = (TextView) itemView.findViewById(R.id.text_title);        }    }}

代码解释

由于RecycleView把Holder的结构进行了封装所有不再需要像使用ListView那样自行处理item的复用,这里内置了MyViewHolder 来保存item控件视图对象以用于复用。
MyRecyclerViewAdapter 继承于RecyclerView.Adapter主要实现onCreateViewHolder,onBindViewHolder,getItemCount三个方法。

getItemCount() 返回item数量,不需要再多说了

    @Override    public int getItemCount() {        return results.size();    }

onCreateViewHolder() 在创建item视图的时候调用,这里就要创建视图并且实例化Holder并返回 来保存视图对象

    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(parent.getContext()).inflate(srcId, parent, false);        return new MyViewHolder(view);    }

onBindViewHolder()在绑定数据的时候调用,会将之前创建的Holder对象传递给你,有开发者进行数据的绑定,而传入的Holder并不一定是上一步创建的,可能是回收再复用的Holder,这个过程对开发者是不可见的,也不需要关心Holder从哪来,你只需要为不同的Holder绑定对应的数据就可以了,这就是RecycleView相比ListView更加便捷的处理方式

    @Override    public void onBindViewHolder(MyViewHolder holder, int position) {        holder.img_header.setImageResource(R.drawable.cheese_1);        holder.text_title.setText(results.get(position).getTitle());    }

这样 一个基本的RecycleView就完成了,更改布局方式只需要使用不同的布局管理器就ok了,相当方便。

这只是RecycleView的一个基础的使用,RecycleView还有许多特性,比如分隔线,item动态增删和入场退场动画,粘滞item头,嵌套,复杂混用布局等等,留在以后再分篇写一下。

觉得有用的话,下面有个顶的按钮可以点一下。

  相关解决方案