处女男学Android(十二) - 新闻资讯 - 云南小程序开发|云南软件开发|云南网站建设-昆明葵宇信息科技有限公司

159-8711-8523

云南网建设/小程序开发/软件开发

知识

不管是网站,软件还是小程序,都要直接或间接能为您产生价值,我们在追求其视觉表现的同时,更侧重于功能的便捷,营销的便利,运营的高效,让网站成为营销工具,让软件能切实提升企业内部管理水平和效率。优秀的程序为后期升级提供便捷的支持!

您当前位置>首页 » 新闻资讯 » 技术分享 >

处女男学Android(十二)

发表时间:2020-10-19

发布人:葵宇科技

浏览次数:23






一、媒介




转载请标明出处:http://blog.csdn.net/wlwlwlwl015/article/details/42170771
本篇blog将记录一下Android中菜单的应用办法,固然在新版本中推荐应用ActionBar去替代菜单,但我认为菜单依然是挺不错的一种UI交互组件,比ActionBar好点一些,对于手指不灵活的人比起来ActionBar右上角的那个方块小按钮,或许ta会更爱好Menu呢,废话不多说,下面就具体介绍一下Android中关于Menu的应用办法。




二、创建第一个菜单




菜荡竽暌剐两种创建方法,分别是:
  • 经由过程Java代码创建菜单对象。
  • 经由过程xml资本文件定义菜单。

这里我想也不必多说,肯定应钙揭捉择第二种情势,在Activity中写代码去创建菜单必定导致法度榜样代码过于痴肥,并且也不易查看和保护,而第二种办法既轻易不雅察菜单的构造,也降低了耦合性,下面是官方给出的将“Using a menu resource”作为最佳实践的来由,简单看一下:
[img]http://img.blog.csdn.net/20141226143227281?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

所以我这里就不浪费篇幅去记录“经由过程代码去创建菜单”了,重要记录一下若何经由过程xml文件定义菜单资本以及如安在Activity中引用处设置以及应用菜单。


菜单的资本文件平日应当放在/res/menu目次下,菜单资本的根元素平日是<menu.../>元素,并且它不须要指定任何属性,仅是菜单资本文件的根标签罢了。我们在eclipse中新建一个Android工程,在/res/menu下去new一个Menu Resource,可以看到Menu的根本构造:
[img]http://img.blog.csdn.net/20141226150534906?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

可以看到<menu.../>元素内可包含的子元素:
  • <group></group>
  • <item/>

下面分别解释一下这两个标签的用法和属性,起首是最常用的<item/>,<item/>元素用于定义一个菜单项,<item/>元素中又可以包含新的<menu/>,而位于<item/>中的<menu/>天然就代表了指定<item/>的子菜单了。下面先看一下<item/>可指定的常用属性:
[img]http://img.blog.csdn.net/20141226151455609?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast



平日我们必须指定的属性只有一个,就是android:title,其余的属性都是可选的,这里我们创建的第一个菜单简单一些,只给出id和title即可:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/item_1"
        android:title="title1"/>
    <item
        android:id="@+id/item_2"
        android:title="title2"/>
    <item
        android:id="@+id/item_3"
        android:title="title3"/>
    <item
        android:id="@+id/item_4"
        android:title="title4"/>
    <item
        android:id="@+id/item_5"
        android:title="title5"/>
    <item
        android:id="@+id/item_6"
        android:title="title6"/>

</menu>

写好了资本文件之后,在Activity中须要重写onCreateOptionsMenu去加载菜单,加载方法也很简单,经由过程MenuInflater的inflate办法即可加载菜单,完全类似于我们LayoutInflater的用法。关于菜单Item的点击事宜须要在Activity中重写onOptionsItemSelected,根据回调参数来断定不合的Item大年夜而进行不合的处理,其拭魅这些在新建Activity之后都邑主动生成的,下面贴上这两个办法的代码,很简单:
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.my_menu, 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.item_1:
			Toast.makeText(this, "item_1 has been clicked!", Toast.LENGTH_SHORT)
					.show();
			;
			break;
		case R.id.item_2:
			Toast.makeText(this, "item_2 has been clicked!", Toast.LENGTH_SHORT)
					.show();
			break;
		case R.id.item_3:
			Toast.makeText(this, "item_3 has been clicked!", Toast.LENGTH_SHORT)
					.show();
			break;
		case R.id.item_4:
			Toast.makeText(this, "item_4 has been clicked!", Toast.LENGTH_SHORT)
					.show();
			break;
		case R.id.item_5:
			Toast.makeText(this, "item_5 has been clicked!", Toast.LENGTH_SHORT)
					.show();
			break;
		case R.id.item_6:
			Toast.makeText(this, "item_6 has been clicked!", Toast.LENGTH_SHORT)
					.show();
			break;
		}
		return true;
	}
最后看一下运行效不雅:
[img]http://img.blog.csdn.net/20141226155022171




三、选项菜单(Options menu)和高低文菜单(Context menu)




google将菜单按功能特点分为了三种,分别是:选项菜单(Options menu)、高低文菜单(Context menu)以及弹出式菜单(Popup menu),如今就分别介绍一下前两个:选项菜单和高低文菜单。


a.选项菜单(Option menu)


起首看一下官方文档中对option menu的简介:
————————————————————————————
[img]http://img.blog.csdn.net/20141226174154250?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

————————————————————————————
简单翻译一下,“选项菜单”是一个Activity中重要的菜单项的集合,在它膳绫擎应当放置有全局性影响的功能,例如:“搜狗票、“写竽暌故件”和“设置”。说到这里我们差不多应当就能对哄人座了选项菜单了,安卓体系就自带了“选项菜单”,也就是下图的┞封个菜单:
[img]http://img.blog.csdn.net/20141226175340463?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

点击手机的Menu键,弹出的就是我们所说的options menu了,再看一下菜单上供给的功能,分别是:墙纸(Wallpaper)、APP治理器(Manage apps)和体系设置(System settings),这也和文档中提到的“放置全局性影响的功能”相吻合。然则因为大年夜Android3.0版本开端,并不请求手机上必须供给Menu键,并且有可能部分别机将不再供给Menu键(比如我的魅族MX4),在这种情况下,google推荐我们应用ActionBar去替代options menu这种需求。
示例代码已经写过了,刚才“创建的第一个菜单”就是一个简单标准的options menu了。


b.高低文菜单(Context menu)



起首看一下官方文档对Context menu的概述:
[img]http://img.blog.csdn.net/20141229113616471?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

重点是第一句话,简单翻译一下,context menu是一个浮动的菜单,当用户在某个view上履行长按操作时弹出。好了概念上就这么简单,那么一般什么情况下会用到它呢?其拭魅这个具体看需求,不过官方也做了相干解释:
[img]http://img.blog.csdn.net/20141229114133120?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

没错,经常用在ListView、GridView的Items膳绫擎,可想而知也确切如斯,经常会有这种需求,长按ListView弹出一个dialog或者一个menu,比如百度搜刮中应当就是一个标准的context menu了,如下图:
[img]http://img.blog.csdn.net/20141229114518650?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

可以看到,当我长按一条Item的时刻,会弹出如许的一个菜单,它就是context menu,下面就具体介绍一下context menu的创建方法。


与options menu类似,然则在Activity中照样有些许的差别,依旧来看一下官方文档:
[img]http://img.blog.csdn.net/20141229115431343?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

可以看到,第一步就是为我们的高低文菜单注册一个View,也就是说当我们长按哪个View的时刻才须要弹出菜单,当我们欲望ListView或GridView的items供给雷同的菜单的话,那么直接传一个ListView或GridView即可完成。下面的代码就是模仿膳绫擎百度的那个菜单的,接下来一一贴出代码,起首是在Activity中为高低文菜单注册一个View:
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ListView lv = (ListView) findViewById(R.id.lv_test);
		registerForContextMenu(lv); //为高低文菜单注册一个ListView
	}
下面看一下接下来的须要做的工作,文档中也已经说的很清跋扈了:
[img]http://img.blog.csdn.net/20141229121054984?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

可以看到,这里重写的是onCreatContextMenu办法,而选项菜单重写的是onOptionsMenu,这也就是它们最重要的差别了。可以看到这个办法并不须要返回值,所以直接经由过程MenuInflater加载一下菜单的资本文件就OK了。
如不雅欲望应用法度榜样可以或许为菜单供给响应,同样的须要再重写一个响应办法,与options menu的类似但也有些许不合:
 [img]http://img.blog.csdn.net/20141229122405671?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
很简单,不做零丁说清楚明了,下面就看一下仿百度的高低文菜单的完全示例代码。


起首是activity的构造文件:
<LinearLayout 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"
    android:orientation="vertical" >

    <ScrollView
        android:id="@+id/sv_4lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="@drawable/top_part" >
            </LinearLayout>

            <com.wl.view.MyListView
                android:id="@+id/lv_test"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="2"
                android:entries="@array/hero" >
            </com.wl.view.MyListView>
        </LinearLayout>
    </ScrollView>

</LinearLayout>

menu的构造文件也很简单:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/item1"
        android:title="新窗口打开"/>
    <item
        android:id="@+id/item2"
        android:title="后台打开"/>
    <item
        android:id="@+id/item3"
        android:title="选择文本"/>
    <item
        android:id="@+id/item4"
        android:title="复制链接地址"/>
    <item
        android:id="@+id/item5"
        android:title="下载链接"/>

</menu>

最后是Activity代码:
package com.wl.contextmenudemo;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.wl.model.BaiduItem;
import com.wl.view.MyListView;

public class MainActivity extends Activity {

	private BaiduItem baiduItem;
	private Context context;
	private LayoutInflater inflater;
	private ScrollView sv;
	private MyListView mlv;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		context = this;
		inflater = LayoutInflater.from(context);
		sv = (ScrollView) findViewById(R.id.sv_4lv);
		sv.smoothScrollTo(0, 0);

		MyListView lv = (MyListView) findViewById(R.id.lv_test);
		baiduItem = new BaiduItem();
		lv.setAdapter(new Myadapter());
		registerForContextMenu(lv); // 为高低文菜单注册一个ListView
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		getMenuInflater().inflate(R.menu.my_menu_2, menu);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case R.id.item1:
			Toast.makeText(context, "新窗口打开!", Toast.LENGTH_SHORT).show();
			break;
		case R.id.item2:
			Toast.makeText(context, "后台打开!", Toast.LENGTH_SHORT).show();
			break;
		case R.id.item3:
			Toast.makeText(context, "选择文本!", Toast.LENGTH_SHORT).show();
			break;
		case R.id.item4:
			Toast.makeText(context, "复制链接地址!", Toast.LENGTH_SHORT).show();
			break;
		case R.id.item5:
			Toast.makeText(context, "下载链接!", Toast.LENGTH_SHORT).show();
			break;
		}
		return true;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		return super.onCreateOptionsMenu(menu);
	}

	class Myadapter extends BaseAdapter {

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return baiduItem.items.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return baiduItem.items.get(position);
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			View v = inflater.inflate(R.layout.my_item_1, null);
			TextView title = (TextView) v.findViewById(R.id.tv_title);
			title.setText(baiduItem.items.get(position).getTitle());
			TextView content = (TextView) v.findViewById(R.id.tv_content);
			content.setText(baiduItem.items.get(position).getContent());
			TextView url = (TextView) v.findViewById(R.id.tv_url);
			url.setText(baiduItem.items.get(position).getUrlAndDate());
			return v;
		}

	};
}

代码中经由过程自定义ListView来处理和ScrollView滑动冲突,关于数据则经由过程封装好的BaiduItem这个类直接供给,数据的初始化写在这个类的静态代码块中,因为只有5条数据,所以adapter也没有效ViewHolder优化,整体很简单,只是模仿那个百度的效不雅装个B,重点照样懂得一下context menu的实用处合,最后看一下运行效不雅图:
[img]http://img.blog.csdn.net/20141231161917497





四、弹出菜单(Popup menu)




看到pop这个词很明显的可以知道它肯定是类似于popupwindow,是一个弹出式的菜单,并且肯定也和popupwindow有很多相似的特点,依旧看一下官方文档对于popupmenu的概述:
[img]http://img.blog.csdn.net/20150101202353272?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

简单翻译一下,popup menu是一个停靠在固定View上的模式菜单,如不雅该View下方有空间,那么弹出菜单将显示在该View的下方,不然会显示在该View的上方。不难解得popup menu是依附于一个View的,也就是说袈溱指定View的上方or下方弹出,这种菜单一般会大年夜顶部弹出或者大年夜底部弹出,在很多APP中都很常见这种菜单,比如微信主界面右上角的加号搁笔,点击就会弹出一个popupmenu。


接下来介绍一下popup menu的创建方法,同popup window很类似,仅需三步:
1.经由过程其构造办法new PopupMenu(Context context,View anchor)创建下拉菜单,第二个参数即表示本菜单所依附的View。
2.调用MenuInflater的inflate()办法装载menu的资本文件。
3.调用popup menu的show()办法来显示菜单即可。
很简单吧,也没啥好说的,下面就模仿微信的那个弹出菜单做一个小例子,直接贴代码。


Activity构造文件:
<LinearLayout 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"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/ll_top_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#000"
        android:orientation="horizontal"
        android:padding="8dp" >

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:text="我不是微信"
            android:textColor="#ccc"
            android:textSize="16sp" />

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" >

            <ImageButton
                android:id="@+id/ibtn_search"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/ic_search" />

            <ImageButton
                android:id="@+id/ibtn_add"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:background="@drawable/ic_add" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

Activity代码:
package com.wl.menusdemo;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.PopupMenu;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

	private ImageButton ibtnAdd;
	private ImageButton ibtnSearch;
	private PopupMenu popMenu;

	private Context context;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		context = this;
		ibtnAdd = (ImageButton) findViewById(R.id.ibtn_add);
		ibtnAdd.setOnClickListener(this);
		ibtnSearch = (ImageButton) findViewById(R.id.ibtn_search);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if (v == ibtnAdd) {
			popMenu = new PopupMenu(context, ibtnAdd);
			getMenuInflater().inflate(R.menu.pop_menu, popMenu.getMenu());
			popMenu.show();
			popMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
				@Override
				public boolean onMenuItemClick(MenuItem item) {
					// TODO Auto-generated method stub
					switch (item.getItemId()) {
					case R.id.item_chart:
						Toast.makeText(context, "提议群聊!", Toast.LENGTH_SHORT)
								.show();
						break;
					case R.id.item_add_friend:
						Toast.makeText(context, "添加同伙!", Toast.LENGTH_SHORT)
								.show();
						break;
					case R.id.item_sao:
						Toast.makeText(context, "扫一扫!", Toast.LENGTH_SHORT)
								.show();
						break;
					case R.id.item_idea:
						Toast.makeText(context, "看法反馈!", Toast.LENGTH_SHORT)
								.show();
						break;
					}
					return false;
				}
			});
		}
	}

}



是不是超简单的说,下面看一下运行效不雅:
[img]http://img.blog.csdn.net/20150101212405724





五、模仿手机QQ的底部弹出菜单




介绍完了所有类型的菜单之后,最后再做一个演习,可能我们也发清楚明了菜单的样式比较局限,一般很难做一些定制的样式,所以说还有一种很不错的解决方檀卷是不应用Menu的API,经由过程监听菜单键的KEY CODE来弹出一个popup window,如许的话我们做一些个性化的样式、动画等等就没有那么多限制了,在这里我就经由过程这种方法来模仿一下手机QQ的功能菜单,下面是效不雅图:
[img]http://img.blog.csdn.net/20150102180313515?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2x3bHdsd2wwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

可以看到,当我们进入QQ之后点击手机的Menu键时,会大年夜底部弹出图中圈出的菜单,下面就结合popup window来实现这个效不雅,起首将须要做的工作拆分为三个步调:
step 1
在Activity中重写onKeyDown()办法,并经由过程KEY CODE来监听菜单键按下的事宜,并在该事宜中弹出一个popup window。
step 2
构造popup window对象,并编写构造文件代码,设制揭捉式以及动画。
step 3
点击菜单键时show这个popup window,点击菜单键或者popup window之外的区域时dismiss这个popup window。


好了,接下来就按步调去实现它,起首是第一步,重写onKeyDown()办法用来响应菜单键的单击,直接贴代码:
package com.wl.menusdemo;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.Toast;

public class SecondActivity extends Activity {

	private Context context;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.second);
		context = this;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if (keyCode == KeyEvent.KEYCODE_MENU) {
			Toast.makeText(context, "预备好,要弹出菜单了!", Toast.LENGTH_LONG).show();
		}
		return true;
	}

}



很简单,看一下效不雅图:
[img]http://img.blog.csdn.net/20150102190024953



第二步和第三步一路说了,编写popup window的构造文件代码,我能想到的最简单的办法就是经由过程一组Button来实现,然后须要为popupwindow添加一个弹出动画,直接看代码,下面分别是popupwindow的构造文件和Activity中的全部代码。


popup_menu.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="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btn_ver_update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/my_btn_selector_2"
        android:gravity="center"
        android:padding="5dp"
        android:text="版本更新"
        android:textColor="#62A6E7"
        android:textSize="20sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#ccc" >
    </LinearLayout>

    <Button
        android:id="@+id/btn_help"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/my_btn_selector_3"
        android:gravity="center"
        android:padding="5dp"
        android:text="赞助与反馈"
        android:textColor="#62A6E7"
        android:textSize="20sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#ccc" >
    </LinearLayout>

    <Button
        android:id="@+id/btn_exit_qq"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/my_btn_selector_4"
        android:gravity="center"
        android:padding="5dp"
        android:text="退出QQ"
        android:textColor="#62A6E7"
        android:textSize="20sp" />

    <Button
        android:id="@+id/btn_undo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        android:background="@drawable/my_btn_selector"
        android:gravity="center"
        android:padding="5dp"
        android:text="撤消"
        android:textColor="#62A6E7"
        android:textSize="20sp" />

</LinearLayout>

Activity:
package com.wl.menusdemo;

import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.Toast;

public class SecondActivity extends Activity implements OnClickListener {

	private Context context;
	private PopupWindow popupWindow;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.second);
		context = this;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if (keyCode == KeyEvent.KEYCODE_MENU) {
			showMenu();
			return true;
		}

		return super.onKeyDown(keyCode, event);
	}

	private void showMenu() {
		LayoutInflater inflater = getLayoutInflater();
		View menuView = inflater.inflate(R.layout.pop_menu, null);
		Button button1 = (Button) menuView.findViewById(R.id.btn_ver_update);
		Button button2 = (Button) menuView.findViewById(R.id.btn_help);
		Button button3 = (Button) menuView.findViewById(R.id.btn_exit_qq);
		Button button4 = (Button) menuView.findViewById(R.id.btn_undo);
		button1.setOnClickListener(this);
		button2.setOnClickListener(this);
		button3.setOnClickListener(this);
		button4.setOnClickListener(this);

		// 设置PopupWindow宽高
		DisplayMetrics metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);
		double screenWidth = metrics.widthPixels * 0.95;

		popupWindow = new PopupWindow(menuView, (int) screenWidth,
				LayoutParams.WRAP_CONTENT);
		// 想要让PopupWindow中的控件可以或许应用,就必须设置PopupWindow为focusable
		popupWindow.setFocusable(true);

		// 想做到在你点击PopupWindow以外的区域时刻让PopupWindow消掉就做如下两步操作
		// 1:设置setOutsideTouchable为ture,这个很轻易懂得吧,跟AlertDialog一样的
		popupWindow.setOutsideTouchable(true);
		popupWindow.setBackgroundDrawable(getResources().getDrawable(
				android.R.color.transparent));
		popupWindow.setAnimationStyle(R.style.AnimationPreview);
		popupWindow.setOnDismissListener(onDismissListener);

		popupWindow.showAtLocation(getWindow().getDecorView(),
				android.view.Gravity.BOTTOM, 0, 0);

		// 设置父窗口透明度
		WindowManager.LayoutParams wlp = getWindow().getAttributes();
		wlp.alpha = 0.5f;
		getWindow().setAttributes(wlp);
	}

	private OnDismissListener onDismissListener = new OnDismissListener() {

		@Override
		public void onDismiss() {
			WindowManager.LayoutParams wlp = getWindow().getAttributes();
			wlp.alpha = 1.0f;
			getWindow().setAttributes(wlp);

		}
	};

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if (popupWindow != null && popupWindow.isShowing())
			popupWindow.dismiss();
		switch (v.getId()) {
		case R.id.btn_ver_update:
			Toast.makeText(context, "版本更新!", Toast.LENGTH_SHORT).show();
			break;
		case R.id.btn_help:
			Toast.makeText(context, "赞助与反馈!", Toast.LENGTH_SHORT).show();
			break;
		case R.id.btn_exit_qq:
			Toast.makeText(context, "退出QQ!", Toast.LENGTH_SHORT).show();
			break;
		case R.id.btn_undo:
			Toast.makeText(context, "撤消!", Toast.LENGTH_SHORT).show();
			break;
		}
	}
}

BINGO~停止了,最后看一下效不雅图,相似度还不错吧:
[img]http://img.blog.csdn.net/20150103151903718



关于样式的话,每个按钮都是经由过程selector+shape嵌套实现的,popup window弹出的时刻还设置了一个异常简单的补间动画,配风景直接用透明色值就OK了,下面把两个动画的资本文件和一个按钮的样式资本文件贴出来(其余的类似)。


anim_bottom_in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="350"
        android:fromYDelta="100%"
        android:toYDelta="0.0" />

</set>

anim_bottom_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="350"
        android:fromYDelta="0.0"
        android:toYDelta="100%p" />

</set>

my_btn_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="false"><shape android:shape="rectangle">
            <gradient android:endColor="#efffffff" android:startColor="#efffffff"></gradient>

            <!-- 设置内填充 -->
            <padding android:bottom="7dp" android:left="7dp" android:right="7dp" android:top="7dp" />

            <!-- 设置圆角矩形 -->
            <corners android:radius="8dp" />
        </shape></item>
    <item android:state_pressed="true"><shape android:shape="rectangle">
            <gradient android:endColor="#ecdcdcdc" android:startColor="#ecdcdcdc"></gradient>

            <!-- 设置内填充 -->
            <padding android:bottom="7dp" android:left="7dp" android:right="7dp" android:top="7dp" />

            <!-- 设置圆角矩形 -->
            <corners android:radius="8dp" />
        </shape></item>

</selector>

Over,如不雅新手同伙细心看了本篇blog的话信赖必定会有不少的收成的~ 我小我有以下收成:
1.进修了Android中的3种Menu的概念和R单的应用办法(Options menu、Context menu、Popup menu)。
2.进修了Android简单动画的编写和引用。
3.进修了selector和shape的嵌套。
4.进修并复习了以下的几个小常识点:改变popupwindow父窗体透明度、shape资本中关于4个corners的随便率性控制、根据DisplayMetrix来设置popupwindow的宽度、根据KEY CODE监听菜单键的动作、关于ScrollView嵌套ListView滚动冲突的问题等等。




六、总结




也许这一篇blog的标题猜吸惹人,内容也没有其余大年夜神写的那么深刻高端,但我认为这算是我写过的最卖力的博客之一了,用了很长时光。大年夜翻译文档、修改图片到录制gif,对每一个常识点和概念句斟字嚼,推敲再三,不放过每一个细节,总的来说我的收成照样蛮大年夜的,至少在我的下一APP中我必定会用到膳绫擎写的那个仿QQ的“菜单”。在往后的blog中我还会尽我最大年夜的尽力去做到“卖力”、“细心”和“完美”,因为我是处女座。好了,废话不多说,持续滚去加班写办事端了,但同时Android的进修我也毫不会拉下的,以csdn为证!加油,Raito!




相关案例查看更多