Android中的上下文菜单类似于Windows中的上下文菜单,Windows中的上下文菜单常称为:鼠标右击后的弹出菜单。
Android的上下文菜单的操作类似于列表项中的长按菜单项的事件响应。
Android用ContextMenu类管理上下文菜单。
1、Activity.onCreateContextMenu(ContextMenu menu,View source, ContextMenu.
ContexMenuInfo menuInfo);
作用:创建上下文菜单对象。
参数-menu:当前的上下文菜单。
参数-source:当前的view对象,即被长按的控件。
参数-menuInfo:没有任何方法的接口,即ContexMenuInfo是一个空接口。若控件是ListView(后面将介绍到该控件)这类的有多个选项的列表,则该参数可以获得列表中被长按项的索引值。
2、add(int);
3、add(CharSequence);
作用:为上下文菜单添加一个菜单项, 参数可以是字符日串,也可以是资源中定义的字符串索引值。
【示例代码】
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0,0,0,"update");//添加一个标题为update的菜单项
menu.add(0,1,0,"insert");//添加一个标题为insert的菜单项
menu.add(0,2,0,"delete");//添加一个标题为delete的菜单项
menu.add(0,3,0,"query");//添加一个标题为query的菜单项
}
4、registerForContextMenu(resId);
作用:为指定控件注册上下文菜单,参数resId是控件的资源索引值。
【示例代码】
TextView tv=(TextView)findViewById(R.id.tv);
registerForContextMenu(tv);//给tv控件注册上下文菜单
5、public boolean onContextItemSelected(MenuItem item)
作用:重写上下文菜单的被点击的事件响应程序.
【示例代码】
//上下文菜单项选择的响应事件
@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.miUpdate://若菜单项是miUpdate
Toast.makeText(this, getText(R.string.update), 3000).show();
break;
case R.id.miInsert: //若菜单项是miInsert
Toast.makeText(this, R.string.insert, 3000).show();
break;
case R.id.miDelete: //若菜单项是miDelete
Toast.makeText(this, R.string.delete, 3000).show();
break;
}
return super.onContextItemSelected(item);
}
说明:以上代码中的item是上下文菜单的当前被点击的菜单项,下面用switch语句对该菜单项的资源索引值 (item.getItem())进行判断,R.id.miUpdate是资源中定义的上下文菜单项的资源索引值。
步骤1、在项目的res文件夹下创建menu文件夹;
步骤2、在menu文件夹下创建上下文菜单资源文件,如:context_menu.xml,该文件内容如下所示:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/miUpdate"
android:title="@string/update"/>
<item
android:id="@+id/miInsert"
android:title="@string/insert"/>
</menu>
步骤3、在代码中解析以上资源文件,示例代码如下:
//创建上下文菜单
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
//创建菜单解析器对象
MenuInflater inflator=getMenuInflater();
//解析资源中定义的菜单
inflator.inflate(R.menu.context_menu, menu);
//设置上下文菜单的图标
menu.setHeaderIcon(R.drawable.icon);
//设置上下文菜单的标题
menu.setHeaderTitle(R.string.cmTitle);
}
1、选项菜单由onCreateOpitionsMenu()方法创建,单击menu按钮,与Activity绑定。
2、上下文菜单由onCreateContextMenu()方法创建,与某个View绑定。
3、每单击一次View,与该View绑定的上下文菜单的onCreateOptionsMenu都会执行一次。而选项菜单只会执行一次。
复选框是UI中常用的控件,复选框的类名:CheckBox,该类继承自Button。如图-1所示:
图-1
Checked:在资源文件中定义checked值为true,则该checkBox控件为选中状态,如图1中标题为音乐的checkBox控件。
提示:checked的默认值是false。
【示例代码】
isChecked();
作用:返回该控件是否被选中,若选中则返回值为true,否则为false。
【示例代码】
CheckBox checkBox=(CheckBox)findViewById(resId);
If(checkbox.isChecked()){
Toast.makeText(this,”该控件被选中”,3000).show();
}else{
Toast.makeText(this,”该控件未被选中”,3000).show();
}
该接口负责监听CheckBox等控件的选中状态的变化。
void onCheckedChanged(CompoundButton buttonView, boolean isChecked);
作用:监听控件选中状态的变化。
参数-buttonView:监听的控件对象;
参数-isChecked:若该控件处于选中状态,值为true,否则是false。
【示例代码】显示图-2效果,当选中图-2中某个CheckBox控件时,在窗口中显示该控件的标题加上is selected字符串。
图-2
//MainAct类实现OnCheckedChangeListener接口
public class MainAct extends Activity implements OnCheckedChangeListener{
CheckBox mChkMusic,mChkSport,mChkReadBook,mChkCollectMail;
String mText="";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//创建图-2中的两个控件
mChkCollectMail=(CheckBox)findViewById(R.id.chkCollectMail);
mChkReadBook=(CheckBox)findViewById(R.id.chkReadBook);
//注册这两个控件的onCheckedChanged事件
mChkCollectMail.setOnCheckedChangeListener(this);
mChkReadBook.setOnCheckedChangeListener(this);
}
//实现OnCheckedChangeListener. OnCheckedChanged()方法
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch(buttonView.getId()){
case R.id.chkReadBook://这是图-2中的read book控件的资源索引
case R.id.chkCollectMail://这是图-2中的collect mail控件的资源索引值
if(isChecked){
mText=buttonView.getText().toString();
Toast.makeText(MainAct.this, mText+" is selected", 5000).show();
}
}
}
}
单选按钮是UI中常用的元素,类名:RadioButton,如图-3所示:
图-3
Checked:控件是否处于选中状态
以下代码定义了图-3中两个RadioButton控件的显示样式:
<RadioButton
android:id="@+id/rbMale"
android:text="男"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"/>
<RadioButton
android:id="@+id/rbFeMale"
android:text="女"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
以上代码中的两个控件还不能形成互斥的效果,即男和女两个控件可以同时处于选中状态。在Android中必须用RadioGroup控件将一组需要互斥的RadioButton包括起来。
将以上代码改进,形成男和女两个RadioButton互斥(即不能同时处于选中状态)的效果,如下代码所示:
<RadioGroup
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/rbMale"
android:text="男"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"/>
<RadioButton
android:id="@+id/rbFeMale"
android:text="女"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RadioGroup>
进度条(ProgressBar)是UI中非常实用的控件,类名:ProgressBar,用于动态显示某个比较耗时操作的进度,可避免因操作时间长,使用户感觉程序失去了响应,从而提高用户的使用体验。如图-4所示:
图-4
说明:
图-4靠上部分显示了一个默认的进度条样式(不断转动的圆圈),该进度条没有进度,用于显示在无法确定进度的操作。
图-4下面显示了一个水平进度条,该进度条上面有一个TextView控件显示该进度条的进度值目前是22%
XML属性 |
说明 |
max |
设置进度条的最大值 |
progess |
设置已完成的进度值 |
progressDrawable |
设置进度条的轨道的绘制形式 |
progressBarStyle |
设置进度条样式 |
progressBarSytleHorizontal |
水平进度条样式 |
progressBarStyleLarge |
大进度条样式 |
proressBarStyleSmall |
小进度条样式 |
图-5
progressBar的style有如下值:
Horizontal |
水平进度条 |
Inverse |
不断跳跃、旋转的进度条 |
Large |
大进度条 |
Large.Inverse |
不断跳跃、旋转的大进度条 |
Small |
小进度条 |
Small.Inverse |
不断跳跃、旋转的小进度条 |
图-6
说明
1、以上的style属性值前面都要加上如下的前缀:
@android:style/Widget.ProgressBar.,例如:
@android:style/Widget.ProgressBar.Large:大进度条
2、Widget:小部件,我们所称的UI中的控件,也称为小部件。
示例代码:
以下代码定义了图-4中两个进度条控件:
<!-- 默认样式的进度条 -->
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<!-- 水平样式的进度条 -->
<ProgressBar
android:id="@+id/pb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Horizontal"
android:max="100"/>
拖动条控件,类名:SeekBar,与进度条在外观上相似,并且允许用户通过拖动滑块来改变滑块的值。手机中调整屏幕亮度、音量的用的就是SeekBar。SeekBar控件如图-7所示:
图-7
SeekBar是ProgressBar的间接子类,因此SeekBar的属性参见ProgressBar的属性列表
以下代码定义了图-7的控件样式:
<SeekBar
android:id="@+id/sb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="10"/>
说明:max属性:表示整个控件的最大长度值。Progress表示目前滑块所处的位置的值是10。
该接口负责监听SeekBar控件的的滑块移动。
1、void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser);
作用:滑块进度值发生改变时,触发本方法。
说明:
参数-seekBar:当前的SeekBard对象。
参数-progress:滑块的进度值。
参数-fromUser:用户是否拖动了滑块,true:是,false;否。
2、void onStartTrackingTouch(SeekBar seekBar);
作用:开始移动滑块时,触发本方法,滑块移动中本方法不再执行。
3、void onStopTrackingTouch(SeekBar seekBar);
作用:结束移动滑块时,触发本方法。
//实现OnSeekBarChangeListener接口
public class MainAct extends Activity implements OnSeekBarChangeListener{
SeekBar sb;
int mProgress;//存放滑块进度值
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sb=(SeekBar)findViewById(R.id.sb);//创建滑块对象
//注册进度条改变的监听事件
sb.setOnSeekBarChangeListener(this);
}
//实现onProgressChanged方法,进度条发生改变时触发该方法
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
mProgress=progress;//存放当前滑块的进度值
}
//实现onStartTrackingTouch方法,该方法在开始拖动进度条时触发
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
Log.i("SeekBar","begin TrackingTouch");
}
//实现onStopTrackingTouch方法,该方法在进度拖动时触发
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Log.i("SeekBar","end TrackingTouch");
Log.i("SeekBar","progress="+mProgress);
}
星级评分控件,类名:RatingBar,与拖动条控件很相似,拖动条控件是通过拖动条上滑块来改变值。RatingBar是通过拖动来改变星级的值。如图-8所示:
图-8
RatingBar是ProgressBar类的间接子类,属性可参见ProgressBar控件的属性列表。以下是该控件独有的属性。
XML属性 |
说明 |
numStars |
星的数量,如图-8中有4颗半星 |
stepSize |
星变化的步长,可以是小数,如0.5(每次增长或减少半颗星) |
图-9
【示例代码】
以下代码定义了图-8中RatingBar的显示样式:
<RatingBar
android:id="@+id/rb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="4.5"
android:stepSize="0.5"/>
该接口负责监听RatingBar控件的滑块移动。
void onRatingChanged(RatingBar ratingBar, float rating,boolean fromUser)
作用:当RatingBar中的滑块移动时,触发本方法执行。
参数-ratingBar:当前的星级滑块对象。
参数-rating:当前星的个数。
参数-fromUser:用户是否拖动了滑块,true:是,false;否。
//实现OnRatingBarChangeListener接口
public class MainAct extends Activity implements OnRatingBarChangeListener{
RatingBar mRatingBar;
TextView mtvRatingBar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//实例化mtvRatingBar控件,该控件负责显示星级控件中当前星的个数
mtvRatingBar=(TextView)findViewById(R.id.tvRagingBar);
//实例化星级控件
mRatingBar=(RatingBar)findViewById(R.id.rb);
//注册onRatingChanged事件
mRatingBar.setOnRatingBarChangeListener(this);
}
//实现onRatingChanged方法,该方法在RatingBar控件发生改变时触发
@Override
public void onRatingChanged(RatingBar ratingBar, float rating,
boolean fromUser) {
//在标签中显示目前星的个数
mtvRatingBar.setText(""+mRatingBar.getRating());
}
}
DatePicker(日期选择器)供用户选择日期。该控件如图-10所示:
图-10
图-10用以下xml代码定义:
init(year,month,day,OndateChangedListener()):初始化控件中的年月日,并设置一个数据发生改变的响应事件。
该接口负责监听DatePicker控件中日期的变化。
OndateChangedListener();
作用:DatePicker对象中的日期因用户的选择发生改变时,本事件被触发。
【示例代码】
//实现OnDateChangedListener接口
public class MainAct extends Activity implements OnDateChangedListener,OnTimeChangedListener{
DatePicker mDatePicker;//定义成员变量
TextView mTvShowTime;//显示日期结果的标签
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTvShowTime=(TextView)findViewById(R.id.tvShowTime);
mDatePicker=(DatePicker)findViewById(R.id.datePicker);
//初始化mDatePicker
mDatePicker.init(2011, 11, 5, this);
}
//实现onDateChanged方法,日期改变时触发本方法
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
StringBuffer sb=new StringBuffer();
sb.append(year+"年").append(monthOfYear+"月")
.append(dayOfMonth+"日");
mTvShowTime.setText(sb.toString());//显示结果
}
TimePicker控件负责选择时间。如图-11所示:
图-11
1、getCurrentHour():获取小时。
2、getCurrentMinute():获取分钟。
OnTimeChangedListener接口负责监听TimePicker控件中时间改变。
void onTimeChanged(TimePicker view, int hourOfDay, int minute);
作用:当TimePicker中的时间发生改变时,触发本方法执行。
参数-view:当前的TimePicker对象。
参数-hourOfDay:小时。
参数-minute:分钟。
以下代码实现是-12的效果,当单击TimePicker控件时,显示当前时间。
图-12
//实现OnTimeChangedListener接口
public class MainAct extends Activity implements OnTimeChangedListener{
TimePicker mTimePicker;
TextView mTvShowTime;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTvShowTime=(TextView)findViewById(R.id.tvShowTime);
mTimePicker=(TimePicker)findViewById(R.id.timePicker);
//注册setOnTimeChangedListener事件响应程序
mTimePicker.setOnTimeChangedListener(this);
}
//实现ontimeChanged方法
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
String text=hourOfDay+"小时 "+minute+"分";
Toast.makeText(this, text, 3000).show();
}
}
数字时钟,父类是TextView。
模拟时钟,父类是View。如图-13所示:
图-13
定义该控件的xml代码如下所示:
<AnalogClock
android:id="@+id/acClock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
设置eclipse开发环境中,类中的方法会在编辑区的右边框用相同颜色标识,如图-14所示:
MainAct类中有三个方法:onDestory、onStart(),还有一个方法没有显示。在编辑区的右边框有三个蓝色的小矩形(称为标记)。
(1) 单击图-14中右边框的第一个蓝色标记,将定位至当onDestory()方法。
(2) 单击图-14中右边框的第二个蓝色标记,将定位至onStart()方法。
提示:若一个文件中有多个类,并且两个类中有同名方法出现,那么通过这种标记可以方便地找到指定类的方法,不会出现混淆问题。
图-14
标记没颜色可以修改,以下介绍修改标记颜色步骤:
步骤1、在编辑区的任意位置右击鼠标;
步骤2、在弹出菜单中选择Preferences。
步骤3、选择General—>Editors—>Text Editors —>Annotations->occurrences,选择颜色,如图-15所示:
图-15
步骤4、在弹出的颜色列表中选择颜色。
1. 同样名称的类,在不同的包中,两个类如果同时使用,需要指定它的包名。
示例代码:
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioButton;
import android.widget.RadioGroup;
public class MainAct extends Activity
implements OnCheckedChangeListener,
android.widget.RadioGroup.OnCheckedChangeListener
说明:
以上代码中,标注(1)指向的接口是第一行(红框所指)的导包路径。
标注(2)指向的类与标注(1)相同,但路径不同,因此在第二个接口前面要写明接口所在的包路径。这样Android才能正确区分两个同名接口。