特别说明
当前博客平台账号已废弃,如果有使用细节问题请前往我新博客平台进行讨论交流。
个人博客平台 HuRuWo的技术小站
文章首发于个人博客HuRuWo的技术小站,如果本文非vip用户无法完全浏览或者图片无法打开,可前往个人博客文章地址查看文章并留言讨论。
个人博客文章地址(收集转载总结)MD设计常用代码/尺寸/颜色/控件个人收集总结--控件部分
更多技术文章访问本人博客HuRuWo的技术小站,包括 Electron从零开发 Android 逆向 app 微信数据抓取 抖音数据抓取 闲鱼数据抓取 小红书数据抓取 其他软件爬虫 等技术文章
前言
作为Android 开发者,不仅要学习功能的实现,还需要定制用户的界面。如何制作一款符合大家审美的app是个根令人头疼的问题。
不过好在google在15发布了MD设计规范,帮助程序员设计更好的app。
MD概述
说明:本文参考资料极客学院 Material Design 中文版
翻译不是很可靠,也不及时。最好还是去谷歌查看原文。
我们挑战自我,为用户创造了崭新的视觉设计语言。与此同时,新的设计语言除了遵循经典设计定则,还汲取了最新的科技,秉承了创新的设计理念。这就是原质化设计(Material Design)
。这份文档是动态更新的,将会随着我们对 Material Design 的探索而不断迭代、升级。
目标
我们希冀创造一种新的视觉设计语言,能够遵循优秀设计的经典定则,同时还伴有创新理念和新的科技。
我们希望创造一种独一无二的底层系统,在这个系统的基础之上,构建跨平台和超越设备尺寸的统一体验。遵循基本的移动设计定则,同时支持触摸、语音、鼠标、键盘等输入方式。
设计原则
实体感就是(通过设计方式来表达)隐喻
通过构建系统化的动效和空间合理化利用,并将两个理念合二为一,构成了实体隐喻。与众不同的触感是实体的基础,这一灵感来自我们对纸墨的研究,但是我们相信,随着科技的进步,应用前景将不可估量。
实体的表面和边缘提供基于真实效果的视觉体验,熟悉的触感让用户可以快速地理解和认知。实体的多样性可以让我们呈现出更多反映真实世界的设计效果,但同时又绝不会脱离客观的物理规律。
光效、表面质感、运动感这三点是解释物体运动规律、交互方式、空间关系的关键。真实的光效可以解释物体之间的交合关系、空间关系,以及单个物体的运动。
鲜明、形象、深思熟虑
新的视觉语言,在基本元素的处理上,借鉴了传统的印刷设计——排版、网格、空间、比例、配色、图像使用——这些基础的平面设计规范。在这些设计基础上下功夫,不但可以愉悦用户,而且能够构建出视觉层级、视觉意义以及视觉聚焦。精心选择色彩、图像、选择合乎比例的字体、留白,力求构建出鲜明、形象的用户界面,让用户沉浸其中。
Material Design 设计语言强调根据用户行为凸显核心功能,进而为用户提供操作指引。
有意义的动画效果
动画效果(简称动效)可以有效地暗示、指引用户。动效的设计要根据用户行为而定,能够改变整体设计的触感。
动效应当在独立的场景呈现。通过动效,让物体的变化以更连续、更平滑的方式呈现给用户,让用户能够充分知晓所发生的变化。
动效应该是有意义的、合理的,动效的目的是为了吸引用户的注意力,以及维持整个系统的连续性体验。动效反馈需细腻、清爽。转场动效需高效、明晰。
所有的关于MD设计的有关规范都能在该文档里找到,下面我们跟随文档,看下一些符合MD设计的应用是如何做到简约大方的。
热门开源MD风格设计App
- 简影讯,简约精彩影讯。仓库地址
[图片上传失败...(image-47eebc-1606128193422)] - 就看天气——是一款遵循Material Design风格的只看天气的APP。仓库地址
[图片上传失败...(image-5cb39c-1606128193422)]
MD相关控件
参考文章:Android MD风格相关控件小结
CoordinatorLayout
CoordinatorLayout作为顶层布局,可以响应子布局的动作,调度协调子布局,形成优雅的动画效果。作为搭配主要有以下几种
CoordinatorLayout+AppBarLayout
CoordinatorLayout配合AppBarLayout 可以形成优雅的顶部导航条。配合ToolBar以及能让响应滑动事件的控件,可以形成根据滑动变化的顶部导航条。
能响应的滑动事件控件有:
- RecyclerView 控件
- NestedScrollView 里面的子控件
实例:一个常用的布局方式
CoordinatorLayout+AppBarLayout+ToolBar+TabLayout+ViewPager+RecyclerView
- CoordinatorLayout+AppBarLayout+ToolBar 制作响应的顶部导航
- TabLayout+ViewPager+RecyclerView 形成带Tab的ViewPager
布局文件:
主布局:
<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_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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"
<!---------------------------------隐藏toolbar----------------------------------->
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="MdView" />
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
<!---------------------------------ViewPage的滚动----------------------------------->
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="@android:drawable/ic_menu_share" />
</android.support.design.widget.CoordinatorLayout>
fragment布局
<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="com.othershe.mdview.TypeFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/type_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
配合CoordinatorLayout、AppBarLayout,我们实现了这样的效果,向上滚动列表时,Toolbar隐藏,TabLayout置顶,再向下滚动Toolbar则显示。
Toolbar之所以可以滚动隐藏\显示,是通过如下属性实现的:
app:layout_scrollFlags="scroll|enterAlways"
相关属性值解释如下:
scroll:需要滚动出屏幕的view需要设置该flag, 没有设置则view将被固定在屏幕顶部。
enterAlways: 使用该flag,则向下的滚动会使view变为可见状态。
更多详情可参考文章玩转AppBarLayout,更酷炫的顶部栏
为Toolbar设置layout_scrollFlags属相只是第一步,还需要在CoordinatorLayout 中提供一个可滚动的View,我们使用ViewPager,并在里边嵌套RecyclerView。同时需要为ViewPager设置如下属性:app:layout_behavior="@string/appbar_scrolling_view_behavior"
其他有关代码:
private void initContent() {
mFragments = new ArrayList<>();
mFragments.add(TypeFragment.newInstance("热点"));
mFragments.add(TypeFragment.newInstance("军事"));
mFragments.add(TypeFragment.newInstance("科技"));
mFragments.add(TypeFragment.newInstance("娱乐"));
mTitles = new ArrayList<>();
mTitles.add("热点");
mTitles.add("军事");
mTitles.add("科技");
mTitles.add("娱乐");
TabPagerAdapter adapter = new TabPagerAdapter(getSupportFragmentManager());
adapter.setArguments(mFragments, mTitles);
mViewPager.setAdapter(adapter);
//设置TabLayout可滚动,保证Tab数量过多时也可正常显示
mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
//两个参数分别对应Tab未选中的文字颜色和选中的文字颜色
mTabLayout.setTabTextColors(Color.WHITE, Color.RED);
//绑定ViewPager
mTabLayout.setupWithViewPager(mViewPager);
//设置TabLayout的布局方式(GRAVITY_FILL、GRAVITY_CENTER)
mTabLayout.setTabMode(TabLayout.MODE_FIXED);
mTabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
//设置TabLayout的选择监听
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
//重复点击时回调
@Override
public void onTabReselected(TabLayout.Tab tab) {
scrollToTop(mFragments.get(tab.getPosition()).getTypeList());
}
});
}
/**
* 滚动到列表顶部
*
* @param recyclerView
*/
private void scrollToTop(RecyclerView recyclerView) {
StaggeredGridLayoutManager manager = (StaggeredGridLayoutManager) recyclerView.getLayoutManager();
int[] lastPositions = manager.findLastVisibleItemPositions(null);
if (lastPositions[0] < 15) {
recyclerView.smoothScrollToPosition(0);
} else {
recyclerView.scrollToPosition(0);
}
}
public class TabPagerAdapter extends FragmentPagerAdapter {
private List<TypeFragment> fragments;
private List<String> titles;
public TabPagerAdapter(FragmentManager fm) {
super(fm);
}
public void setArguments(List<TypeFragment> fragments, List<String> titles) {
this.fragments = fragments;
this.titles = titles;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
//返回TabLayout对应Tab的标题
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
RecyclerView的Adapter
public class TypeListAdapter extends RecyclerView.Adapter<TypeListAdapter.ViewHolder> {
private ArrayList<String> mDatas;
private List<Integer> mHeights;
private OnItemClickListener mListner;
public TypeListAdapter(ArrayList<String> datas) {
if (datas != null) {
mDatas = datas;
} else {
mDatas = new ArrayList<>();
}
mHeights = new ArrayList<>();
for (int i = 0; i < mDatas.size(); i++) {
mHeights.add((int) (260 + Math.random() * 100));
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_type_layout, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
ViewGroup.LayoutParams params = holder.itemTv.getLayoutParams();
params.height = mHeights.get(position);
holder.itemTv.setLayoutParams(params);
holder.itemTv.setText(mDatas.get(position));
if (mListner != null) {
holder.itemLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mListner.onItemClick(mDatas.get(position), position);
}
});
}
}
@Override
public int getItemCount() {
return mDatas.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.item_tv)
TextView itemTv;
@BindView(R.id.item_layout)
View itemLayout;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListner = listener;
}
public interface OnItemClickListener {
void onItemClick(String data, int position);
}
}
效果:CoordinatorLayout + AppBarLayout + CollapsingToolbarLayout
关于CollapsingToolbarLayout的说明
CollapsingToolbarLayout作用是提供了一个可以折叠的Toolbar,它继承至FrameLayout,给它设置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端)。
所以我们尝试加一个ImageView在里面试试,同时添加
app:layout_scrollFlags="scroll|exitUntilCollapsed"
再加一个响应滑动的控件,除了RecyclerView还有一个NestedScrollView控件同理加上app:layout_behavior="@string/appbar_scrolling_view_behavior"
布局文件:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/detail_content"
tools:context="com.othershe.mdview.DetailActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="200dp"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
<!---------------------------折叠-------------------------->
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/detail_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="fitXY"
<!---------------------------折叠-------------------------->
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
<!---------------------------折叠-------------------------->
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:src="@android:drawable/ic_menu_share"
app:layout_anchor="@id/app_bar"
app:layout_anchorGravity="bottom|end" />
</android.support.design.widget.CoordinatorLayout>
可以看到:
CollapsingToolbarLayout添加了两个子控件,由于CollapsingToolbarLayout本质是一个Fragmentlayout,所以层叠显示。同时设置ToolBar背景透明。
关于返回箭头:
//使mToolbar取代原来的ActionBar
setSupportActionBar(mToolbar);
//设置mToolbar左上角显示返回图标
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
//设置返回图标的点击事件
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
其他代码
//设置还没收缩时状态下字体颜色
mToolbarLayout.setExpandedTitleColor(Color.RED);
//设置收缩后Toolbar上字体的颜色
mToolbarLayout.setCollapsedTitleTextColor(Color.WHITE);
//设置image背景
mDetailImg.setBackgroundResource(R.mipmap.bg);
mWebView.loadUrl("//www.greatytc.com/");
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
//必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上则不会显示
mToolbarLayout.setTitle(title);
}
});
结合CollapsingToolbarLayout,我们向上滑动时ImageView隐藏、Toolbar显示,向下滑动则反之,类似折叠展开的效果。
在CollapsingToolbarLayout中通过app:contentScrim="?attr/colorPrimary"
属相设置Toolbar折叠到顶部的背景,同时设置了app:layout_scrollFlags="scroll|exitUntilCollapsed"
属相,其中scroll的=含义已经解释过了,exitUntilCollapsed的含义如下:
exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端
同时AppBarLayout的高度需要时第一个固定值,这样CollapsingToolbarLayout就有了折叠的效果。
折叠后Toolbar可以固定在顶部是因为使用了app:layout_collapseMode="pin"
属性,属性值除了pin还有一个parallax:
pin:固定模式,在折叠的时候最后固定在顶端
parallax:视差模式,在折叠时会有个视差折叠的效果
同时在ImageView中使用了app:layout_collapseMode="parallax"
属性,来产生视差渐变的效果,使用app:layout_collapseParallaxMultiplier="0.7"
可以控制视差的变化,属性值的范围是[0.0, 1.0],值越大视察越大。
最后还需要在NestedScrollView中设置app:layout_behavior="@string/appbar_scrolling_view_behavior
属性。
CoordinatorLayout+FloatingActionButton
这个很简单,只要加入了FloatingActionButton即可响应
<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_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
........................................
<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="@android:drawable/ic_menu_share" />
</android.support.design.widget.CoordinatorLayout>
代码
mFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(mCoordinatorLayout, "点我分享哦!", Snackbar.LENGTH_SHORT).show();
}
});
在Snackbar展示的时候FloatingActionButton上移,隐藏时下移。如果FloatingActionButton的父View是RelativeLayout或其它Container则FloatingActionButton不会上移而导致被Snackbar覆盖。
要做到我们上滑时FloatingActionButton会折叠消失,其实只需要如下两个属性就可以
app:layout_anchor="@id/app_bar"
app:layout_anchorGravity="bottom|end"
第一个属性使FloatingActionButton显示在AppBarLayout的区域,
第二个属性确定显示的具体位置。
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/detail_content"
tools:context="com.othershe.mdview.DetailActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="200dp"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
.............................
</android.support.design.widget.AppBarLayout>
.........................
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:src="@android:drawable/ic_menu_share"
<!--------------------------在app_bar中------------------->
app:layout_anchor="@id/app_bar"
app:layout_anchorGravity="bottom|end" />
</android.support.design.widget.CoordinatorLayout>
用来替换yuanlaide
Toolbar
ToolBar的出现是为了替换之前的ActionBar的各种不灵活使用方式,相反,ToolBar的使用变得非常灵活,因为它可以让我们自由往里面添加子控件。我们可以单独的使用也可以代替原来的ActionBar。
替换ActionBar
- 使用Toolbar首先要隐藏原有的ActionBar,我们可以增加一个主题
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
也可以扩展原有的主题,
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
colorPrimary:对应ActionBar的颜色。
colorPrimaryDark:对应状态栏的颜色
colorAccent:对应EditText编辑时、FloatingActionButton背景等颜色。
配置文件修改:Android:theme=”@style/AppTheme”
- 在布局文件中的用法可以参考上边的代码,之后在java代码中得到Toolbar,通过
setSupportActionBar(mToolbar);
使Toolbar取代原本的ActionBar。
相关属性
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary">
<!--添加Toolbar的子控件-->
<Button
android:id="@+id/btn_diy"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="#80ffffff"
android:text="自定义按钮"
android:textColor="#000000"
android:textSize="11sp" />
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="首页"
android:textColor="@android:color/black"
android:textSize="20sp" />
</android.support.v7.widget.Toolbar>
?attr/actionBarSize
:表示根据屏幕的分辨率采用系统默认的高度
关于图标以及其他设置:参考图片对应方法
mToolbar = (Toolbar) findViewById(R.id.toolbar);
// App Logo
// mToolbar.setLogo(R.drawable.app_icon);
// 主标题,默认为app_label的名字
mToolbar.setTitle("Title");
mToolbar.setTitleTextColor(Color.YELLOW);
// 副标题
mToolbar.setSubtitle("Sub title");
mToolbar.setSubtitleTextColor(Color.parseColor("#80ff0000"));
//侧边栏的按钮
mToolbar.setNavigationIcon(R.drawable.back);
//取代原本的actionbar
setSupportActionBar(mToolbar);
//设置NavigationIcon的点击事件,需要放在setSupportActionBar之后设置才会生效,
//因为setSupportActionBar里面也会setNavigationOnClickListener
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mToast.setText("click NavigationIcon");
mToast.show();
}
});
//设置toolBar上的MenuItem点击事件
mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_edit:
mToast.setText("click edit");
break;
case R.id.action_share:
mToast.setText("click share");
break;
case R.id.action_overflow:
//弹出自定义overflow
popUpMyOverflow();
return true;
}
mToast.show();
return true;
}
});
//ToolBar里面还可以包含子控件
mToolbar.findViewById(R.id.btn_diy).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mToast.setText("点击自定义按钮");
mToast.show();
}
});
mToolbar.findViewById(R.id.tv_title).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mToast.setText("点击自定义标题");
mToast.show();
}
});
设置menu,以及item点击事件
//如果有Menu,创建完后,系统会自动添加到ToolBar上
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.menu_share:
break;
case R.id.menu_search:
break;
}
return super.onOptionsItemSelected(item);
}
NavigationView
NavigationView的就是抽屉,是隐藏在界面外的一个布局。
在MD设计规范里,主要的东西应该是显眼的,用户直达的。所以NavigationView只能放一些次要的东西。比如说明、设置等等
布局文件
其实NavigationView就是用来实现我们常见的侧滑菜单的效果的。
在布局文件中的代码:
<?xml version="1.0" encoding="utf-8"?>
<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_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include
layout="@layout/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="@menu/menu_drawer"
app:headerLayout="@layout/nav_head_main" />
</android.support.v4.widget.DrawerLayout>
以DrawerLayout作为根布局,content_main作为主界面布局,最后是NavigationView,
通过android:layout_gravity="start"
设置为左侧滑菜单,
同理android:layout_gravity="end"
代表右侧滑菜单。
其中
app:menu="@menu/menu_drawer"
app:headerLayout="@layout/nav_head_main"
两个属性分别代表NavigationView的顶部header布局以及下边的menu item布局,具体可以参考源代码。
nav_head_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="#309393"
android:gravity="center_vertical"
android:orientation="horizontal"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/nav_head_icon"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="20dp"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/nav_head_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:textSize="18sp" />
</LinearLayout>
menu_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_item1"
android:icon="@android:drawable/ic_menu_compass"
android:title="我的圈子" />
<item
android:id="@+id/nav_item2"
android:icon="@android:drawable/ic_menu_add"
android:title="我的收藏" />
</group>
<item android:title="其它">
<menu>
<item
android:id="@+id/nav_set"
android:icon="@android:drawable/ic_menu_crop"
android:title="设置" />
<item
android:id="@+id/menu_share"
android:icon="@android:drawable/ic_menu_share"
android:title="分享" />
<item
android:id="@+id/nav_about"
android:icon="@android:drawable/ic_menu_help"
android:title="关于" />
</menu>
</item>
</menu>
代码
准备好了布局文件,接下来就是初始化工作:
private void initNavigationView() {
//初始化NavigationView顶部head的icon和name
ImageView icon = (ImageView) mNavView.getHeaderView(0).findViewById(R.id.nav_head_icon);
icon.setImageResource(R.mipmap.ic_launcher);
TextView name = (TextView) mNavView.getHeaderView(0).findViewById(R.id.nav_head_name);
name.setText("VipOthershe");
//设置NavigationView对应menu item的点击事情
mNavView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_item1:
break;
case R.id.nav_item2:
break;
case R.id.nav_set:
break;
case R.id.menu_share:
break;
case R.id.nav_about:
break;
}
//隐藏NavigationView
mDrawerLayout.closeDrawer(GravityCompat.START);
return true;
}
});
}
很简单,就是初始化NavigationView的顶部header和Menu Item。
接下来看一下如何将右滑菜单和Toolbar结合使用:
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, mDrawerLayout, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
mDrawerLayout.addDrawerListener(toggle);
//设置左上角显示三道横线
toggle.syncState();
通过设置将两者绑定在一起,同时Toolbar左上角显示三道横线,左上角可打开左滑菜单。
还可以采用另外一种方式:
//设置Toolbar左上角图标
mToolbar.setNavigationIcon(R.mipmap.ic_launcher);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mDrawerLayout.openDrawer(GravityCompat.START);
}
});
先设置Toolbar左上角图标,并绑定事件,通过mDrawerLayout.openDrawer(GravityCompat.START);
打开左滑菜单。
以上两个方法,分别对应打开和关闭左滑菜单:
mDrawerLayout.openDrawer(GravityCompat.START);
mDrawerLayout.closeDrawer(GravityCompat.START);
如果使用右滑菜单则将GravityCompat.START改成GravityCompat.END,即可实现右滑菜单的开关。
效果图