首页 > 代码库 > Android基本控件之Menus
Android基本控件之Menus
在我们的手机中有很多样式的菜单,比如:我们的短信界面,每条短信,我们长按都会出现一个菜单,还有很多的种类。那么现在,我们就来详细的讨论一下安卓中的菜单
Android的控件中就有这么一个,叫做Menus。就是菜单的意思,他基本分为三种:选项式菜单、上下文菜单、弹出式菜单
我们先来看第一种:选项式菜单
那么什么是选项式菜单呢? 就是当我们点击一个菜单的时候会弹出来一个菜单
如上图所示,右上角的那三个小点 就是菜单按钮,当我们点击时就会弹出一个菜单,这就是一个选项是菜单,既然我们知道是什么东西了,我们自然要做出来嘛~
我们来分析一下,这个选项式菜单怎么做:
我们知道弹出来的菜单是有布局的,那么我们就创建这样的一个文件,但是这个文件不同于layout。这个文件是menus专用的,需要在res下创建一个menu的一个目录,然后我们在menu目录中创建一个文件
我们再来分析下Activity中应该如何实现:
我们需要重写父类的onCreateOptionMenu()方法和onOptionsItemSelected()方法
这两个方法是干什么的呢? 其中的onCreateOptionMenu()方法是用来创建这样的一个菜单的,那么onOptionsItemSelected()方法就是设置点击菜单后的点击事件
然后,我们根据上述的分析,来操作一下:
我们首先来在res下创建menu目录,并新建一个文件
<?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"> <item android:id="@+id/item_op_caomao" android:icon="@mipmap/lufei_titile" android:orderInCategory="100" android:title="草帽" app:showAsAction="ifRoom"> <menu> <item android:id="@+id/item_op_lufei" android:icon="@mipmap/lufei" android:orderInCategory="100" android:title="路飞" app:showAsAction="ifRoom" /> </menu> </item> <item android:id="@+id/item_op_haijun" android:icon="@mipmap/aisi" android:orderInCategory="100" android:title="海军" app:showAsAction="ifRoom"> <menu> <item android:id="@+id/item_op_simoge" android:icon="@mipmap/simoge" android:orderInCategory="100" android:title="斯摩格" app:showAsAction="ifRoom"/> </menu> </item> <item android:id="@+id/item_op_hongxin" android:icon="@mipmap/xiangkesi" android:orderInCategory="100" android:title="红心" app:showAsAction="ifRoom"> <menu> <item android:id="@+id/item_op_luo" android:icon="@mipmap/duolanan" android:orderInCategory="100" android:title="多拉男" app:showAsAction="ifRoom" /> </menu> </item> </menu>
在这里,我们创建这么一个文件,其中的item就是每个菜单的菜单项,我们为其设置了ID、图标(icon)、子菜单(menu)等属性。
我们来仔细看一下showAsAction属性,这个属性要求必须用app的命名空间,而我们默认是android的命名空间,那么我们就在上面定义一个app的命名空间,并使用,其中的值,也就是ifRoom的意思就是当屏幕上有空余的地方就显示图标,否则就显示“三个小点”
然后我们来到我们的Activity中,去编写代码
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /** * 重写的父类的方法 * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { //通过菜单加载器获得菜单的布局 getMenuInflater().inflate(R.menu.item_menus,menu); return super.onCreateOptionsMenu(menu); } /** * 重写的父类方法(用作点击事件) * @param item * @return */ @Override public boolean onOptionsItemSelected(MenuItem item) { //判断item的id switch (item.getItemId()){ case R.id.item_op_lufei: //弹出一个吐司 Toast.makeText(this, "路飞", Toast.LENGTH_SHORT).show(); break; case R.id.item_op_luo: Toast.makeText(this, "ROOM!!", Toast.LENGTH_SHORT).show(); break; case R.id.item_op_simoge: Toast.makeText(this, "斯摩格", Toast.LENGTH_SHORT).show(); break; } return super.onOptionsItemSelected(item); } }
我们这么一个选项式菜单就编写完成了,我们来看一下运行的结果吧
我们的运行结果是从左往右一次运行的哦~
选项式菜单,我们就完成了。
接下来,我们来看第二种,也就是上下文菜单:
那么什么是上下文菜单呢?上下文菜单是需要依附在某个控件之上的,需要长按该控件,会弹出来一个菜单,例如:我们以前的手机,在我们按住短信的时候,会弹出一个小菜单,提示你转发啊、删除啊什么的,那么就是一个上下文菜单。
我们来实现一下
我们还是来分析一下都需要怎么做:
我们首先需要一个控件让上下文菜单去依附,我们就在主布局文件上创建一个TextView好了。
然后,我们还是需要一个弹出的菜单的布局,我们在res下创建一个menu目录,在目录下创建菜单的文件
我们的布局暂时就这么多
我们来分析下Activity中如何去实现:
首先,我们找到需要的控件,就是那个TextView,我们还需要注册一个长按的这么一个事件,使用registerForContextMenu()方法
然后,我们重写父类的onCreateContextMenu()方法和onContextItemSelected()方法
这两个方法中 onCreateContextMenu()方法是为了创建一个上下文菜单,onContextItemSelected()方法就是点事件了。这个和选项式菜单就不一样了哦
然后我们根据上面的分析来实现一下:
首先,我们来创建菜单的布局文件:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item_content_one" android:title="摁你了,怎么地!给你变成蓝色" android:orderInCategory="100"/> <item android:id="@+id/item_content_two" android:title="摁你了,怎么地!给你变成黄色" android:orderInCategory="200"/> <item android:id="@+id/item_content_three" android:title="摁你了,怎么地!给你变成红色" android:orderInCategory="300"/> </menu>
然后,我们来看主界面菜单的布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main2" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="application.smile.menus.Main2Activity"> <TextView android:id="@+id/tv_dese" android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="不服你摁我" android:textSize="50sp"/> </RelativeLayout>
现在,我们再来看我们的Activity中是如何实现的:
public class Main2Activity extends AppCompatActivity { private TextView tv_dese; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); //找到我们关心的控件 tv_dese = (TextView) findViewById(R.id.tv_dese); //注册长按的事件 registerForContextMenu(tv_dese); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); //根据菜单加载器,加载菜单布局 getMenuInflater().inflate(R.menu.content_menus,menu); } @Override public boolean onContextItemSelected(MenuItem item) { //根据id查找点击的是那个菜单项 switch (item.getItemId()){ case R.id.item_content_one: //改变TextView上字体的颜色 tv_dese.setTextColor(Color.BLUE); break; case R.id.item_content_two: tv_dese.setTextColor(Color.YELLOW); break; case R.id.item_content_three: tv_dese.setTextColor(Color.RED); break; } return super.onContextItemSelected(item); } }
这样,我们就完成了,我们来测试一下吧
我们发现,我们长按之后就弹出来了菜单,然后我们选择菜单就改变了文字的颜色
这样,我们的上下文菜单就完成了。
最后,我们来看一下弹出式菜单
那么什么是弹出式菜单呢? 简单说是弹出来的菜单嘛~哈哈,就是当我们点击一个控件的时候就会弹出来一个菜单,这个弹出和选项式可不同哦。这个的弹出菜单是在该控件的下方出现,如果下方没有地方了,就在上方出现
我们来分析一下:
首先,我们还是需要一个控件让弹出式菜单去依附,在这里,我们就使用imageview,并设置onclick属性为了好看点儿
然后,我们仍然需要菜单的布局,与前两种一致
然后我们来分析一下Acitivity:
我们要在Activity中写以onclick属性值命名的点击事件(这个是imageView的点击事件)(这里为什么有去找ImageView呢?因为onclick方法参数中的view就是我们点击的控件,也就是该程序中的ImageView)
然后,我们要实现OnMenuItemClickListener接口并重写onMenuItemClick()方法 作为菜单的点击事件
接下来,我们根据我们的分析来实现弹出式菜单
首先,我们需要在主界面布局文件中定义一个ImageView,并设置onClick属性
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main3" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="application.smile.menus.Main3Activity"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@android:drawable/ic_menu_add" android:onClick="show" /> </RelativeLayout>
然后,我们在res下的menu目录下创建一个菜单的布局文件
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item_popup_1" android:orderInCategory="100" android:title="标题一"></item> <item android:id="@+id/item_popup_2" android:orderInCategory="200" android:title="标题二"></item> <item android:id="@+id/item_popup_3" android:orderInCategory="300" android:title="标题三"></item> <item android:id="@+id/item_popup_4" android:orderInCategory="400" android:title="标题四" /> </menu>
现在我们的这些布局文件算是都写完了,然后我们来看Activity中的具体实现
public class Main3Activity extends Activity implements PopupMenu.OnMenuItemClickListener{ private PopupMenu popupMenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); } public void show(View v){ //实例化一个弹出式菜单,传入上下文和控件 popupMenu = new PopupMenu(this,v); //根据菜单填充器获得菜单的布局 popupMenu.getMenuInflater().inflate(R.menu.popup_menus1,popupMenu.getMenu()); //设置菜单的点击事件 popupMenu.setOnMenuItemClickListener(this); //显示菜单 popupMenu.show(); } @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.item_popup_1: Toast.makeText(Main3Activity.this,"你点击了第一个标签",Toast.LENGTH_LONG).show(); break; case R.id.item_popup_2: Toast.makeText(Main3Activity.this,"你点击了第二个标签",Toast.LENGTH_LONG).show(); break; case R.id.item_popup_3: Toast.makeText(Main3Activity.this,"你点击了第三个标签",Toast.LENGTH_LONG).show(); break; } return true; } }
然后,我们来看一下运行的结果:
这样,我们的弹出式菜单就完成了
我们来看一下这三个在Activity中的区别:
选项式菜单:重写父类的onCreateOptionsMenu()方法 和 父类的onOptionsItemSelected()方法
上下文菜单:重写父类的onCreateContextMenu()方法 和 父类的onContextItemSelected()方法
弹出式菜单:写onclick属性对应的点击事件 和 OnMenuItemClickListener接口的onMenuItemClick()方法
Android基本控件之Menus