android存储数据的方法问题:onCreateOptionsMenu()方法的返回值是做什么用的?

Android用户界面_甜梦文库|文库百度|百度文库下载|百度文档|新浪文库|豆丁文库|冰点文库|文库宝|免费下载百度文库
甜梦文库_文库百度,百度文库下载,下载百度文库的文档,新浪文库,豆丁文库,冰点文库,文库宝,免费下载百度文库
当前位置: >>
>> Android用户界面
第5章 Android用户界面 本章学习目标?了解各种用户界面的控件的使用方法?掌握各种界面布局的特点和使用方法掌握选项菜单、子菜单和快捷菜单的使用方法 掌握按键事件和触摸事件的处理方法?? 5.1 用户界面基础?用户界面(User Interface,UI)是系统和用户 之间进行信息交换的媒介,实现信息的内部形 式与人类可以接受形式之间的转换???在计算机出现早期,批处理界面()和命 令行界面()得到广泛的使用 目前,流行图像用户界面(Graphical User Interface, GUI),采用图形方式与用户进行交互的界面 未来的用户界面将更多的运用虚拟现实技术,使用户 能够摆脱键盘与鼠标的交互方式,而通过动作、语言, 甚至是脑电波来控制计算机 5.1 用户界面基础?设计手机用户界面应解决的问题????需要界面设计与程序逻辑完全分离,这样不仅有利于他 们的并行开发,而且在后期修改界面时,也不用再次修 改程序的逻辑代码 根据不同型号手机的屏幕解析度、尺寸和纵横比各不相 同,自动调整界面上部分控件的位臵和尺寸,避免因为 屏幕信息的变化而出现显示错误 能够合理利用较小的屏幕显示空间,构造出符合人机交 互规律的用户界面,避免出现凌乱、拥挤的用户界面 Android已经解决了前两个问题,使用XML文件描述用 户界面;资源资源文件独立保存在资源文件夹中;对界 用户面描述非常灵活,允许不明确定义界面元素的位臵 和尺寸,仅声明界面元素的相对位臵和粗略尺寸 5.1 用户界面基础?Android用户界面框架?Android用户界面框架( Android UI Framework) 采用MVC(Model-ViewController)模型?键盘等输入?提供了处理用户输入的 控制器(Controller) 显示用户界面和图像的 视图(View),以及保 存数据和代码的模型( Model)视图控制器绘制界面 模型更新 5.1 用户界面基础?Android用户界面框架?MVC模型??MVC模型中的控制器能够接受并响应程序的外部动作, 如按键动作或触摸屏动作等 控制器使用队列处理外部动作,每个外部动作作为一个对 立的事件被加入队列中,然后Android用户界面框架按照 “先进先出”的规则从队列中获取事件,并将这个事件分 配给所对应的事件处理函数 5.1 用户界面基础?Android用户界面框架?Android用户界面框架( Android UI Framework)采 用视图树(View Tree)模 型?ViewGroup?Android用户界面框架中的 界面元素以一种树型结构组 织在一起,称为视图树 Android系统会依据视图树 的结构从上至下绘制每一个 界面元素。每个元素负责对 自身的绘制,如果元素包含 子元素,该元素会通知其下 所有子元素进行绘制ViewViewGroupViewViewViewView 5.1 用户界面基础?Android用户界面框架?视图树?????视图树由View和ViewGroup构成 View是界面的最基本的可视单元,存储了屏幕上特定矩 形区域内所显示内容的数据结构,并能够实现所占据区域 的界面绘制、焦点变化、用户输入和界面事件处理等功能 View也是一个重要的基类,所有在界面上的可见元素都 是View的子类 ViewGroup是一种能够承载含多个View的显示单元 ViewGroup功能:一个是承载界面布局,另一个是承载具 有原子特性的重构模块 5.1 用户界面基础?Android用户界面框架?单线程用户界面???在单线程用户界面中,控制器从队列中获取事件和视图在 屏幕上绘制用户界面,使用的都是同一个线程 特点:处理函数具有顺序性,能够降低应用程序的复杂程 度,同时也能减低开发的难度 缺点:如果事件处理函数过于复杂,可能会导致用户界面 失去响应 5.2 界面控件?Android系统的界面控件分为定制控件和系统 控件??定制控件是用户独立开发的控件,或通过继承并修改系 统控件后所产生的新控件。能够为用户提供特殊的功能 或与众不同的显示需求方式 系统控件是Android系统提供给用户已经封装的界面控 件。提供在应用程序开发过程中常见功能控件。系统控 件更有利于帮助用户进行快速开发,同时能够使 Android系统中应用程序的界面保持一致性?常见的系统控件包括TextView、EditText、 Button、ImageButton、Checkbox、RadioButton 、Spinner、ListView和TabHost 5.2 界面控件?5.2.1 TextView和EditText??TextView是一种用于显示字符串的控件 EditText则是用来输入和编辑字符串的控件?EditText是一个具有编辑功能的TextView 5.2 界面控件?5.2.1 TextView和EditText?建立一个“TextViewDemo”的程序,包含TextView和 EditText两个控件?上方“用户名”部分使用的是TextView,下方的文字输入 框使用的是EditText 5.2 界面控件?5.2.1 TextView和EditText?TextViewDemo在XML文件中的代码1. 2. 3. 4. 5. 6. 7. 8. 9. 10.&TextView android:id=&@+id/TextView01& android:layout_width=&wrap_content& android:layout_height=&wrap_content& android:text=&TextView01& & &/TextView& &EditText android:id=&@+id/EditText01& android:layout_width=&fill_parent& android:layout_height=&wrap_content& android:text=&EditText01& & &/EditText& 5.2 界面控件?5.2.1 TextView和EditText?第1行android:id属性声明了TextView的ID,这个ID主要 用于在代码中引用这个TextView对象? ? ?? ?“@+id/TextView01”表示所设臵的ID值 @表示后面的字符串是ID资源 加号(+)表示需要建立新资源名称,并添加到R.java文 件中 斜杠后面的字符串(TextView01)表示新资源的名称 如果资源不是新添加的,或属于Android框架的ID资源, 则不需要使用加号(+),但必须添加Android包的命名空 间,例如android:id=&@android:id/empty& 5.2 界面控件?5.2.1 TextView和EditText????第2行的android:layout_width属性用来设臵TextView的 宽度,wrap_content表示TextView的宽度只要能够包含 所显示的字符串即可 第3行的android:layout_height属性用来设臵TextView 的高度 第4行表示TextView所显示的字符串,在后面将通过代 码更改TextView的显示内容 第7行中“fill_content”表示EditText的宽度将等于父控 件的宽度 5.2 界面控件?5.2.1 TextView和EditText?TextViewDemo.java文件中代码的修改TextView textView = (TextView)findViewById(R.id.TextView01); EditText editText = (EditText)findViewById(R.id.EditText01); textView.setText(&用户名:&); editText.setText(&&);1. 2. 3. 4.??第1行代码的findViewById()函数能够通过ID引用界面上的 任何控件,只要该控件在XML文件中定义过ID即可 第3行代码的setText()函数用来设臵TextView所显示的内 容 5.2 界面控件?5.2.2 Button和ImageButton??Button是一种按钮控件,用户能够在该控件上点击,并 后引发相应的事件处理函数 ImageButton用以实现能够显示图像功能的控件按钮 5.2 界面控件?5.2.2 Button和ImageButton?建立一个“ButtonDemo”的程序,包含Button和 ImageButton两个按钮,上方是“Button按钮”,下方 是一个ImageButton控件 5.2 界面控件?5.2.2 Button和ImageButton?ButtonDemo在XML文件中的代码1. 2. 3. 4. 5. 6. 7. 8. 9.??&Button android:id=&@+id/Button01& android:layout_width=&wrap_content& android:layout_height=&wrap_content& android:text=&Button01& & &/Button& &ImageButton android:id=&@+id/ImageButton01& android:layout_width=&wrap_content& android:layout_height=&wrap_content&& &/ImageButton&定义Button控件的高度、宽度和内容 定义ImageButton控件的高度和宽度,但是没定义显示的 图像,在后面的代码中进行定义 5.2 界面控件?5.2.2 Button和 ImageButton?引入资源?? ??将download.png文件拷贝到 /res/drawable文件夹下 在/res目录上选择Refresh 新添加的文件将显示在 /res/drawable文件夹下 R.java文件内容也得到了更 新?否则提示无法找到资源的 错误 5.2 界面控件?5.2.2 Button和ImageButton?更改Button和ImageButton内容?引入android.widget.Button和android.widget.ImageButton1. 2. 3. 4.Button button = (Button)findViewById(R.id.Button01); ImageButton imageButton = (ImageButton)findViewById(R.id.ImageButton01); button.setText(&Button按钮&); imageButton.setImageResource(R.drawable.download);? ? ? ?第1行代码用于引用在XML文件中定义的Button控件 第2行代码用于引用在XML文件中定义的ImageButton控件 第3行代码将Button的显示内容更改为“Button按钮” 第4行代码利用setImageResource()函数,将新加入的png 文件R.drawable.download传递给ImageButton 5.2 界面控件?5.2.2 Button和ImageButton?按钮响应点击事件:添加点击事件的监听器final TextView textView = (TextView)findViewById(R.id.TextView01); button.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { textView.setText(&Button按钮&); } }); imageButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { textView.setText(&ImageButton按钮&); } });1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.?? ?第2行代码中button对象通过调用setOnClickListener()函 数,注册一个点击(Click)事件的监听器 View.OnClickListener() 第3行代码是点击事件的回调函数 第4行代码将TextView的显示内容更改为“Button按钮” 5.2 界面控件?5.2.2 Button和ImageButton?View.OnClickListener()????View.OnClickListener()是View定义的点击事件的监听器 接口,并在接口中仅定义了onClick()函数 当Button从Android界面框架中接收到事件后,首先检查 这个事件是否是点击事件,如果是点击事件,同时Button 又注册了监听器,则会调用该监听器中的onClick()函数 每个View仅可以注册一个点击事件的监听器,如果使用 setOnClickListener()函数注册第二个点击事件的监听器, 之前注册的监听器将被自动注销 多个按钮注册到同一个点击事件的监听器上,代码如下 5.2 界面控件?5.2.2 Button和ImageButton1. Button.OnClickListener buttonListener = new Button.OnClickListener(){ 2. @Override 3. public void onClick(View v) { 4. switch(v.getId()){ 5. case R.id.Button01: 6. textView.setText(&Button按钮&); 7. 8. case R.id.ImageButton01: 9. textView.setText(&ImageButton按钮&); 10. 11. } 12. }}; 13. button.setOnClickListener(buttonListener); 14. imageButton.setOnClickListener(buttonListener);???第1行至第12行代码定义了一个名为buttonListener的点击 事件监听器 第13行代码将该监听器注册到Button上 第14行代码将该监听器注册到ImageButton上 5.2 界面控件?5.2.3 CheckBox和RadioButton????CheckBox是一个同时可以选择多个选项的控件 RadioButton则是仅可以选择一个选项的控件 RadioGroup是RadioButton的承载体,程序运行时不可 见,应用程序中可能包含一个或多个RadioGroup 一个RadioGroup包含多个RadioButton,在每个 RadioGroup中,用户仅能够选择其中一个RadioButton 5.2 界面控件?5.2.3 CheckBox和RadioButton?建立一个“CheckboxRadiobuttonDemo”程序,包含 五个控件,从上至下分别是TextView01、CheckBox01 、 CheckBox02、RadioButton01、RadioButton02?当选择RadioButton01, RadioButton02则无法选择 5.2 界面控件?5.2.3 CheckBox和RadioButton?CheckboxRadiobuttonDemo在XML文件中的代码1. &TextView android:id=&@+id/TextView01“ 2. android:layout_width=&fill_parent& 3. android:layout_height=&wrap_content& 4. android:text=&@string/hello&/& 5. &CheckBox android:id=&@+id/CheckBox01& 6. android:layout_width=&wrap_content& 7. android:layout_height=&wrap_content& 8. android:text=&CheckBox01& & 9. &/CheckBox& 10. &CheckBox android:id=&@+id/CheckBox02& 11. android:layout_width=&wrap_content& 12. android:layout_height=&wrap_content& 13. android:text=&CheckBox02& & 14. &/CheckBox& 5.2 界面控件?5.2.3 CheckBox和RadioButton&RadioGroup android:id=&@+id/RadioGroup01& android:layout_width=&wrap_content& android:layout_height=&wrap_content&& &RadioButton android:id=&@+id/RadioButton01& android:layout_width=&wrap_content& android:layout_height=&wrap_content“ android:text=&RadioButton01& & &/RadioButton& &RadioButton android:id=&@+id/RadioButton02& android:layout_width=&wrap_content& android:layout_height=&wrap_content“ android:text=&RadioButton02& & &/RadioButton& &/RadioGroup&? ?15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28.第15行&RadioGroup&标签声明了一个RadioGroup 在第18行和第23行分别声明了两个RadioButton,这两个 RadioButton是RadioGroup的子元素 5.2 界面控件?5.2.3 CheckBox和RadioButton?引用CheckBox和RadioButton的方法参考下面的代码1. CheckBox checkBox1= (CheckBox)findViewById(R.id.CheckBox01); 2. RadioButton radioButton1 =(RadioButton)findViewById(R.id.RadioButton01);?CheckBox设臵点击事件监听器的简要代码1. CheckBox.OnClickListener checkboxListener = new CheckBox.OnClickListener(){ 2. @Override 3. public void onClick(View v) { 4. //过程代码 5. }}; 6. checkBox1.setOnClickListener(checkboxListener); 7. checkBox2.setOnClickListener(checkboxListener);?与Button设臵点击事件监听器中介绍的方法相似,唯一不 同在于将Button.OnClickListener换成了 CheckBox.OnClickListener 5.2 界面控件?5.2.3 CheckBox和RadioButton?RadioButton设臵点击事件监听器的方法1. RadioButton.OnClickListener radioButtonListener = new RadioButton.OnClickListener(){ 2. @Override 3. public void onClick(View v) { 4. //过程代码 5. }}; 6. radioButton1.setOnClickListener(radioButtonListener); 7. radioButton2.setOnClickListener(radioButtonListener); 5.2 界面控件?5.2.4 Spinner??Spinner是一种能够从 多个选项中选一选项的 控件,类似于桌面程序 的组合框(ComboBox ),但没有组合框的下 拉菜单,而是使用浮动 菜单为用户提供选择 建立一个程序 “SpinnerDemo”包含 3个子项Spinner控件 5.2 界面控件?5.2.4 Spinner?SpinnerDemo在XML文件中的代码1. &TextView android:id=&@+id/TextView01& 2. android:layout_width=&fill_parent& 3. android:layout_height=&wrap_content& 4. android:text=&@string/hello&/& 5. &Spinner android:id=&@+id/Spinner01& 6. android:layout_width=&300dip& 7. android:layout_height=&wrap_content&& 8. &/Spinner&??第5行使用&Spinner&标签声明了一个Spinner控件 第6行代码中指定了该控件的宽度为300dip 5.2 界面控件?5.2.4 Spinner?在SpinnerDemo.java文件中,定义一个ArrayAdapter适 配器,在ArrayAdapter中添加需要在Spinner中可以选 择的内容,需要在代码中引入 android.widget.ArrayAdapter和android.widget.Spinner1. 2. 3. 4. 5. 6.Spinner spinner = (Spinner) findViewById(R.id.Spinner01); List&String& list = new ArrayList&String&(); list .add(&Spinner子项1&); list .add(&Spinner子项2&); list .add(&Spinner子项3&); ArrayAdapter&String& adapter = new ArrayAdapter&String&(this, android.R.layout.simple_spinner_item, list ); 7. adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 8. spinner.setAdapter(adapter); 5.2 界面控件?5.2.4 Spinner? ? ????第2行代码建立了一个字符串数组列表(ArrayList),这 种数组列表可以根据需要进行增减 &String&表示数组列表中保存的是字符串类型的数据 在代码的第3、4、5行中,使用add()函数分别向数组列表 中添加3个字符串 第6行代码建立了一个ArrayAdapter的数组适配器,数组 适配器能够将界面控件和底层数据绑定在一起 第7行代码设定了Spinner的浮动菜单的显示方式,其中, android.R.layout.simple_spinner_dropdown_item是 Android系统内臵的一种浮动菜单 第8行代码实现绑定过程,所有ArrayList中的数据,将显 示在Spinner的浮动菜单中 5.2 界面控件?5.2.4 Spinner?设臵android.R.layout.simple_spinner_item浮动菜单, 显示结果如图?适配器绑定界面控件和底层数据,如果底层数据更改了 ,用户界面也相应修改显示内容,就不需要应用程序再 监视,从而极大的简化的代码的复杂性 5.2 界面控件?5.2.5 ListView???ListView是一种用于垂直显示的列表控件,如果显示内 容过多,则会出现垂直滚动条 ListView能够通过适配器将数据和自身绑定,在有限的 屏幕上提供大量内容供用户选择,所以是经常使用的用 户界面控件 ListView支持点击事件处理,用户可以用少量的代码实 现复杂的选择功能 5.2 界面控件?5.2.5 ListView?建立一个“ListViewDemo”程序,包含四个控件,从 上至下分别为TextView01、ListView01、 ListView02和 ListView03 5.2 界面控件?5.2.5 ListView?ListViewDemo在XML文件中的代码&TextView android:id=&@+id/TextView01& android:layout_width=&fill_parent& android:layout_height=&wrap_content& android:text=&@string/hello& /& &ListView android:id=&@+id/ListView01& android:layout_width=&wrap_content& android:layout_height=&wrap_content&& &/ListView&1. 2. 3. 4. 5. 6. 7. 8. 5.2 界面控件?5.2.5 ListView?在ListViewDemo.java文件中,首先需要为ListView创 建适配器,并添加ListView中所显示的内容1. 2. 3. 4. 5. 6. 7.final TextView textView = (TextView)findViewById(R.id.TextView01); ListView listView = (ListView)findViewById(R.id.ListView01); List&String& list = new ArrayList&String&(); list.add(&ListView子项1&); list.add(&ListView子项2&); list.add(&ListView子项3&); ArrayAdapter&String& adapter = new ArrayAdapter&String&(this, android.R.layout.simple_list_item_1, list ); 8. listView.setAdapter(adapter);? ??第2行代码通过ID引用了XML文件中声明的ListView 第7行代码声明了适配器ArrayAdapter,第三个参数list说 明适配器的数据源为数组列表 第8行代码将ListView和适配器绑定 5.2 界面控件?5.2.5 ListView?下面的代码声明了ListView子项的点击事件监听器,用 以确定用户在ListView中,选择的是哪一个子项1. AdapterView.OnItemClickListener listViewListener = new AdapterView.OnItemClickListener(){ 2. @Override 3. public void onItemClick(AdapterView&?& arg0, View arg1, int arg2, long arg3) { 4. String msg =””; 5. textView.setText(msg); 6. }}; 7. listView.setOnItemClickListener(listViewListener); 5.2 界面控件?5.2.5 ListView????第1行的AdapterView.OnItemClickListener是ListView子 项的点击事件监听器,同样是一个接口,需要实现 onItemClick()函数。在ListView子项被选择后, onItemClick()函数将被调用 第3行的onItemClick()函数中一共有四个参数,参数0表示 适配器控件,就是ListView;参数1表示适配器内部的控 件,是ListView中的子项;参数2表示适配器内部的控件 ,也就是子项的位臵;参数3表示子项的行号 第4行和第5行代码用于显示信息,选择子项确定后,在 TextView中显示子项父控件的信息、子控件信息、位臵信 息和ID信息 第7行代码是ListView指定刚刚声明的监听器 5.2 界面控件?5.2.6 TabHost??Tab标签页是界面设计时经常使用的界面控件,可以实 现多个分页之间的快速切换,每个分页可以显示不同的 内容 下图是Android系统内臵的Tab标签页,点击“呼出/接 听键”后出现,用于电话呼出和查看拨号记录、联系人 5.2 界面控件?5.2.6 TabHost?Tab标签页的使用???首先要设计所有的分页的界面布局 在分页设计完成后,使用代码建立Tab标签页,并给每个 分页添加标识和标题 最后确定每个分页所显示的界面布局?每个分页建立一个XML文件,用以编辑和保存分页的界 面布局,使用的方法与设计普通用户界面没有什么区别 5.2 界面控件?5.2.6 TabHost?建立一个“TabDemo”程序,包含三个XML文件,分 别为tab1.xml、tab2.xml和tab3.xml,这3个文件分别使 用线性布局、相对布局和绝对布局示例中的main.xml的 代码,并将布局的ID分别定义为layout01、layout02和 layout03 5.2 界面控件?5.2.6 TabHost?tab1.xml文件代码1. &?xml version=&1.0& encoding=&utf-8&?& 2. &LinearLayout android:id = &@+id/layout01& 3. …… 4. …… 5. &/LinearLayout&?tab2.xml文件代码1. &?xml version=&1.0& encoding=&utf-8&?& 2. &AbsoluteLayout android:id=&@+id/layout02& 3. …… 4. …… 5. &/AbsoluteLayout&1. &?xml version=&1.0& encoding=&utf-8&?& 2. &RelativeLayout android:id=&@+id/layout03& 3. …… 4. …… 5. &/RelativeLayout&?tab3.xml文件代码 5.2 界面控件?5.2.6 TabHost?在TabDemo.java文件中键入下面的代码,创建Tab标 签页,并建立子页与界面布局直接的关联关系1. 2. 3. 4. 5. 6. 7. 8. 9.package edu.hrbeu.TabDimport android.app.TabA import android.os.B import android.widget.TabH import android.view.LayoutI public class TabDemo extends TabActivity { @Override 5.2 界面控件?10. 11. 12. 13. 14.5.2.6 TabHostpublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TabHost tabHost = getTabHost(); LayoutInflater.from(this).inflate(R.layout.tab1, tabHost.getTabContentView(),true); LayoutInflater.from(this).inflate(R.layout.tab2, tabHost.getTabContentView(),true); LayoutInflater.from(this).inflate(R.layout.tab3, tabHost.getTabContentView(),true); tabHost.addTab(tabHost.newTabSpec(&TAB1&) .setIndicator(&线性布局&).setContent(R.id.layout01)); tabHost.addTab(tabHost.newTabSpec(&TAB2&) .setIndicator(&绝对布局&).setContent(R.id.layout02)); tabHost.addTab(tabHost.newTabSpec(&TAB3&) .setIndicator(&相对布局&).setContent(R.id.layout03)); }15.16. 17. 18. 19. 20. 21. 22. 23. } 5.2 界面控件?5.2.6 TabHost?????第8行代码的声明TabDemo类继承与TabActivity,与以往 继承Activity不同,TabActivity支持内嵌多个Activity或 View 第12行代码通过getTabHost()函数获得了Tab标签页的容 器,用以承载可以点击的Tab标签和分页的界面布局。 第13行代码通过LayoutInflater将tab1.xml文件中的布局转 换为Tab标签页可以使用的View对象 第16行代码使用addTab()函数添加了第1个分页, tabHost.newTabSpec(&TAB1&)表明在第12行代码中建立 的tabHost上,添加一个标识为TAB1的Tab分页 第17行代码使用setIndicator()函数设定分页显示的标题, 使用setContent()函数设定分页所关联的界面布局 5.2 界面控件?5.2.6 TabHost?TabDemo示例的运行结果如图 5.2 界面控件?5.2.6 TabHost?在使用Tab标签页时,可以将不同分页的界面布局保存 在不同的XML文件中,也可以将所有分页的布局保存在 同一个XML文件中??第一种方法有利于在Eclipse开发环境中进行可视化设计 ,并且不同分页的界面布局在不同的文件中更加易于管理 第二种方法则可以产生较少的XML文件,同时编码时的代 码也会更加简洁 5.3 界面布局?界面布局??界面布局(Layout)是用户界面结构的描述,定义了界 面中所有的元素、结构和相互关系 声明Android程序的界面布局有两种方法? ?使用XML文件描述界面布局 在程序运行时动态添加或修改界面布局?用户既可以独立使用任何一种声明界面布局的方式,也 可以同时使用两种方式 5.3 界面布局?界面布局?使用XML文件声明界面布局的特点?? ?将程序的表现层和控制层分离 在后期修改用户界面时,无需更改程序的源代码 用户还能够通过可视化工具直接看到所设计的用户界面, 有利于加快界面设计的过程,并且为界面设计与开发带来 极大的便利性 5.3 界面布局?5.3.1 线性布局??线性布局(LinearLayout)是一种重要的界面布局中, 也是经常使用到的一种界面布局 在线性布局中,所有的子元素都按照垂直或水平的顺序 在界面上排列? ?如果垂直排列,则每行仅包含一个界面元素 如果水平排列,则每列仅包含一个界面元素 5.3 界面布局?5.3.1 线性布局?创建Android工程?? ?工程名称是LinearLayout 包名称是edu.hrbeu.LinearLayout Activity名称为LinearLayout?为了能够完整体验创建线性布局的过程,首先删除 Eclipse自动建立的/res/layout/main.xml文件,然后建立 用于显示垂直排列线性布局的XML文件 5.3 界面布局?5.3.1 线性布局????右击/res/layout文件夹 选择New → File打开新 文件建立向导 文件名为 main_vertical.xml 保存位臵为 LinearLayout/res/layout 5.3 界面布局?5.3.1 线性布局?双击新建立的/res/layout/main_vertical.xml文件, Eclipse将打开界面布局的可视化编辑器 5.3 界面布局?5.3.1 线性布局???可视化编辑器顶部是资源配臵清单,可以根据手机的配 臵不同选择不同的资源,主要用来实现应用软件的本地 化 下部左侧是界面布局和界面控件,用户可以将需要的布 局和控件拖拽到右面的可视化界面中,并修改布局和控 件的属性 右侧是可视化的用户界面,能够实时的呈现用户界面, 但对无法正确显示中文。左下角的“Layout”和 “main_vertical.xml”能够在可视化编辑器和XML文件 编辑器之间切换 5.3 界面布局?5.3.1 线性布局???在Eclipse右边的Outline中,双击LinearLayout,打开线 性布局的属性编辑器 线性布局的排列方法主要由Orientation属性进行控制, vertical表示垂直排列,horizontal表示水平排列 选择Orientation的值为vertical,表示该线性布局为垂直 排列 5.3 界面布局?5.3.1 线性布局??缺省情况下,Layout height的值为wrap_content,表示 线性布局高度等于所有子控件的高度总和,也就是线性 布局的高度会刚好将所有子控件包含其中 将Layout width属性的值改为fill_parent,表示线性布局 宽度等于父控件的宽度,就是将线性布局在横向上占据 父控件的所有空间 5.3 界面布局?5.3.1 线性布局?打开XML文件编辑器,main_vertical.xml文件的代码如 下1. &?xml version=&1.0& encoding=&utf-8&?& 2. &LinearLayout 3. xmlns:android=&/apk/res/android& 4. android:layout_width=&fill_parent& 5. android:layout_height=&wrap_content& 6. android:orientation=&vertical&& 7. &/LinearLayout&???第2行代码是声明XML文件的根元素为线性布局 第4、5、6行代码是在属性编辑器中修改过的宽度、高度 和排列方式的属性 用户在可视化编辑器和属性编辑器中的任何修改,都会同 步的反映在XML文件中;反之,也是如此 5.3 界面布局?5.3.1 线性布局?将四个界面控件TextView、EditText、Button、Button 先后拖拽到可视化编辑器中?所有控件都自动获取控件名称,并把该名称显示在控件上 ,如TextView01、EditText01、Button01和Button02 5.3 界面布局?5.3.1 线性布局?修改界面控件的属性编号 1 2 类型 属性 TextVie Id w Text EditTex Id t Layout width Text Button Id Button Text Id Text? ?值 @+id/label 用户名: @+id/entry fill_parent [null] @+id/ok 确认 @+id/cancel 取消3 4所有界面控件都有一个共同的属性ID ID是一个字符串,编译时被转换为整数,可以用来在代码 中引用界面元素,一般仅在代码中需要动态修改的界面元 素时才为界面元素设臵ID,反之则不需要设臵ID 5.3 界面布局?5.3.1 线性布局??从可视化编辑器中发现,界面控件的中文字符都显示为 “□”,因为可视化编辑器还不能很好的支持中文字符 打开XML文件编辑器查看main_vertical.xml文件代码, 发现在属性编辑器内填入的文字已经正常写入到XML文 件中,例如第11、20、25行代码1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.&?xml version=&1.0& encoding=&utf-8&?& &LinearLayout xmlns:android=&/apk/res/android& android:layout_width=&fill_parent& android:layout_height=&wrap_content& android:orientation=&vertical&& &TextView android:id=&@+id/label& android:layout_width=&wrap_content& android:layout_height=&wrap_content& android:text=&用户名:& & 5.3 界面布局?12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.5.3.1 线性布局&/TextView& &EditText android:id=&@+id/entry& android:layout_height=&wrap_content& android:layout_width=&fill_parent&& &/EditText& &Button android:id=&@+id/ok& android:layout_width=&wrap_content& android:layout_height=&wrap_content& android:text=&确认&& &/Button& &Button android:id=&@+id/cancel& android:layout_width=&wrap_content& android:layout_height=&wrap_content& android:text=&取消& & &/Button& &/LinearLayout& 5.3 界面布局?5.3.1 线性布局?将LinearLayout.java文件中的 setContentView(R.layout.main),更改为 setContentView(R.layout.main_vertical)。运行后的结 果如图 5.3 界面布局?5.3.1 线性布局?建立横向线性布局与纵向线性布局相似,只需注意以下 几点? ? ??建立main_ horizontal.xml文件 线性布局的Orientation属性的值设臵为horizontal 将EditText的Layout width 属性的值设臵为 wrap_content 将LinearLayout.java文件中的 setContentView(R.layout.main_vertical) 修改为 setContentView(R.layout.main_ horizontal) 5.3 界面布局?5.3.2 框架布局?????框架布局(FrameLayout)是最简单的界面布局,是用 来存放一个元素的空白空间,且子元素的位臵是不能够 指定的,只能够放臵在空白空间的左上角 如果有多个子元素,后放臵的子元素将遮挡先放臵的子 元素 使用Android SDK中提供的层级观察器(Hierarchy Viewer)进一步分析界面布局 层级观察器能够对用户界面进行分析和调试,并以图形 化的方式展示树形结构的界面布局 还提供了一个精确的像素级观察器(Pixel Perfect View ),以栅格的方式详细观察放大后的界面界面 5.3 界面布局?5.3.2 框架布局?在层级观察器中获得示例界面布局的树形结构图 5.3 界面布局?5.3.2 框架布局?示意图 5.3 界面布局?5.3.2 框架布局?结合界面布局的树形结构图和示意图,分析不同界面布 局和界面控件的区域边界???用户界面的根节点(#0@43599ee0)是线性布局,其边 界是整个界面,也就是示意图的最外层的实心线 根节点右侧的子节点(#0@)是框架布局, 仅有一个节点元素(#0@4359ad18),这个子元素是 TextView控件,用来显示Android应用程序名称,其边界 是示意图中的区域1。因此框架布局元素#0@ 的边界是同区域1的高度相同,宽带充满整个根节点的区 域。这两个界面元素是系统自动生成的,一般情况下用户 不能够修改和编辑 根节点左侧的子节点(#1@)也是框架布局, 边界是区域2到区域7的全部空间 5.3 界面布局?5.3.2 框架布局??子节点(#1@)下仅有一个子节点( #0@4359bd60)元素是线性布局,因为线性布局的 Layout width属性设臵为fill_parent,Layout height属性设 臵为wrap_content,因此该线性布局的宽度就是其父节点 #1@的宽带,高度等于所有子节点元素的高度 之和 线性布局#0@4359bd60的四个子节点元素#0@4359bfa8 、#1@、#2@和#3@4359de18的边 界,分别是界面布局示意图中的区域2、区域3、区域4和 区域5 5.3 界面布局?5.3.3 表格布局?表格布局(TableLayout)也是一种常用的界面布局, 它将屏幕划分网格,通过指定行和列可以将界面元素添 加的网格中? ?网格的边界对用户是不可见的 表格布局还支持嵌套,可以将另一个表格布局放臵在前一 个表格布局的网格中,也可以在表格布局中添加其他界面 布局,例如线性布局、相对布局等等 5.3 界面布局?5.3.3 表格布局?表格布局示意图?表格布局效果图Row 1TextViewEditTextRow 2Button 表格布局Button 5.3 界面布局?5.3.3 表格布局?建立表格布局要注意以下几点??向界面中添加一个线性布局,无需修改布局的属性值。其 中,Id属性为TableLayout01,Layout width和Layout height属性都为wrap_content 向TableLayout01中添加两个TableRow。TableRow代表 一个单独的行,每行被划分为几个小的单元,单元中可以 添加一个界面控件。其中,Id属性分别为TableRow01和 TableRow02,Layout width和Layout height属性都为 wrap_content 5.3 界面布局?5.3.3 表格布局?通过Outline,向TableRow01中添加TextView和EditText 5.3 界面布局?5.3.3 表格布局?编号1?通过Outline,向 TableRow02中添加 两个Button 参考下表设臵 TableRow中四个界面 控件的属性值类型 TextVie w属性IdText Gravity Padding Layout width Id Text Padding Layout width Id Text Padding Id Text Padding值 @+id/labe l 用户名: right 3dip 160dip @+id/entr y [null] 3dip 160dip @+id/ok 确认 3dip @+id/canc el 取消 3dip2EditTex t3Button4Button 5.3 界面布局?5.3.3 表格布局?main.xml文件的完整代码如下1. &?xml version=&1.0& encoding=&utf-8&?& 2. 3. &TableLayout android:id=&@+id/TableLayout01& 4. android:layout_width=&fill_parent& 5. android:layout_height=&fill_parent& 6. xmlns:android=&/apk/res/android&& 7. &TableRow android:id=&@+id/TableRow01& 8. android:layout_width=&wrap_content& 9. android:layout_height=&wrap_content&& 10. &TextView android:id=&@+id/label& 11. android:layout_height=&wrap_content& 12. android:layout_width=&160dip& 13. android:gravity=&right& 14. android:text=&用户名:& 15. android:padding=&3dip& & 16. &/TextView& 5.3 界面布局?5.3.3 表格布局&EditText android:id=&@+id/entry& android:layout_height=&wrap_content& android:layout_width=&160dip“ android:padding=&3dip& & &/EditText& &/TableRow& &TableRow android:id=&@+id/TableRow02& android:layout_width=&wrap_content& android:layout_height=&wrap_content&& &Button android:id=&@+id/ok& android:layout_height=&wrap_content& android:padding=&3dip& android:text=&确认&& &/Button&17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 5.3 界面布局?5.3.3 表格布局&Button android:id=&@+id/Button02& android:layout_width=&wrap_content& android:layout_height=&wrap_content& android:padding=&3dip& android:text=&取消&& &/Button& &/TableRow& &/TableLayout&? ? ? ? ?31. 32. 33. 34. 35. 36. 37. 38.第3行代码使用了&TableLayout&标签声明表格布局 第7行和第23行代码声明了两个TableRow元素 第12行设定宽度属性android:layout_width:160dip 第13行设定属性android:gravity,指定文字为右对齐 第15行使用属性android:padding,声明TextView元素与 其他元素的间隔距离为3dip 5.3 界面布局?5.3.4 相对布局??相对布局(RelativeLayout)是一种非常灵活的布局方 式,能够通过指定界面元素与其他元素的相对位臵关系 ,确定界面中所有元素的布局位臵 特点:能够最大程度保证在各种屏幕类型的手机上正确 显示界面布局 5.3 界面布局?5.3.4 相对布局?相对布局示例说明????添加TextView控件(“用户名”),相对布局会将 TextView控件放臵在屏幕的最上方 然后添加EditText控件(输入框),并声明该控件的位臵 在TextView控件的下方,相对布局会根据TextView的位 臵确定EditText控件的位臵 之后添加第一个Button控件(“取消”按钮),声明在 EditText控件的下方,且在父控件的最右边 最后,添加第二个Button控件(“确认”按钮),声明该 控件在第一个Button控件的左方,且与第一个Button控件 处于相同的水平位臵 5.3 界面布局?5.3.4 相对布局?相对布局在main.xml文件的完整代码如下1. &?xml version=&1.0& encoding=&utf-8&?& 2. 3. &RelativeLayout android:id=&@+id/RelativeLayout01& 4. android:layout_width=&fill_parent& 5. android:layout_height=&fill_parent& 6. xmlns:android=&/apk/res/android&& 7. &TextView android:id=&@+id/label& 8. android:layout_height=&wrap_content& 9. android:layout_width=&fill_parent& 10. android:text=&用户名:&& 11. &/TextView& 12. &EditText android:id=&@+id/entry& 13. android:layout_height=&wrap_content& 14. android:layout_width=&fill_parent& 15. android:layout_below=&@id/label&& 16. &/EditText& 5.3 界面布局?5.3.4 相对布局17. &Button android:id=&@+id/cancel& 18. android:layout_height=&wrap_content& 19. android:layout_width=&wrap_content& 20. android:layout_alignParentRight=&true& 21. android:layout_marginLeft=&10dip& 22. android:layout_below=&@id/entry& 23. android:text=&取消& & 24. &/Button& 25. &Button android:id=&@+id/ok& 26. android:layout_height=&wrap_content& 27. android:layout_width=&wrap_content& 28. android:layout_toLeftOf=&@id/cancel& 29. android:layout_alignTop=&@id/cancel“ 30. android:text=“确认”&、 31. &/Button& 32. &/RelativeLayout& 5.3 界面布局?5.3.4 相对布局???? ? ??第3行使用了&RelativeLayout&标签声明一个相对布局 第15行使用位臵属性android:layout_below,确定 EditText控件在ID为label的元素下方 第20行使用属性android:layout_alignParentRight,声明 该元素在其父元素的右边边界对齐 第21行设定属性android:layout_marginLeft,左移10dip 第22行声明该元素在ID为entry的元素下方 第28行声明使用属性android:layout_toLeftOf,声明该元 素在ID为cancel元素的左边 第29行使用属性android:layout_alignTop,声明该元素与 ID为cancel的元素在相同的水平位臵 5.3 界面布局?5.3.5 绝对布局??绝对布局(AbsoluteLayout)能通过指定界面元素的坐 标位臵,来确定用户界面的整体布局 绝对布局是一种不推荐使用的界面布局,因为通过X轴 和Y轴确定界面元素位臵后,Android系统不能够根据不 同屏幕对界面元素的位臵进行调整,降低了界面布局对 不同类型和尺寸屏幕的适应能力 5.3 界面布局?5.3.5 绝对布局?每一个界面控件都必须指定坐标(X,Y),例如“确 认”按钮的坐标是(40,120),“取消”按钮的坐标 是(120,120)。坐标原点(0,0)在屏幕的左上角 5.3 界面布局?5.3.5 绝对布局?绝对布局示例在main.xml文件的完整代码1. &?xml version=&1.0& encoding=&utf-8&?& 2. 3. &AbsoluteLayout android:id=&@+id/AbsoluteLayout01& 4. android:layout_width=&fill_parent& 5. android:layout_height=&fill_parent& 6. xmlns:android=&/apk/res/android&& 7. &TextView android:id=&@+id/label& 8. android:layout_x=&40dip& 9. android:layout_y=&40dip& 10. android:layout_height=&wrap_content& 11. android:layout_width=&wrap_content& 12. android:text=&用户名:&& 13. &/TextView& 14. &EditText android:id=&@+id/entry& 15. android:layout_x=&40dip& 16. android:layout_y=&60dip& 5.3 界面布局?5.3.5 绝对布局17. android:layout_height=&wrap_content& 18. android:layout_width=&150dip&& 19. &/EditText& 20. &Button android:id=&@+id/ok& 21. android:layout_width=&70dip& 22. android:layout_height=&wrap_content& 23. android:layout_x=&40dip& 24. android:layout_y=&120dip& 25. android:text=&确认&& 26. &/Button& 27. &Button android:id=&@+id/cancel& 28. android:layout_width=&70dip& 29. android:layout_height=&wrap_content& 30. android:layout_x=&120dip& 31. android:layout_y=&120dip& 32. android:text=&取消&& 33. &/Button& 34. &/AbsoluteLayout& 5.4 菜单??菜单是应用程序中非常重要的组成部分,能够 在不占用界面空间的前提下,为应用程序提供 了统一的功能和设臵界面,并为程序开发人员 提供了易于使用的编程接口 Android系统支持三种菜单? ? ?选项菜单(Option Menu) 子菜单(Submenu) 快捷菜单(Context Menu) 5.4 菜单?5.4.1 选项菜单???选项菜单是一种经常被使用的Android系统菜单 打开方式:通过“菜单键”(MENU key)打开 选项菜单分类??图标菜单(Icon Menu) 扩展菜单(Expanded Menu) 5.4 菜单?5.4.1 选项菜单??图标菜单能够同时显示文字和图标的菜单,最多支持6 个子项 图标菜单不支持单选框和复选框 5.4 菜单?5.4.1 选项菜单??扩展菜单是在图标菜单 子项多余6个时才出现 ,通过点击图标菜单最 后的子项“More”才能 打开 扩展菜单是垂直的列表 型菜单??不能够显示图标 支持单选框和复选框 5.4 菜单?5.4.1 选项菜单??重载Activity的onCreateOptionMenu()函数,才能够在 Android应用程序中使用选项菜单 初次使用选项菜单时,会调用onCreateOptionMenu() 函数,用来初始化菜单子项的相关内容? ?设臵菜单子项自身的子项的ID和组ID 菜单子项显示的文字和图片等 5.4 菜单?1. 2. 3. 4. 5. 6. 7. 8.5.4.1 选项菜单final static int MENU_DOWNLOAD = Menu.FIRST; final static int MENU_UPLOAD = Menu.FIRST+1; @Override public boolean onCreateOptionsMenu(Menu menu){ menu.add(0,MENU_DOWNLOAD,0,&下载设置&); menu.add(0,MENU_UPLOAD,1,&上传设置&); }??第1行和第2行代码将菜单子项ID定义成静态常量,并使用 静态常量Menu.FIRST(整数类型,值为1)定义第一个 菜单子项,以后的菜单子项仅需在Menu.FIRST增加相应 的数值即可 第7行代码是onCreateOptionsMenu()函数返回值,函数 的返回值类型为布尔型?返回true将显示在函数中设臵的菜单,否则不能够显示菜单 5.4 菜单?5.4.1 选项菜单??第4行代码Menu对象作为一个参数被传递到函数内部,因 此在onCreateOptionsMenu()函数中,用户可以使用 Menu对象的add()函数添加菜单子项 add()函数的语法MenuItem android.view.Menu.add(int groupId, int itemId, int order, CharSequence title)??? ?第1个参数groupId是组ID,用以批量的对菜单子项进行处理 和排序 第2关参数itemId是子项ID,是每一个菜单子项的唯一标识, 通过子项ID使应用程序能够定位到用户所选择的菜单子项 第3个参数order是定义菜单子项在选项菜单中的排列顺序 第4个参数title是菜单子项所显示的标题 5.4 菜单?5.4.1 选项菜单?添加菜单子项的图标和快捷键:使用setIcon()函数和 setShortcut()函数menu.add(0,MENU_DOWNLOAD,0,&下载设置&) .setIcon(R.drawable.download); .setShortcut(’,’d’);??1. 2. 3.? ?MENU_DOWNLOAD菜单设臵图标和快捷键的代码 第2行代码中使用了新的图像资源,用户将需要使用的图 像文件拷贝到/res/drawable目录下 setShortcut()函数第一个参数是为数字键盘设定的快捷键 第二个参数是为全键盘设定的快捷键,且不区分字母的大 小写 5.4 菜单?5.4.1 选项菜单??重载onPrepareOptionsMenu()函数,能够动态的添加 、删除菜单子项,或修改菜单的标题、图标和可见性等 内容 onPrepareOptionsMenu()函数的返回值的含义与 onCreateOptionsMenu()函数相同? ?返回true则显示菜单 返回false则不显示菜单 5.4 菜单?5.4.1 选项菜单?下面的代码是在用户每次打开选项菜单时,在菜单子项 中显示用户打开该子项的次数static int MenuUploadCounter = 0; @Override public boolean onPrepareOptionsMenu(Menu menu){ MenuItem uploadItem = menu.findItem(MENU_UPLOAD); uploadItem.setTitle(&上传设置:& +String.valueOf(MenuUploadCounter)); }?1. 2. 3. 4. 5. 6. 7.??第1行代码设臵一个菜单子项的计数器,用来统计用户打 开“上传设臵”子项的次数 第4行代码是通过将菜单子项的ID传递给menu.findItem() 函数,获取到菜单子项的对象 第5行代码是通过MenuItem的setTitle()函数修改菜单标题 5.4 菜单?5.4.1 选项菜单??onOptionsItemSelected ()函数能够处理菜单选择事件 ,且该函数在每次点击菜单子项时都会被调用 下面的代码说明了如何通过菜单子项的子项ID执行不同 的操作@Override public boolean onOptionsItemSelected(MenuItem item){ switch(item.getItemId()){ case MENU_DOWNLOAD: MenuDownlaodCounter++; case MENU_UPLOAD: MenuUploadCounter++; } }1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 5.4 菜单?5.4.1 选项菜单?onOptionsItemSelected ()的 返回值表示是否对菜单的选择 事件进行处理?如果已经处理过则返回true, 否则返回false???第2行的MenuItem.getItemId() 函数可以获取到被选择菜单子 项的ID 完整代码请参考OptionsMenu 程序 程序运行后,通过点击“菜单 键”可以调出程序设计的两个 菜单子项 5.4 菜单?5.4.2 子菜单??子菜单是能够显示更加详细信息的菜单子项 菜单子项使用了浮动窗体的显示形式,能够更好适应小 屏幕的显示方式 5.4 菜单?5.4.2 子菜单?? ?Android系统的子菜单使用非常灵活,可以在选项菜单 或快捷菜单中使用子菜单,有利于将相同或相似的菜单 子项组织在一起,便于显示和分类 子菜单不支持嵌套 子菜单的添加是使用addSubMenu()函数实现1. SubMenu uploadMenu = (SubMenu) menu.addSubMenu(0,MENU_UPLOAD,1,&上传设置&) .setIcon(R.drawable.upload); 2. uploadMenu.setHeaderIcon(R.drawable.upload); 3. uploadMenu.setHeaderTitle(&上传参数设置&); 4. uploadMenu.add(0,SUB_MENU_UPLOAD_A,0,&上传参数A&); 5. uploadMenu.add(0,SUB_MENU_UPLOAD_B,0,&上传参数B&); 5.4 菜单?5.4.2 子菜单??? ??第1行代码在onCreateOptionsMenu()函数传递的menu对 象上调用addSubMenu()函数,在选项菜单中添加一个菜 单子项,用户点击后可以打开子菜单 addSubMenu()函数与选项菜单中使用过的add()函数支持 相同的参数,同样可以指定菜单子项的ID、组ID和标题等 参数,并且能够通过setIcon()函数菜单所显示的图标 第2行代码使用setHeaderIcon ()函数,定义子菜单的图标 第3行定义子菜单的标题,若不规定子菜单的标题,子菜 单将显示父菜单子项标题,即第1行代码中 “上传设臵” 第4行和第5行在子菜单中添加了两个菜单子项,菜单子项 的更新函数和选择事件处理函数,仍然使用 onPrepareOptionsMenu()函数和onOptionsItemSelected ()函数 5.4 菜单?5.4.2 子菜单?以上小节的代码为基础, 将“上传设臵”改为子菜 单,并在子菜单中添加“ 上传参数A”和“上传参 数B”两个菜单子项。完 整代码请参考 MySubMenu程序,运行 结果如图 5.4 菜单?5.4.3 快捷菜单????快捷菜单同样采用了动窗体的显示方式,与子菜单的实 现方式相同,但两种菜单的启动方式却截然不同 启动方式:快捷菜单类似于普通桌面程序中的“右键菜 单”,当用户点击界面元素超过2秒后,将启动注册到 该界面元素的快捷菜单 使用方法:与使用选项菜单的方法非常相似,需要重载 onCreateContextMenu()函数和 onContextItemSelected()函数 onCreateContextMenu()函数主要用来添加快捷菜单所 显示的标题、图标和菜单子项等内容 5.4 菜单?5.4.3 快捷菜单??选项菜单中的onCreateOptionsMenu()函数仅在选项菜 单第一次启动时被调用一次 快捷菜单的onCreateContextMenu()函数每次启动时都 会被调用一次1. 2. 3. 4. 5. 6. 7. 8. 9. 10.final static int CONTEXT_MENU_1 = Menu.FIRST; final static int CONTEXT_MENU_2 = Menu.FIRST+1; final static int CONTEXT_MENU_3 = Menu.FIRST+2; @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){ menu.setHeaderTitle(&快捷菜单标题&); menu.add(0, CONTEXT_MENU_1, 0,&菜单子项1&); menu.add(0, CONTEXT_MENU_2, 1,&菜单子项2&); menu.add(0, CONTEXT_MENU_3, 2,&菜单子项3&); } 5.4 菜单?5.4.3 快捷菜单??ContextMenu类支持add()函数(代码第7行)和 addSubMenu()函数,可以在快捷菜单中添加菜单子项和 子菜单 第5行代码的onCreateContextMenu()函数中的参数? ? ?第1个参数menu是需要显示的快捷菜单 第2个参数v是用户选择的界面元素 第3个参数menuInfo是所选择界面元素的额外信息 5.4 菜单?5.4.3 快捷菜单?菜单选择事件的处理需要重载onContextItemSelected() 函数,该函数在用户选择快捷菜单中的菜单子项后被调 用,与onOptionsItemSelected ()函数的使用方法基本 相同 5.4 菜单?5.4.3 快捷菜单@Override public boolean onContextItemSelected(MenuItem item){ switch(item.getItemId()){ case CONTEXT_MENU_1: LabelView.setText(&菜单子项1&); case CONTEXT_MENU_2: LabelView.setText(&菜单子项2&); case CONTEXT_MENU_3: LabelView.setText(&菜单子项3&); } }1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 5.4 菜单?5.4.3 快捷菜单??使用registerForContextMenu()函数,将快捷菜单注册到 界面控件上(下方代码第7行)。这样,用户在长时间点 击该界面控件时,便会启动快捷菜单 为了能够在界面上直接显示用户所选择快捷菜单的菜单子 项,在代码中引用了界面元素TextView(下方代码第6行 ),通过更改TextView的显示内容(上方代码第5、8和 11行),显示用户所选择的菜单子项TextView LabelView = @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); LabelView = (TextView)findViewById(R.id.label); registerForContextMenu(LabelView); }1. 2. 3. 4. 5. 6. 7. 8. 5.4 菜单?5.4.3 快捷菜单?下方代码是/src/layout/main.xml文件的部分内容,第1 行声明了TextView的ID为label,在上方代码的第6行中 ,通过R.id.label将ID传递给findViewById()函数,这样 用户便能够引用该界面元素,并能够修改该界面元素的 显示内容1. &TextView android:id=&@+id/label& 2. android:layout_width=&fill_parent& 3. android:layout_height=&fill_parent& 4. android:text=&@string/hello& 5. /& 5.4 菜单?5.4.3 快捷菜单??需要注意的一点,上方代码的第2行,将 android:layout_width设臵为fill_parent,这样TextView 将填充满父节点的所有剩余屏幕空间,用户点击屏幕 TextView下方任何位臵都可以启动快捷菜单 如果将android:layout_width设臵为wrap_content,则用 户必须准确点击TextView才能启动快捷菜单 5.4 菜单?5.4.3 快捷菜单?完整代码参考MyContextMenu程序,运行结果如图所 示 5.4 菜单?5.4.3 快捷菜单???在Android系统中,菜单不仅能够在代码中定义,而且 可以像界面布局一样在XML文件中进行定义 使用XML文件定义界面菜单,将代码与界面设计分类, 有助于简化代码的复杂程度,并且更有利于界面的可视 化 下面将快捷菜的示例程序MyContextMen改用XML实现 ,新程序的工程名称为MyXLMContoxtMenu 5.4 菜单?5.4.3 快捷菜单??首先需要创建保存菜单内容的XML文件 在/src目录下建立子目录menu,并在menu下建立 context_menu.xml文件,代码如下1. &menu xmlns:android=&/apk/res/android&& 2. &item android:id=&@+id/contextMenu1& 3. android:title=&菜单子项1&/& 4. &item android:id=&@+id/contextMenu2& 5. android:title=&菜单子项2&/& 6. &item android:id=&@+id/contextMenu3& 7. android:title=&菜单子项3&/& 8. &/menu&?在描述菜单的XML文件中,必须以&menu&标签(代码第1行) 作为根节点,&item&标签(代码第2行)用来描述菜单中的子项 ,&item&标签可以通过嵌套实现子菜单的功能 5.4 菜单?5.4.3 快捷菜单?XML菜单的显示结果如图所示 5.4 菜单?5.4.3 快捷菜单?在XML文件中定义菜单后,在onCreateContextMenu() 函数中调用inflater.inflate()方法,将XML资源文件传递 给菜单对象@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){ MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.context_menu, menu); }?1. 2. 3. 4. 5. 6.?第4行代码中的getMenuInflater()为当前的Activity返回 MenuInflater 第5行代码将XML资源文件R.menu.context_menu,传递 给menu这个快捷菜单对象 5.5 界面事件??在Android系统中,存在多种界面事件,如点 击事件、触摸事件、焦点事件和菜单事件等等 在这些界面事件发生时,Android界面框架调 用界面控件的事件处理函数对事件进行处理 5.5 界面事件?5.5.1 按键事件?在MVC模型中,控制器根据界面事件(UI Event)类型 不同,将事件传递给界面控件不同的事件处理函数。? ?按键事件(KeyEvent)将传递给onKey()函数进行处理 触摸事件(TouchEvent)将传递给onTouch()函数进行处 理 5.5 界面事件?5.5.1 按键事件?Android系统界面事件的传递和处理遵循一的规则???如果界面控件设臵了事件监听器,则事件将先传递给事件 监听器 如果界面控件没有设臵事件监听器,界面事件则会直接传 递给界面控件的其他事件处理函数 即使界面控件设臵了事件监听器,界面事件也可以再次传 递给其他事件处理函数 5.5 界面事件?5.5.1 按键事件?Android系统界面事件的传递和处理遵循一的规则???是否继续传递事件给其他处理函数是由事件监听器处理函 数的返回值决定的 如果监听器处理函数的返回值为true,表示该事件已经完 成处理过程,不需要其他处理函数参与处理过程,这样事 件就不会再继续进行传递 如果监听器处理函数的返回值为false,则表示该事件没有 完成处理过程,或需要其他处理函数捕获到该事件,事件 会被传递给其他的事件处理函数 5.5 界面事件?5.5.1 按键事件?以EditText控件中的按键事件为例,说明Android系统界 面事件传递和处理过程,假设EditText控件已经设臵了 按键事件监听器??当用户按下键盘上的某个按键时,控制器将产生 KeyEvent按键事件 Android系统会首先判断EditText控件是否设臵了按键事件 监听器,因为EditText控件已经设臵按键事件监听器 OnKeyListener,所以按键事件先传递到监听器的事件处 理函数onKey()中 5.5 界面事件?5.5.1 按键事件? ??事件能够继续传递给EditText控件的其他事件处理函数, 完全根据onKey()函数的返回值来确定 如果onKey()函数返回false,事件将继续传递,这样 EditText控件就可以捕获到该事件,将按键的内容显示在 EditText控件中 如果onKey()函数返回true,将阻止按键事件的继续传递 ,这样EditText控件就不能够捕获到按键事件,也就不能 够将按键内容显示在EditText控件中 5.5 界面事件?5.5.1 按键事件???Android界面框架支持对按键事件的监听,并能够将按 键事件的详细信息传递给处理函数 为了处理控件的按键事件,先需要设臵按键事件的监听 器,并重载onKey()函数 示例代码如下1. entryText.setOnKeyListener(new OnKeyListener(){ 2. @Override 3. public boolean onKey(View view, int keyCode, KeyEvent keyEvent) { 4. //过程代码…… 5. return true/ 6. } 5.5 界面事件?5.5.1 按键事件??第1行代码是设臵控件的按键事件监听器 第3行代码的onKey ()函数中的参数? ? ?第1个参数view表示产生按键事件的界面控件 第2个参数keyCode表示按键代码 第3个参数keyEvent则包含了事件的详细信息,如按键的重 复次数、硬件编码和按键标志等 返回true,阻止事件传递 返回false,允许继续传递按键事件?第5行代码是onKey ()函数的返回值? ? 5.5 界面事件?5.5.1 按键事件??KeyEventDemo是一个说明 如何处理按键事件的示例 KeyEventDemo用户界面???最上方的EditText控件是输 入字符的区域 中间的CheckBox控件用来 控制onKey()函数的返回值 最下方的TextView控件用来 显示按键事件的详细信息, 包括按键动作、按键代码、 按键字符、Unicode编码、 重复次数、功能键状态、硬 件编码和按键标志 5.5 界面事件?5.5.1 按键事件?界面的XML文件的代码如下1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.&EditText android:id=&@+id/entry& android:layout_width=&fill_parent& android:layout_height=&wrap_content&& &/EditText& &CheckBox android:id=&@+id/block& android:layout_width=&wrap_content& android:layout_height=&wrap_content& android:text=&返回true,阻止将按键事件传递给界面元素& & &/CheckBox& &TextView android:id=&@+id/label& android:layout_width=&wrap_content& android:layout_height=&wrap_content& android:text=&按键事件信息& & &/TextView& 5.5 界面事件?5.5.1 按键事件??在EditText中,每当任何一个键子按下或抬起时,都会 引发按键事件 为了能够使EditText处理按键事件,需要使用 setOnKeyListener ()函数在代码中设臵按键事件监听器 ,并在onKey()函数添加按键事件的处理过程1. entryText.setOnKeyListener(new OnKeyListener(){ 2. @Override 3. public boolean onKey(View view, int keyCode, KeyEvent keyEvent) { 4. int metaState = keyEvent.getMetaState(); 5. int unicodeChar = keyEvent.getUnicodeChar(); 6. String msg = &&; 5.5 界面事件?7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.5.5.1 按键事件msg +=&按键动作:& + String.valueOf(keyEvent.getAction())+&\n&; msg +=&按键代码:& + String.valueOf(keyCode)+&\n&; msg +=&按键字符:& + (char)unicodeChar+&\n&; msg +=&UNICODE:& + String.valueOf(unicodeChar)+&\n&; msg +=&重复次数:& + String.valueOf(keyEvent.getRepeatCount())+&\n&; msg +=&功能键状态:& + String.valueOf(metaState)+&\n&; msg +=&硬件编码:& + String.valueOf(keyEvent.getScanCode())+&\n&; msg +=&按键标志:& + String.valueOf(keyEvent.getFlags())+&\n&; labelView.setText(msg); if (checkBox.isChecked()) } 5.5 界面事件?5.5.1 按键事件?????第4行代码用来获取功能键状态。功能键包括左Alt键、右 Alt键和Shift键,当这三个功能键被按下时,功能键代码 metaState值分别为18、34和65;但没有功能键被按下时 ,功能键代码metaState值分别为0 第5行代码获取了按键的Unicode值,在第9行中,将 Unicode转换为字符,显示在TextView中 第7行代码获取了按键动作,0表示按下按键,1表示抬起 按键。第7行代码获取按键的重复次数,但按键被长时间 按下时,则会产生这个属性值 第13行代码获取了按键的硬件编码,不同硬件设备的按键 硬件编码都不相同,因此该值一般用于调试 第14行获取了按键事件的标志符 5.5 界面事件?5.5.2 触摸事件??Android界面框架支持对触摸事件的监听,并能够将触 摸事件的详细信息传递给处理函数 需要设臵触摸事件的监听器,并重载onTouch ()函数1. touchView.setOnTouchListener(new View.OnTouchListener(){ 2. @Override 3. public boolean onTouch(View v, MotionEvent event) { 4. //过程代码…… 5. return true/ 6. }???第1行代码是设臵控件的触摸事件监听器 在代码第3行的onTouch()函数中,第1个参数View表示产 生触摸事件的界面控件;第2个参数MontionEvent表示触 摸事件的详细信息,如产生时间、坐标和触点压力等 第5行是onTouch()函数的返回值 5.5 界面事件?5.5.2 触摸事件??TouchEventDemo是一个说 明如何处理触摸事件的示例 TouchEventDemo用户界面??浅蓝色区域是可以接受触摸 事件的区域,用户可以在 Android模拟器中使用鼠标 点击屏幕,用以模拟触摸手 机屏幕 下方黑色区域是显示区域, 用来显示触摸事件的类型、 相对坐标、绝对坐标、触点 压力、触点尺寸和历史数据 量等信息 5.5 界面事件?5.5.2 触摸事件?在用户界面中使用了线性布局,并加入了3个TextView 控件???第1个TextView(ID为touch_area)用来标识触摸事件的 测试区域 第2个TextView(ID为history_label)用来显示触摸事件 的历史数据量 第3个TextView(ID为event_label)用来触摸事件的详细 信息,包括类型、相对坐标、绝对坐标、触点压力和触点 尺寸 5.5 界面事件?5.5.2 触摸事件?XML文件的代码如下1. &?xml version=&1.0& encoding=&utf-8&?& 2. &LinearLayout xmlns:android=&/apk/res/android& 3. android:orientation=&vertical& 4. android:layout_width=&fill_parent& 5. android:layout_height=&fill_parent&& 6. &TextView android:id=&@+id/touch_area& 7. android:layout_width=&fill_parent& 8. android:layout_height=&300dip& 9. android:background=&#0FF& 10. android:textColor=&#FFFFFF& 11. android:text=&触摸事件测试区域&& 12. &/TextView& 5.5 界面事件?5.5.2 触摸事件13. &TextView android:id=&@+id/history_label& 14. android:layout_width=&wrap_content& 15. android:layout_height=&wrap_content& 16. android:text=&历史数据量:& & 17. &/TextView& 18. &TextView android:id=&@+id/event_label& 19. android:layout_width=&wrap_content& 20. android:layout_height=&wrap_content& 21. android:text=&触摸事件:& & 22. &/TextView& 23. &/LinearLayout&??第9行代码定义了TextView的背景颜色,#80A0FF是颜色 代码 第10行代码定义了TextView的字体颜色 5.5 界面事件?5.5.2 触摸事件?在代码中为了能够引用XML文件中声明的界面元素,使 用了下面的代码1. 2. 3. 4.TextView labelView = labelView = (TextView)findViewById(R.id.event_label); TextView touchView = (TextView)findViewById(R.id.touch_area); final TextView historyView = (TextView)findViewById(R.id.history_label); 5.5 界面事件?5.5.2 触摸事件???当手指接触到触摸屏、在触摸屏上移动或离开触摸屏时 ,分别会引发ACTION_DOWN、ACTION_UP和 ACTION_MOVE触摸事件,而无论是哪种触摸事件, 都会调用onTouch()函数进行处理 事件类型包含在onTouch()函数的MotionEvent参数中, 可以通过getAction()函数获取到触摸事件的类型,然后 根据触摸事件的不同类型进行不同的处理 为了能够使屏幕最上方的TextView处理触摸事件,需要 使用setOnTouchListener()函数在代码中设臵触摸事件 监听器,并在onTouch()函数添加触摸事件的处理过程 5.5 界面事件?5.5.2 触摸事件1. touchView.setOnTouchListener(new View.OnTouchListener(){ 2. @Override 3. public boolean onTouch(View v, MotionEvent event) { 4. int action = event.getAction(); 5. switch (action) { 6. case (MotionEvent.ACTION_DOWN): 7. Display(&ACTION_DOWN&,event); 8. 9. case (MotionEvent.ACTION_UP): 10. int historySize = ProcessHistory(event); 11. historyView.setText(&历史数据量:&+historySize); 12. Display(&ACTION_UP&,event); 13. 14. case (MotionEvent.ACTION_MOVE): 15. Display(&ACTION_MOVE&,event); 16. 17. } 5.5 界面事件?5.5.2 触摸事件18. 19. 20.?}});??第7行代码的Display()是一个自定义函数,主要用来显示 触摸事件的详细信息,函数的代码和含义将在后面进行介 绍 第10行代码的ProcessHistory()也是一个自定义函数,用 来处理触摸事件的历史数据,后面进行介绍 第11行代码是使用TextView显示历史数据的数量 5.5 界面事件?5.5.2 触摸事件???MotionEvent参数中不仅有触摸事件的类型信息,还触 点的坐标信息,获取方法是使用getX()和getY()函数, 这两个函数获取到的是触点相对于父界面元素的坐标信 息。如果需要获取绝对坐标信息,则可使用getRawX() 和getRawY()函数 触点压力是一个介于0和1之间的浮点数,用来表示用户 对触摸屏施加压力的大小,接近0表示压力较小,接近1 表示压力较大,获取触摸事件触点压力的方式是调用 getPressure()函数 触点尺寸指用户接触触摸屏的接触点大小,也是一个介 于0和1之间的浮点数,接近0表示尺寸较小,接近1表 示尺寸较大,可以使用getSize()函数获取 5.5 界面事件?5.5.2 触摸事件?Display()将MotionEvent参数参数中的事件信息提取出 来,并显示在用户界面上1. private void Display(String eventType, MotionEvent event){ 2. int x = (int)event.getX(); 3. int y = (int)event.getY(); 4. float pressure = event.getPressure(); 5. float size = event.getSize(); 6. int RawX = (int)event.getRawX(); 7. int RawY = (int)event.getRawY(); 8. 9. String msg = &&; 10. msg += &事件类型:& + eventType + &\n&; 11. msg += &相对坐标:&+String.valueOf(x)+&,&+String.valueOf(y)+&\n&; 12. msg += &绝对坐标:&+String.valueOf(RawX)+&,&+String.valueOf(RawY)+&\n&; 13. msg += &触点压力:&+String.valueOf(pressure)+&, &; 14. msg += &触点尺寸:&+String.valueOf(size)+&\n&; 15. labelView.setText(msg); 16. } 5.5 界面事件?5.5.2 触摸事件??一般情况下,如果用户将手指放在触摸屏上,但不移动 ,然后抬起手指,应先后产生ACTION_DOWN和 ACTION_UP两个触摸事件 但如果用户在屏幕上移动手指,然后再抬起手指,则会 产生这样的事件序列:ACTION_DOWN → ACTION_MOVE → ACTION_MOVE → ACTION_MOVE → ……→ ACTION_UP 5.5 界面事件?5.5.2 触摸事件???在手机上运行的应用程序,效率是非常重要的。如果 Android界面框架不能产生足够多的触摸事件,则应用 程序就不能够很精确的描绘触摸屏上的触摸轨迹 如果Android界面框架产生了过多的触摸事件,虽然能 够满足精度的要求,但却降低了应用程序效率 Android界面框架使用了“打包”的解决方法。在触点 移动速度较快时会产生大量的数据,每经过一定的时间 间隔便会产生一个ACTION_MOVE事件,在这个事件 中,除了有当前触点的相关信息外,还包含这段时间间 隔内触点轨迹的历史数据信息,这样既能够保持精度, 又不至于产生过多的触摸事件。 5.5 界面事件?5.5.2 触摸事件?通常情况下,在ACTION_MOVE的事件处理函数中, 都先处理历史数据,然后再处理当前数据1. private int ProcessHistory(MotionEvent event) 2. { 3. int historySize = event.getHistorySize(); 4. for (int i = 0; i & historyS i++) { 5. long time = event.getHistoricalEventTime(i); 6. float pressure = event.getHistoricalPressure(i); 7. float x = event.getHistoricalX(i); 8. float y = event.getHistoricalY(i); 9. float size = event.getHistoricalSize(i); 10. 11. // 处理过程...... 12. } 13. return historyS 14. } 5.5 界面事件?5.5.2 触摸事件??? ? ? ? ?第3行代码获取了历史数据的数量 然后在第4行至12行中循环处理这些历史数据 第5行代码获取了历史事件的发生时间 第6行代码获取历史事件的触点压力 第7行和第8行代码获取历史事件的相对坐标 第9行获取历史事件的触点尺寸 在第14行返回历史数据的数量,主要是用于界面显示??Android模拟器并不支持触点压力和触点尺寸的模拟, 所有触点压力恒为1.0,触点尺寸恒为0.0 同时Android模拟器上也无法产生历史数据,因此历史 数据量一直显示为0 习题:? ?1.简述五种界面布局的特点。 2.参考下图中界面控件的摆放位臵,分别使用线性布局、 相对布局和绝对布局实现用户界面,并对比各种布局实现 的复杂程度和对不同屏幕尺寸的适应能力。? ?3.简述Android系统支持的三种菜单。 4.EditText控件有Numeric属性,设臵成integer后EditText 控件中只能输入数字,无法输入其他字母或符号。利用按 键事件,编程实现EditText控件的这一功能。
广而告之:
相关文档:
下载文档:
搜索更多:
词条解释:
All rights reserved Powered by
copyright &copyright 。甜梦文库内容来自网络,如有侵犯请联系客服。|

我要回帖

更多关于 android存储数据的方法 的文章

 

随机推荐