android(一) 菜单创建
来源:互联网 发布:华为和三星的差距 知乎 编辑:程序博客网 时间:2024/06/05 00:38
android中当我们需要进行相应的页面跳转时,我们可以通过菜单的方式来对页面进行切换,如下是一个比较传统的menu布局:
<menu 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" tools:context="com.demo.mianhai.woyaodushu.MainActivity" > <item android:id="@+id/action_new" android:orderInCategory="1" android:title="SubMenu" android:icon="@drawable/ic_drawer_home" app:showAsAction="always"> <menu> <item android:id="@+id/submenu1" android:title="Accept" android:titleCondensed="Accept" android:icon="@drawable/ic_notifications" /> <item android:id="@+id/submenu2" android:title="Cancel" android:titleCondensed="Cancel" android:icon="@drawable/ic_notifications" /> <item android:id="@+id/submenu3" android:title="Unread" android:titleCondensed="Unread" android:icon="@drawable/ic_notifications" /> </menu> </item> <item android:id="@+id/action_overflow" android:orderInCategory="2" android:title="PopupWindow" android:icon="@drawable/ic_menu_more_overflow" app:showAsAction="always"/></menu>
由上我们可以获得一个差不多类似于微信悬浮窗的效果,如图(+号所显示的内容,图片来自网络)
以上看名字都可以理解的我就不解释了
- orderInCategory:通过设置数值的大小来决定优先级,值越大优先级就越低,这样当actionbar空间位置不够时就会被隐藏掉
showAsAction:可填的数值有ifRoom、never、always、withText、collapseActionView,可以混合使用。
ifRoom 会显示在Item中,但是如果已经有4个或者4个以上的Item时会隐藏在溢出列表中。当然个数并不仅仅局限于4个,依据屏幕的宽窄而定
never 永远不会显示。只会在溢出列表中显示,而且只显示标题,所以在定义item的时候,最好把标题都带上。
always 无论是否溢出,总会显示。
withText withText值示意Action bar要显示文本标题。Actionbar会尽可能的显示这个标题,但是,如果图标有效并且受到Action bar空间的限制,文本标题有可能显示不全。
collapseActionView 声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。否则,这个操作视窗在默认的情况下是可见的,并且即便在用于不适用的时候,也要占据操作栏的有效空间。
一般我们设置ifroom就行了,当然也可以混合显示,看需求决定,那么如上的视图我们要如何实现呢?这里列举了几种比较常规的方法,看情况决定哪一种。
通过PopupWindow来实现,代码如下:
package com.demo.mianhai.woyaodushu;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Rect;import android.graphics.drawable.BitmapDrawable;import android.os.Bundle;import android.support.design.widget.FloatingActionButton;import android.support.design.widget.Snackbar;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.Toolbar;import android.view.Gravity;import android.view.Menu;import android.view.MenuInflater;import android.view.MenuItem;import android.view.View;import android.widget.PopupWindow;public class Main3Activity extends AppCompatActivity { Toolbar toolbar = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu items for use in the action bar MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu3, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); switch (id) { case R.id.action_overflow: popUpMyOverflow();//弹出自定义overflow return true; } return super.onOptionsItemSelected(item); } public void popUpMyOverflow() { /** * 定位PopupWindow,让它恰好显示在Action Bar的下方。 通过设置Gravity,确定PopupWindow的大致位置。 * 首先获得状态栏的高度,再获取Action bar的高度,这两者相加设置y方向的offset样PopupWindow就显示在action * bar的下方了。 通过dp计算出px,就可以在不同密度屏幕统一X方向的offset.但是要注意不要让背景阴影大于所设置的offset, * 否则阴影的宽度为offset. */ // 获取状态栏高度 Rect frame = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);// 状态栏高度:frame.top,这里的R.layout.activity_tool_bar其实就是上图中的第二个菜单按钮显示出来的视图 int xOffset = frame.top+this.getSupportActionBar().getHeight()-25;//减去阴影宽度,适配UI. int yOffset = Dp2Px(this, 5f); //设置x方向offset为5dp View parentView = getLayoutInflater().inflate(R.layout.activity_main, null); View popView = getLayoutInflater().inflate( R.layout.activity_tool_bar, null); PopupWindow popWind = new PopupWindow(popView, Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.WRAP_CONTENT, true);//popView即popupWindow的布局,ture设置focusAble. //必须设置BackgroundDrawable后setOutsideTouchable(true)才会有效。这里在XML中定义背景,所以这里设置为null; popWind.setBackgroundDrawable(new BitmapDrawable(getResources(), (Bitmap) null)); popWind.setOutsideTouchable(true); //点击外部关闭。 popWind.setAnimationStyle(android.R.style.Animation_Dialog); //设置一个动画。 //设置Gravity,让它显示在右上角。 popWind.showAtLocation(parentView, Gravity.RIGHT | Gravity.TOP, yOffset, xOffset); } public int Dp2Px(Context context, float dp) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dp * scale + 0.5f); }}
你以为这样就完了?不,由于我的安卓版本是5.0的,所以相应的继承的类是AppCompatActivity,默认的actionbar是悬浮效果的,我们需要在value/style.xml中更改如下代码:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="actionOverflowMenuStyle">@style/LYJMenuStyle</item> </style> <style name="LYJMenuStyle" parent="@style/Widget.AppCompat.Light.PopupMenu.Overflow"> <!--关掉悬浮效果--> <item name="overlapAnchor">false</item> </style>
如果你这边需要做到像知乎一样的菜单的话,只需将overlapAnchor改为true,如下:
<style name="LYJMenuStyle" parent="@style/Widget.AppCompat.Light.PopupMenu.Overflow"> <!--关掉悬浮效果--> <item name="overlapAnchor">true</item> </style>
第二种方法,通过设置在menu.xml中的item中设置actionProviderClass属性,来创建子菜单。菜单如下:
<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.demo.mianhai.woyaodushu.MainActivity" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/search_menu" android:icon="@mipmap/ic_search" android:title="@string/search_menu" app:actionProviderClass="com.demo.mianhai.woyaodushu.actionprovide.MenuProvide" app:showAsAction="always" /> <item android:id="@+id/notify_menu" android:icon="@mipmap/ic_notifications" android:title="@string/notify_menu" app:showAsAction="ifRoom" /> <item android:id="@+id/setting" android:icon="@mipmap/ic_menu_more_overflow" android:title="设置" app:showAsAction="never" /> <item android:id="@+id/about" android:icon="@mipmap/ic_menu_more_overflow" android:title="关于" app:showAsAction="never" /></menu>
MenuProvide类的实现如下:
public class MenuProvide extends ActionProvider { /** * Creates a new instance. * * @param context Context for accessing resources. */ public MenuProvide(Context context) { super(context); } @Override public View onCreateActionView() { return null; } @Override public void onPrepareSubMenu(SubMenu subMenu) { subMenu.clear(); subMenu.add("sub item 1").setIcon(R.mipmap.ic_notifications) .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return true; } }); subMenu.add("sub item 2").setIcon(R.mipmap.ic_search) .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return false; } }); } @Override public boolean hasSubMenu() { return true; }}
以上的类可以清晰的看出我们对submenu进行了重写赋值,为其添加了子菜单,这里我们同样可以获取类似于以下的效果
,
一般我们用ActionProvider往往还要讲到他的儿子ShareActionProvider,但这里就不做特别的详解了,直接贴相关的代码,步骤如下:
1 在rest下创建Asset这个文件夹,放入你想放的图片
2. 在menu中进行配置文件,如下:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_search" android:icon="@drawable/ic_search" android:title="@string/action_search" app:showAsAction="ifRoom" app:actionViewClass="android.support.v7.widget.SearchView"/> <item android:id="@+id/action_share" android:icon="@drawable/ic_share" android:title="@string/action_share" app:actionProviderClass="android.support.v7.widget.ShareActionProvider" app:showAsAction="ifRoom"/></menu>
在Activity中添加如下代码:
@Overridepublic boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu items for use in the action bar MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); MenuItem shareItem = menu.findItem(R.id.action_share); ShareActionProvider shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem); shareActionProvider.setShareIntent(getDefaultIntent()); return super.onCreateOptionsMenu(menu);}private Intent getDefaultIntent() { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("image/*"); return intent;}
一般可以获得如下的效果图:
使用material design 来设计toolbar
相比与android自带的toolbar,我们更倾向于使用material design的设计风格,那么我们首先需要将我们需要的包给导进来,在app/build.gradle 下添加如下代码
compile 'com.android.support:design:23.2.1'
由于我用的sdk是23的,所以这里的版本你要根据实际情况来写。
接下来我们可以新建一个layout,用于放我们的toolbar,如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:toolbar="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimaryDark" android:theme="@style/Theme.ToolBar.ZhiHu"> </android.support.v7.widget.Toolbar></LinearLayout>
由于我们的布局存在了toolbar了,所以我们需要将默认的toolbar给关掉,在AndroidManifest.xml下对theme主题进行更改,如下:
android:theme="@style/Theme.ToolBar.Base"
res/value/style.xml 加入如下代码:
<style name="Theme.ToolBar.Base" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:textColorPrimary">@color/colorPrimaryDark</item> <item name="actionOverflowButtonStyle">@style/ActionButton.Overflow.ZhiHu</item> </style> <!--设置隐藏菜单的颜色--> <style name="ActionButton.Overflow.ZhiHu" parent="android:style/Widget.Holo.Light.ActionButton.Overflow"> <item name="android:src">@drawable/ic_menu_more_overflow</item> </style>
上面如果不加@style/ActionButton.Overflow.ZhiHu显示出来的效果图是这样的:
接下来在我们的主类下添加如下代码:
public class MainActivity extends AppCompatActivity { Toolbar toolbar = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_tool_bar); initToolBar(); } private void initToolBar(){ toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setNavigationIcon(R.mipmap.ic_drawer_home);//设置导航栏图标 //toolbar.setLogo(R.mipmap.ic_launcher);//设置app logo //toolbar.setTitle("Title");//设置主标题 //toolbar.setSubtitle("Subtitle");//设置子标题 toolbar.inflateMenu(R.menu.zhihu_menu);//设置右上角的填充菜单 toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { int menuItemId = item.getItemId(); if (menuItemId == R.id.setting) { Toast.makeText(MainActivity.this , R.string.item_01 , Toast.LENGTH_SHORT).show(); } else if (menuItemId == R.id.about) { Toast.makeText(MainActivity.this , R.string.item_02 , Toast.LENGTH_SHORT).show(); } return true; } }); }}
menu菜单布局
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.demo.mianhai.woyaodushu.MainActivity" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/search_menu" android:icon="@drawable/ic_search" android:title="@string/search_menu" app:showAsAction="always" /> <item android:id="@+id/notify_menu" android:icon="@drawable/ic_notifications" android:title="@string/notify_menu" app:showAsAction="ifRoom" /> <item android:id="@+id/setting" android:icon="@drawable/ic_menu_more_overflow" android:title="设置" app:showAsAction="never" /> <item android:id="@+id/about" android:icon="@drawable/ic_menu_more_overflow" android:title="关于" app:showAsAction="never" /></menu>
这就不添图了,这边我们只需要如何使用material design的toolbar就行了,下面我们再来讲解一下toolbar + drawerlayer 实现抽屉布局效果,这种效果一般对功能点比较多的可以考虑使用,如下就是一个我们比较常见的抽屉效果图:
android为我们提供了一个简单的drawerlayout布局然我们可以轻松实现这个效果,如下是实现代码:
package com.demo.mianhai.hbook;import android.os.Bundle;import android.support.v4.widget.DrawerLayout;import android.support.v7.app.ActionBarDrawerToggle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.Toolbar;public class DrawerActivity extends AppCompatActivity { Toolbar toolbar = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drawer); initToolBar(); } private void initToolBar(){ toolbar = (Toolbar) findViewById(R.id.toolBar); //toolbar.setNavigationIcon(R.drawable.ic_drawer_home);//设置导航栏图标 //toolbar.setLogo(R.mipmap.ic_launcher);//设置app logo //toolbar.setTitle("Title");//设置主标题 //toolbar.setSubtitle("Subtitle");//设置子标题 DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer); toolbar.setTitleTextColor(getResources().getColor(android.R.color.white)); setSupportActionBar(toolbar); ActionBarDrawerToggle actionBarDrawerToggle=new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.open_string,R.string.close_string); actionBarDrawerToggle.syncState(); drawerLayout.addDrawerListener(actionBarDrawerToggle); }}
layout.xml代码如下:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.demo.mianhai.hbook.DrawerActivity"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/toolBar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" android:minHeight="?attr/actionBarSize" > </android.support.v7.widget.Toolbar> <FrameLayout android:id="@+id/contentFL" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_below="@+id/toolBar" > </FrameLayout> </RelativeLayout> <LinearLayout android:id="@+id/menuLL" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="start" android:clickable="true" android:background="@android:color/white" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="sss" /> </LinearLayout></android.support.v4.widget.DrawerLayout>
需要注意的是,这边我们需要用到material design里面的toolbar来实现,如果是用系统默认的话,那么布局会往下跑,这个下面会讲,运行完就可以出现上面类似于上面的布局效果了。
如果我们要实现的效果是把布局放到toolbar下面呢,如图所示:
这边我们需要对我们的布局xml做一些微调,让他用的是我们的系统自带的那个,布局xml如下:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.demo.mianhai.hbook.DrawerActivity"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/contentFL" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_below="@+id/toolBar" > </FrameLayout> </RelativeLayout> <LinearLayout android:id="@+id/menuLL" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="start" android:clickable="true" android:background="@android:color/white" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="sss" /> </LinearLayout></android.support.v4.widget.DrawerLayout>
代码:
package com.demo.mianhai.hbook;import android.os.Bundle;import android.support.v4.view.GravityCompat;import android.support.v4.widget.DrawerLayout;import android.support.v7.app.ActionBarDrawerToggle;import android.support.v7.app.AppCompatActivity;import android.view.MenuItem;public class Drawer2Activity extends AppCompatActivity { private DrawerLayout drawerLayout = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drawer2); drawerLayout= (DrawerLayout) findViewById(R.id.drawer); getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); ActionBarDrawerToggle actionBarDrawerToggle=new ActionBarDrawerToggle(this,drawerLayout,R.string.open_string,R.string.close_string); actionBarDrawerToggle.syncState(); drawerLayout.addDrawerListener(actionBarDrawerToggle); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == android.R.id.home) { if( drawerLayout.isDrawerOpen(GravityCompat.START) ){ drawerLayout.closeDrawers(); }else{ drawerLayout.openDrawer(GravityCompat.START); } return true; } return super.onOptionsItemSelected(item); }}
androidmanifest.xml
<activity android:name=".activity.DrawerLayout2Activity" android:theme="@style/AppTheme" android:label="@string/title_activity_drawer_layout2" > </activity>
好了上面的简单效果图也出来了
未完待续
参考文献:
http://www.jianshu.com/p/d70e2fd4d0be
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1120/2021.html
https://developer.android.google.cn/guide/index.html
http://m.blog.csdn.net/Guofengpu/article/details/51965925
http://www.jianshu.com/p/ae0013a4f71a
http://www.jianshu.com/p/0acc12c29c1b
http://www.jianshu.com/p/79604c3ddcae
http://www.jianshu.com/p/3fe2acac0ddb
- android(一) 菜单创建
- android创建上下文菜单(即长按菜单)
- Android 创建菜单(menu)的总结
- Android 中右上角菜单创建(Menu)
- Android 创建菜单。
- android 创建菜单
- Android 创建菜单
- Android用户界面-创建菜单
- Android 创建菜单Menu
- Android创建菜单Menu
- Android创建菜单
- android 菜单的创建
- Android菜单(一)----关于菜单
- 第六课 菜单操作 一 菜单创建
- Android 用户界面---菜单(Menus 一)
- Android 用户界面---菜单(Menus 一)
- Android 用户界面---菜单(Menus 一)
- 漫谈android开发之菜单(一)
- 【JSP笔记】指令标签(3)、动作标签(6)
- 星级酒店案例
- 折叠式标题栏的使用——复习笔记
- springmvc与struts2的不同点
- 三周三次课(11月1日)
- android(一) 菜单创建
- [poj] 1797
- 每日一练
- mysql默认事务隔离级别-事务并发实战
- C++ 引用
- Leetcode 股票交易
- javaScript去除数组中相同元素
- oracle下载安装
- Java 基础巩固:再谈抽象类和接口