右上菜单,可以通过 重写 onCreateOptionsMenu指定 menu, 重写 onOptionsItemSelected 来响应点击事件
不过 这个菜单在某些手机上弹出的有点卡顿,而且如果不对主题进行设置,会从actionbar 上直接弹出,而不是下面
如果想从下面弹出,要先添加一个style
<style name="MenuStyle" parent="@style/Widget.AppCompat.Light.PopupMenu.Overflow"><item name="overlapAnchor">false</item></style>
之后在activity引用的主题中添加一行 就行了
<item name="actionOverflowMenuStyle">@style/MenuStyle</item>
Menu在没有特别要求的情况还是很好用的,但是如果要求比较复杂的时候就不如用PopupWindow了
要实现如图的效果
先拿到从美工拿到的图片
打开sdk的 tools文件夹 打开 draw9patch.bat 把图片拖进去
画黑边 左上两个方向的黑边 表示拉伸部分
右下表示布局中控件内容显示的区域
如果画错了 按住shift 抹掉
完成之后save
布局
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 android:background="@drawable/pop_bg_shadow9" 6 android:gravity="center_horizontal" 7 android:orientation="vertical" 8 > 9 10 <LinearLayout 11 android:id="@+id/ll_action_config" 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:gravity="center_vertical" 15 android:orientation="horizontal" 16 android:padding="10dp" 17 > 18 19 <ImageView 20 android:layout_width="25dp" 21 android:layout_height="25dp" 22 android:src="@drawable/pop_setting"/> 23 24 <TextView 25 android:layout_width="wrap_content" 26 android:layout_height="wrap_content" 27 android:paddingLeft="15dp" 28 android:text="关联配置" 29 android:textColor="@color/white"/> 30 31 </LinearLayout> 32 33 <LinearLayout 34 android:id="@+id/ll_action_history" 35 android:layout_width="match_parent" 36 android:layout_height="wrap_content" 37 android:gravity="center_vertical" 38 android:orientation="horizontal" 39 android:padding="10dp" 40 > 41 42 <ImageView 43 android:layout_width="25dp" 44 android:layout_height="25dp" 45 android:src="@drawable/pop_history"/> 46 47 <TextView 48 android:layout_width="wrap_content" 49 android:layout_height="wrap_content" 50 android:paddingLeft="15dp" 51 android:text="历史记录" 52 android:textColor="@color/white"/> 53 54 </LinearLayout> 55 56 <LinearLayout 57 android:id="@+id/ll_action_ip" 58 android:layout_width="match_parent" 59 android:layout_height="wrap_content" 60 android:gravity="center_vertical" 61 android:orientation="horizontal" 62 android:padding="10dp" 63 > 64 65 <ImageView 66 android:layout_width="25dp" 67 android:layout_height="25dp" 68 android:src="@drawable/pop_ip"/> 69 70 <TextView 71 android:layout_width="wrap_content" 72 android:layout_height="wrap_content" 73 android:paddingLeft="15dp" 74 android:text="IP地址" 75 android:textColor="@color/white"/> 76 77 </LinearLayout> 78 79 <LinearLayout 80 android:id="@+id/ll_action_about" 81 android:layout_width="match_parent" 82 android:layout_height="wrap_content" 83 android:gravity="center_vertical" 84 android:orientation="horizontal" 85 android:padding="10dp" 86 > 87 88 <ImageView 89 android:layout_width="25dp" 90 android:layout_height="25dp" 91 android:src="@drawable/pop_about"/> 92 93 <TextView 94 android:layout_width="wrap_content" 95 android:layout_height="wrap_content" 96 android:paddingLeft="15dp" 97 android:text="关于" 98 android:textColor="@color/white"/> 99 100 </LinearLayout> 101 </LinearLayout>
现在要实现点击 右上菜单 弹出 这个布局,同时菜单的图标会变换。
在menu目录 新建一个xml 默认icon是 more_close
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><itemandroid:id="@+id/action_menu"android:icon="@drawable/more_close"android:title="菜单"app:showAsAction="always"></item> </menu>
回到activity
@Overridepublic boolean onCreateOptionsMenu(Menu menu) {this.menu = menu;getMenuInflater().inflate(R.menu.face, menu);return super.onCreateOptionsMenu(menu);}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case R.id.action_menu:View view=findViewById(R.id.action_menu);showActionMenuPopup(view);break;}return super.onOptionsItemSelected(item);}
红色部分都是关键部分
先看 showActionMenuPopup 这个弹出菜单的方法
首先要改变菜单的图标
menu.getItem(0).setIcon(getResources().getDrawable(R.drawable.more_open));
这个menu是 全局的
private Menu menu;
在 onCreateOptionsMenu 中 把这个menu初始化
之后 设置 PopupWindow
1 View view=LayoutInflater.from(this).inflate(R.layout.popup_actionmenu,null); 2 actionmenupopupWindow = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT); 3 actionmenupopupWindow.setContentView(view); 4 5 view.findViewById(R.id.ll_action_config).setOnClickListener(this); 6 view.findViewById(R.id.ll_action_history).setOnClickListener(this); 7 view.findViewById(R.id.ll_action_ip).setOnClickListener(this); 8 view.findViewById(R.id.ll_action_about).setOnClickListener(this); 9 10 actionmenupopupWindow.setFocusable(true); 11 actionmenupopupWindow.setBackgroundDrawable(new BitmapDrawable()); 12 13 actionmenupopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { 14 @Override 15 public void onDismiss() { 16 menu.getItem(0).setIcon(getResources().getDrawable(R.drawable.more_close)); 17 } 18 }); 19 20 actionmenupopupWindow.showAsDropDown(v);
5-8 设置弹出菜单的点击事件
11 点击PopupWindow之外的地方PopupWindow消失
13-18 监听PopupWindow消失 改变菜单图标
20 showAsDropDown 从下方出现 肯定要是一个view的, 回到onOptionsItemSelected 找到右上菜单的view 传入了方法中,最后在这里使用
还有一个显示方法 直接指定位置,不过要测量出状态栏和actionbar的高度
actionmenupopupWindow.showAtLocation(findViewById(R.id.action_menu),Gravity.RIGHT|Gravity.TOP ,0, getStatusBarHeight(this)+getSupportActionBar().getHeight());
IOS有一个底部菜单控件 UIActionSheet
安卓方面想实现这个 有第三方的 ActionSheet 有 谷歌官方的design包 BottomSheet
用PopupWindow 也可以实现
rootview = LayoutInflater.from(this).inflate(R.layout.activity_main,null);
1 View view= LayoutInflater.from(this).inflate(R.layout.popup_camera_sel,null); 2 bottompopupWindow = new PopupWindow(view, LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT); 3 4 bottompopupWindow.setContentView(view); 5 6 view.findViewById(R.id.ll_gallery).setOnClickListener(this); 7 view.findViewById(R.id.ll_camera).setOnClickListener(this); 8 view.findViewById(R.id.ll_cancle).setOnClickListener(this); 9 10 WindowManager.LayoutParams lp = getWindow().getAttributes(); 11 lp.alpha = 0.6f; 12 getWindow().setAttributes(lp); 13 14 bottompopupWindow.setFocusable(true); 15 bottompopupWindow.setBackgroundDrawable(new BitmapDrawable()); 16 bottompopupWindow.setAnimationStyle(R.style.mypopwindow_anim_style); 17 18 bottompopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { 19 @Override 20 public void onDismiss() { 21 WindowManager.LayoutParams lp = getWindow().getAttributes(); 22 lp.alpha = 1f; 23 getWindow().setAttributes(lp); 24 } 25 }); 26 bottompopupWindow.showAtLocation(rootview, Gravity.BOTTOM, 0, 0);
10-12 18-25 改变屏幕的透明度
style 从底部升上来 降下去的动画
<style name="mypopwindow_anim_style"><item name="android:windowEnterAnimation">@anim/popshow_anim</item><!-- 指定显示的动画xml --><item name="android:windowExitAnimation">@anim/pophidden_anim</item><!-- 指定消失的动画xml --></style>
show
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="500"android:fromYDelta="50%p"android:toYDelta="0" /> </set>
hide
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="500"android:fromYDelta="0"android:toYDelta="50%p" /> </set>
布局
<?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="wrap_content"android:background="@color/white"android:orientation="vertical"android:gravity="center"><LinearLayoutandroid:id="@+id/ll_gallery"android:layout_width="match_parent"android:layout_height="50dp"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="相册"android:textColor="#333333"android:textSize="20sp"/></LinearLayout><!--<TextView--><!--android:layout_width="200dp"--><!--android:layout_height="1dp"--><!--android:background="#838B8B"--><!--/>--><ImageViewandroid:src="@drawable/line_pop"android:scaleType="centerCrop"android:layout_width="match_parent"android:layout_height="wrap_content"/><LinearLayoutandroid:id="@+id/ll_camera"android:layout_width="match_parent"android:layout_height="50dp"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="相机"android:textColor="#333333"android:textSize="20sp"/></LinearLayout><!--<TextView--><!--android:layout_width="200dp"--><!--android:layout_height="1dp"--><!--android:background="#838B8B"--><!--/>--><ImageViewandroid:src="@drawable/line_pop"android:scaleType="centerCrop"android:layout_width="match_parent"android:layout_height="wrap_content"/><LinearLayoutandroid:id="@+id/ll_cancle"android:layout_width="match_parent"android:layout_height="50dp"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="取消"android:textSize="20sp"/></LinearLayout></LinearLayout>
最后 记得响应完点击事件之后 dismiss 关闭PopupWindow