
一、OptionMenu的使用
1、代码生成menu(重写activity的onCreateOptionMenu()方法)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
u = menu;
int groupId = 1;
MenuItem item1 = menu.add(groupId, Menu.FIRST + 1, 1, "将第二组item不可见");
item1.setIcon(R.mipmap.ic_launcher);
menu.add(groupId, Menu.FIRST + 2, 2, "将第二组item可见");
menu.add(groupId, Menu.FIRST + 3, 3, "将第二组item不可用");
MenuItem item4 = menu.add(groupId, Menu.FIRST + 4, 4, "将第二组item可用");
item4.setIcon(R.mipmap.ic_launcher);
menu.add(groupId, Menu.FIRST + 5, 5, "将第二组item可单选");
menu.add(groupId, Menu.FIRST + 6, 6, "将第二组item可多选");
groupId = 2;
MenuItem item7 = menu.add(groupId, Menu.FIRST + 7, 7, "menu2_1");
item7.setIcon(R.mipmap.ic_launcher);
MenuItem item8 = menu.add(groupId, Menu.FIRST + 8, 8, "menu2_2");
item8.setIcon(R.mipmap.ic_launcher);
SubMenu subMenu = menu.addSubMenu(groupId, Menu.FIRST + 9, 9, "sub menu");
subMenu.add(groupId, Menu.FIRST + 10, 1, "sub1");
subMenu.add(groupId, Menu.FIRST + 11, 2, "sub2");
/**
* 这个监听事件可以对item的点击事件进行拦截,拦截后的item在onOptionsItemSelected()中不会得到执行
*/
item1.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return true;//返回true为拦截,false不拦截
}
});
return true;
} 使用menu.add(int groupId, int itemId, int order, charsequence title);
groupId: 可以对MenuItem进行分组,以便可以再代码中对某一组MenuItem进行操作,如menu.setGroupXXX();
itemId: MenuItem的id,可以使用ItemId(int id)获取到,便于对MenuItem的点击事件处理
order: 根据这个对menuItem的排序,越小排在越前面,如果某两个item的order相同,则按照代码添加顺序排列
title: 该menuitem的内容
/
menu.addSubMenu(int groupId, int itemId, int order, charsequence title);//使用同上
menuitem.setOnMenuItemClickListener()//可以直接在这里设置menuitem的点击事件,可以对onOptionsItemSeleted()进行拦截
onCreateOptionMenu()return true表示展示菜单,return false表示隐藏菜单
2、添加menuitem的点击事件,在activity的onOptionsItemSeleted(MenuItem menuitem)中进行设置
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = ItemId();
switch (id) {
case Menu.FIRST + 1:
menu.setGroupVisible(2, false);
break;
case Menu.FIRST + 2:
menu.setGroupVisible(2, true);
break;
case Menu.FIRST + 3:
menu.setGroupEnabled(2, false);
break;
case Menu.FIRST + 4:
menu.setGroupEnabled(2, true);
break;
case Menu.FIRST + 5:
menu.setGroupCheckable(2, true, true);
break;
case Menu.FIRST + 6:
menu.setGroupCheckable(2, true, false);
break;
case Menu.FIRST + 7:
Toast.makeText(this, "menu2_1", Toast.LENGTH_SHORT).show();
break;
case Menu.FIRST + 8:
Toast.makeText(this, "menu2_2", Toast.LENGTH_SHORT).show();
break;
case Menu.FIRST + 10:
Toast.makeText(this, "sub1", Toast.LENGTH_SHORT).show();
break;
case Menu.FIRST + 11:
Toast.makeText(this, "sub2", Toast.LENGTH_SHORT).show();
break;
}
3、xml生成menu
在res目录下新建menu目录,在这下面创建menu资源文件如l
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android=""
xmlns:app="">
<group android:id="@+id/group1" android:checkableBehavior="all">
<item android:id="@+id/group1_item1" android:icon="@mipmap/ic_launcher" android:title="item1" app:showAsAction="always"></item>
<item android:id="@+id/group1_item2" android:icon="@mipmap/ic_launcher" android:title="item2" app:showAsAction="always"></item>
<item android:id="@+id/group1_item3" android:icon="@mipmap/ic_launcher" android:title="item3" app:showAsAction="always"></item>
<item android:id="@+id/group1_item4" android:icon="@mipmap/ic_launcher" android:title="item4" app:showAsAction="always"></item>
<item android:id="@+id/group1_item5" android:icon="@mipmap/ic_launcher" android:title="item5" app:showAsAction="always"></item>
<item android:id="@+id/group1_item6" android:title="点我" app:showAsAction="always">
<menu>
<item android:id="@+id/sub_item1" android:icon="@mipmap/ic_launcher" android:title="sub item1"></item>
<item android:id="@+id/sub_item2" android:icon="@mipmap/ic_launcher" android:title="sub item2"></item>
<item android:id="@+id/sub_item3" android:icon="@mipmap/ic_launcher" android:title="sub item3"></item>
</menu>
</item>
<item android:id="@+id/group1_item7" android:icon="@mipmap/ic_launcher" android:title="item7" ></item>
</group>
</menu>
注意xml中showAsAction的用法,根据编译版本的不同,使用不同,23使用的app:showAsAction ,该属性可以设置menuitem是展示在actionbar上还是现实在overflow中
其中设置在actionbar上的menuitem只要设置了icon都会显示,但是在overflow中的menuitem的icon就分系统版本不同,而有不同,android 4.0之前会显示icon,android4.0之后显示不出icon,解决方法如下:
/**
* 利用反射机制调用MenuBuilder中的setOptionIconsVisable(),
* 如果是集成自AppCompatActivity则不行,需要在onPreareOptionPanel()中调用该方法
* @param menu 该menu实质为MenuBuilder,该类实现了Menu接口
* @param enable enable为true时,菜单添加图标有效,enable为false时无效。因为4.0系统之后默认无效
*/
private void setIconEnable(Menu menu, boolean enable) {
if (menu != null) {
try {
Class clazz = Class();
if (SimpleName().equals("MenuBuilder")) {
Method m = DeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
//MenuBuilder实现Menu接口,创建菜单时,传进来的menu其实就是MenuBuilder对象(java的多态特征)
m.invoke(menu, enable);
}
} catch (Exception e) {
e.printStackTrace();
}
}
} activity中传进来的menu其实是一个MenuBuilder的实例,而在MenuBuilder中有一个方法setOptionIconVisable(),这里只是用的向上转型,所以这里的menu调用不到,
而该方法又是一个访问修饰符为默认缺省的,所以只能利用反射机制
那么该在哪里调用该方法呢,这里为了兼容AppCompatActivity,我们在onPrepareOptionPanel()中调用
/**
* android 4.0以后使用AppCompatActivity必须在该方法中调用setIconEnable(),
* 隐藏的menuitem的icon才会显示
* android 4.0以后其他的activity可以再onPrepreOptionMenu()中调用
* android 4.0以前可以正常显示overflow中的menuitem的icon
* @param view
* @param menu
* @return*/
@Override
protected boolean onPrepareOptionsPanel(View view, Menu menu) {
setIconEnable(menu, true);//让在overflow中的menuitem的icon显示
PrepareOptionsPanel(view, menu);
}
运行之后可以看到如下图:
有的手机有menu实体键,这个时候actionbar上将不会显示右上角的竖直的三个小点,而是按实体menu键显示menuitem,这不方便我们做统一的界面管理,这个时候可以再activity的onCreate()函数中调用以下代码
/**
* 通过反射,设置实体menu键可用与否
* 该方法在onCreate()中调用
* @param enable false:实体键不可用,会在actionbar上显示小点
* true:可用,点击menu实体键才会显示menuitem
*/
public void setHasPermanentMenuKey(boolean enable){
try {
ViewConfiguration mconfig = (this);
Field menuKeyField = DeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(mconfig, enable);
}
} catch (Exception ex) {
}
}
有的时候系统默认的title也就是actionbar并不能达到我们的预期,这时候我们一般采用自定义的方法,然后把系统默认的隐藏掉,而使用自己的,其实不必如此,android本身支持自定义actionBar的,只需要在activity的oncreate()函数中获取到actionbar,然后设置自己的actionbar布局就可以了如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
Create(savedInstanceState);
setContentView(R.layout.activity_drawer_layout);
ButterKnife.bind(this);
setHasPermanentMenuKey(false);
/*
* ActionBar
*/
ActionBar actionBar = getSupportActionBar();
//设置自定义actionbar的view
actionBar.setCustomView(R.layout.action_bar_layout);
//设置展示的options为DISPLAY_SHOW_CUSTOM
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
//设置showCustom为true
actionBar.setDisplayShowCustomEnabled(true);
//实例化自定义actionbar的view
actionImageView = (ImageView) CustomView().findViewById(R.id.image_view);
actionTextView = (TextView) CustomView().findViewById(R.id.textview);
actionPersonalView = (TextView) CustomView().findViewById(R.id.personal_textview);
actionPersonalView.setOnClickListener(this);
actionImageView.setOnClickListener(this);
这里注意使用getSupportActionBar()的时候有些时候获取到的actionbar为null,这个时候检查是否在menifest或者代码中设置了No_title或者全屏,设置成任何一个都会导致null
这里的actionBar.setCustomView(int layout);这个就可以设置自定义actionbar布局
我的布局acdtion_bar_layout如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image_view"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="20sp"
android:text="标题" />
<TextView
android:id="@+id/personal_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="个人中心"
android:gravity="right|center_vertical"
android:layout_gravity="right"/>
</LinearLayout> 得到的action如下:
二、侧滑菜单Drawerlayout
该类位于
android.support.v4.widget.DrawerLayout
使用很简单,直接在xml中使用按照规则使用即可
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android=""
xmlns:tools=""
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=ample.user.customviewdemo.drawerlayout.DrawerLayoutActivity">
<!--主界面布局 主界面写在最上面-->
<LinearLayout
android:id="@+id/content_frame"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textview"
android:layout_marginTop="100dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="滑出左菜单"
android:textSize="30sp"
android:gravity="center"/>
<TextView
android:id="@+id/textview1"
android:layout_marginTop="100dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="滑出右菜单"
android:gravity="center"/>
<ImageView
android:id="@+id/image_view"
android:layout_marginTop="50dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@mipmap/ic_launcher"
android:scaleType="center"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
<!--左侧滑菜单布局 layout_gravity="start" -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@android:color/holo_green_dark"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" />
<!--右侧滑菜单布局 layout_gravity="end"-->
<RelativeLayout
android:id="@+id/right_drawer"
android:layout_width="220dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="#111"
android:gravity="center_horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="个人中心"
android:textColor="@android:color/white"
android:textSize="24sp" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
activity中代码如下:
ample.user.customviewdemo.drawerlayout;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
ample.user.customviewdemo.R;
import flect.Field;
import flect.Method;
import butterknife.Bind;
import butterknife.ButterKnife;
public class DrawerLayoutActivity extends AppCompatActivity implements View.OnClickListener {
@Bind(R.id.left_drawer)
ListView leftDrawer;
@Bind(R.id.right_drawer)
RelativeLayout rightDrawer;
@Bind(R.id.drawer_layout)
DrawerLayout drawerLayout;
@Bind(R.id.textview)
TextView textview;
@Bind(R.id.textview1)
TextView textview1;
@Bind(R.id.image_view)
ImageView imageView;
private ImageView actionImageView;
private TextView actionTextView;
private TextView actionPersonalView;
@Override
protected void onCreate(Bundle savedInstanceState) {
Create(savedInstanceState);
setContentView(R.layout.activity_drawer_layout);
ButterKnife.bind(this);
setHasPermanentMenuKey(false);
/*
* ActionBar
*/
ActionBar actionBar = getSupportActionBar();
//设置自定义actionbar的view
actionBar.setCustomView(R.layout.action_bar_layout);
//设置展示的options为DISPLAY_SHOW_CUSTOM
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
//设置showCustom为true
actionBar.setDisplayShowCustomEnabled(true);
//实例化自定义actionbar的view
actionImageView = (ImageView) CustomView().findViewById(R.id.image_view);
actionTextView = (TextView) CustomView().findViewById(R.id.textview);
actionPersonalView = (TextView) CustomView().findViewById(R.id.personal_textview);
actionPersonalView.setOnClickListener(this);
actionImageView.setOnClickListener(this);
/**
* 左边侧滑菜单
*/
String[] strs = getResources().getStringArray(R.array.menu_list);
leftDrawer.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strs));
/**
* 主界面按钮添加监听,点击滑出菜单
*/
textview.setOnClickListener(this);
textview1.setOnClickListener(this);
/**
* drawerLayout添加监听,监听侧滑过程,包括打开,关闭,和侧滑offSet
* ActionBarDrawerToggle继承了DrawerLayout.DrawerListener
* 所以可以直接使用
*/
drawerLayout.addDrawerListener(new ActionBarDrawerToggle(this, drawerLayout, R.string.hello_blank_fragment, R.string.app_name) {
@Override
public void onDrawerOpened(View drawerView) {
DrawerOpened(drawerView);
}
@Override
public void onDrawerClosed(View drawerView) {
DrawerClosed(drawerView);
actionTextView.setText("标题");
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
DrawerSlide(drawerView, slideOffset);
//设置actionbar中的icon和主界面的imageview旋转
actionImageView.setRotation(slideOffset*90);
imageView.setRotation(slideOffset*270);
}
});
}
/**
* 通过反射,设置实体menu键可用与否
* 该方法在onCreate()中调用
* @param enable false:实体键不可用,会在actionbar上显示小点
* true:可用,点击menu实体键才会显示menuitem
*/
public void setHasPermanentMenuKey(boolean enable){
try {
ViewConfiguration mconfig = (this);
Field menuKeyField = DeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(mconfig, enable);
}
} catch (Exception ex) {
}
}
/**
* android 4.0以后使用AppCompatActivity必须在该方法中调用setIconEnable(),
* 隐藏的menuitem的icon才会显示
* android 4.0以后其他的activity可以再onPrepreOptionMenu()中调用
* android 4.0以前可以正常显示overflow中的menuitem的icon
* @param view
* @param menu
* @return*/
@Override
protected boolean onPrepareOptionsPanel(View view, Menu menu) {
setIconEnable(menu, true);//让在overflow中的menuitem的icon显示
PrepareOptionsPanel(view, menu);
}
private Menu menu;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
u = menu;
int groupId = 1;
MenuItem item1 = menu.add(groupId, Menu.FIRST + 1, 1, "将第二组item不可见");
item1.setIcon(R.mipmap.ic_launcher);
menu.add(groupId, Menu.FIRST + 2, 2, "将第二组item可见");
menu.add(groupId, Menu.FIRST + 3, 3, "将第二组item不可用");
MenuItem item4 = menu.add(groupId, Menu.FIRST + 4, 4, "将第二组item可用");
item4.setIcon(R.mipmap.ic_launcher);
menu.add(groupId, Menu.FIRST + 5, 5, "将第二组item可单选");
menu.add(groupId, Menu.FIRST + 6, 6, "将第二组item可多选");
groupId = 2;
MenuItem item7 = menu.add(groupId, Menu.FIRST + 7, 7, "menu2_1");
item7.setIcon(R.mipmap.ic_launcher);
MenuItem item8 = menu.add(groupId, Menu.FIRST + 8, 8, "menu2_2");
item8.setIcon(R.mipmap.ic_launcher);
SubMenu subMenu = menu.addSubMenu(groupId, Menu.FIRST + 9, 9, "sub menu");
subMenu.add(groupId, Menu.FIRST + 10, 1, "sub1");
subMenu.add(groupId, Menu.FIRST + 11, 2, "sub2");
/**
* 这个监听事件可以对item的点击事件进行拦截,拦截后的item在onOptionsItemSelected()中不会得到执行
*/
item1.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return true;//返回true为拦截,false不拦截
}
});
return true;
}
/**
* 利用反射机制调用MenuBuilder中的setOptionIconsVisable(),
* 如果是集成自AppCompatActivity则不行,需要在onPreareOptionPanel()中调用该方法
* @param menu 该menu实质为MenuBuilder,该类实现了Menu接口
* @param enable enable为true时,菜单添加图标有效,enable为false时无效。因为4.0系统之后默认无效
*/
private void setIconEnable(Menu menu, boolean enable) {
if (menu != null) {
try {
Class clazz = Class();
if (SimpleName().equals("MenuBuilder")) {
Method m = DeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
//MenuBuilder实现Menu接口,创建菜单时,传进来的menu其实就是MenuBuilder对象(java的多态特征)
m.invoke(menu, enable);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = ItemId();
switch (id) {
case Menu.FIRST + 1:
menu.setGroupVisible(2, false);
break;
case Menu.FIRST + 2:
menu.setGroupVisible(2, true);
break;
case Menu.FIRST + 3:
menu.setGroupEnabled(2, false);
break;
case Menu.FIRST + 4:
menu.setGroupEnabled(2, true);
break;
case Menu.FIRST + 5:
menu.setGroupCheckable(2, true, true);
break;
case Menu.FIRST + 6:
menu.setGroupCheckable(2, true, false);
break;
case Menu.FIRST + 7:
Toast.makeText(this, "menu2_1", Toast.LENGTH_SHORT).show();
break;
case Menu.FIRST + 8:
Toast.makeText(this, "menu2_2", Toast.LENGTH_SHORT).show();
break;
case Menu.FIRST + 10:
Toast.makeText(this, "sub1", Toast.LENGTH_SHORT).show();
break;
case Menu.FIRST + 11:
Toast.makeText(this, "sub2", Toast.LENGTH_SHORT).show();
break;
}
OptionsItemSelected(item);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.textview:
drawerLayout.openDrawer(leftDrawer);
actionTextView.setText("左滑菜单");
break;
case R.id.textview1:
drawerLayout.openDrawer(rightDrawer);
actionTextView.setText("右滑菜单");
break;
case R.id.personal_textview:
drawerLayout.openDrawer(rightDrawer);
actionTextView.setText("右滑菜单");
break;
case R.id.image_view:
drawerLayout.openDrawer(leftDrawer);
actionTextView.setText("左滑菜单");
break;
}
}
}
最后得到效果如下图:
怎么样,是不是感觉还是很炫的,
本文发布于:2024-02-04 13:08:35,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170707973755854.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
| 留言与评论(共有 0 条评论) |