一、Android应用的界面编程
1、布局管理器
线性布局:LinerLayout
表格布局:TableLayout
相对布局:RelativeLayout
绝对布局:AbsoluteLayout
帧布局:FrameLayout
网格布局:GridLayout(android 4.0新增)
1.线性布局
线性布局不会自动换行,当组件会一个一个的排列到头后,剩下的组件将不会被显示出来。
注:纵向vertical或横向horizontal
2.表格布局(注册界面)
TableLayout属于行和列形式的管理控件,每行为一个TableRow对象,也可以是一个View对象。在TableRow中还可以继续添加其他的控件,每添加一个子控件就成为一列。TableLayout不会生成边框。
Android:collapseColumns 设置指定的列为collapse,如果一列被标示为collapse,该列会被隐藏
Android:shrinkColumns 设置指定的列为shrinkable,如果一列被标示为shrinkable,列的宽度进行收缩,自适应父容器的大小
Android:stretchColumns 设置指定的列为stretchable,如果一列被标示为stretchable ,该列会被拉伸,填充满表格的空白区域
e.g.
android:shrinkColumns="1" //第2列允许收缩
android:stretchColumns="2" //第3列允许拉伸
android:collapseColumns="1" //第2列被隐藏
3.相对布局
相对布局中的视图组件是按相互之间的相对位置来确定的,并不是线性布局中的必须按行或按列单个显示。
4.帧布局(视频播放暂停画面)
帧布局中的每一个组件都代表一个画面,默认以屏幕左上角作为(0,0)坐标,按组件定义的先后顺序依次逐屏显示,后面出现的会覆盖前面的画面。用该布局可以实现动画效果。
5.绝对布局(登陆界面)
注:绝对定位AbsoluteLayout,又可以叫做坐标布局,可以直接指定子元素的绝对位置,这种布局简单直接,直观性强,但是由于手机屏幕尺寸差别比较大,使用绝对定位的适应性会比较差。
在绝对定位中,如果子元素不设置layout_x和layout_y,那么它们的默认值是0,也就是说它会像在FrameLayout一样这个元素会出现在左上角。
6.网格布局(计算器)
网格布局的作用类似于HTML中的table标签,它把整个容器分成raws x columns个网格,每个网格放一个组件,除此之外也可以设置一个组件横跨多少列,一个组件横跨多少行。
e.g.
android:rowCount="6" //6行
android:columnCount="4" //4列
android:layout_columnSpan="4" //横跨4列
Android长度单位详解(dp、sp、px、in、pt、mm、dip)
android中定义的dimension单位有以下这些:
1、px(Pixels ,像素):对应屏幕上的实际像素点。例如,320*480的屏幕在横向有320个象素,在纵向有480个象素。
2、in(Inches ,英寸):屏幕物理长度单位。每英寸等于2.54厘米。例如,形容手机屏幕大小,经常说,3.2(英)寸、3.5(英)寸、4(英)寸就是指这个单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是3.2英寸,表示手机的屏幕(可视区域)对角线长度是3.2*2.54 = 8.128厘米。读者可以去量一量自己的手机屏幕,看和实际的尺寸是否一致。
3、mm(Millimeters ,毫米):屏幕物理长度单位。
4、pt(Points ,磅):屏幕物理长度单位, 表示一个点,是屏幕的物理尺寸。大小为1英寸的1/72。
5、dp(与密度无关的像素):逻辑长度单位,在 160 dpi 屏幕上,1dp=1px=1/160英寸。随着密度变化,对应的像素数量也变化,但并没有直接的变化比例。
dip:与dp相同,多用于Google示例中。
sp(与密度和字体缩放度无关的像素):与dp类似,但是可以根据用户的字体大小首选项进行缩放。尽量使用dp作为空间大小单位,sp作为和文字相关大小单位。
二、UI组件
1.TextView及其子类
android:ellipsize="marquee"
android:singleLine="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:marqueeRepeatLimit="marquee_forever"
android:shadowDx="10.0" //阴影水平偏移量
android:shadowDy="8.0" //阴影垂直偏移量
android:shadowRadius="3.0" //阴影半径
android:autoLink="email|phone"
android:password="true"
android:checkMark="@drawable/ok"
android:background="@drawable/bg_border" //红色边框,bg_border.xml如下
android:background="@drawable/bg_border2" //圆角边框,渐变背景
android:topLeftRadius="20px"
android:topRightRadius="5px"
android:bottomRightRadius="20px"
android:bottomLeftRadius="5px"/>
android:startColor="#f00"
android:centerColor="#0f0"
android:endColor="#00f"
android:type="sweep"/>
android:hint="请填写登录帐号"
android:inputType="numberPassword"
android:inputType="number"
android:inputType="date"
android:inputType="phone"
android:shadowColor="#aa5"
android:shadowRadius="1"
android:shadowDx="5"
android:shadowDy="5"
android:background="@drawable/button_selector"//button_selector.xml如下所示
- android:state_pressed="true"
android:drawable="@drawable/red"
/>
- android:state_pressed="false"
android:drawable="@drawable/purple"
/>
android:orientation="horizontal"
android:layout_gravity="center_horizontal">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/male"
android:text="男"
android:checked="true" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/female"
android:text="女" />
android:layout_height="wrap_content"
android:text="红色"
android:checked="true"/>
android:layout_height="wrap_content"
android:text="蓝色"/>
android:layout_height="wrap_content"
android:text="绿色" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="横向排列"
android:textOn="纵向排列"
android:checked="true" />
android:layout_height="wrap_content"
android:textOff="横向排列"
android:textOn="纵向排列"
android:thumb="@drawable/check"
android:checked="true"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14pt"
android:textColor="#f0f"
android:drawableRight="@drawable/ic_launcher" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:dial="@drawable/watch"
android:hand_minute="@drawable/hand"/>
android:id="@+id/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12pt"
android:textColor="#ffff0000" />
2.ImageView及其子类
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_zoom_down"
android:src="@android:drawable/btn_minus" />
android:id="@+id/badge"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_launcher"/>
QuickContactBadge badge = (QuickContactBadge) findViewById(R.id.badge);
// 将QuickContactBadge组件与特定电话号码对应的联系人建立关联
badge.assignContactFromPhone("15828560682", false);
3. AdapterView及其子类
AdapterView派生了三个子类:AbsListView , AbsSpinner ,和AdapterViewAnimator
3.1、列表视图(ListView)和ListActivity
创建ListView有如下两种方式:
(1)、直接使用ListView创建
(2)、让Activity继承ListActivity(相当于该Activity显示的组件为ListView)
ListView、GridView、Spinner、Gallery等AdapterView都只是容器,而Adapter负责提供每个列表项组件,AdapterView则采用合适的方式显示这些表项。
ListView的功能与用法:
(1)、直接指定ListView的数组资源
android:entries="@array/books" // 数组资源
android:divider="#f00" //红色分割线
android:dividerHeight="2px" //分割线宽度
android:headerDividersEnabled="false" //不会在页眉视图前画分隔符
/>
Adapter常见的实现类如下:
<1>.ArrayAdapter:简单、易用,通常用于数组或List集合的多个值包装成的列表项
<2>.SimpleAdapter:不简单、功能强大,可用于将List集合的多个对象包装成列表项
<3>.SimpleCursorAdapter:与SimpleAdapter基本相似,用于包装Cursor提供的数据
<4>.BaseAdapter:通常用于扩展,可以对列表项进行最大限制的定制
(2)、使用ArrayAdapter创建ListView
// 定义一个数组
String[] arr2 = { "Java", "Hibernate", "Spring" , "Android" };
// 将数组包装ArrayAdapter
ArrayAdapter adapter2 = new
ArrayAdapter(this, R.layout.checked_item, arr2);
// 为ListView设置Adapter
list2.setAdapter(adapter2);
(3)、基于ListActivity实现列表
String[] arr = { "孙悟空", "猪八戒", "唐僧" };
// 创建ArrayAdapter对象
ArrayAdapter adapter = new ArrayAdapter
(this,android.R.layout.simple_list_item_multiple_choice, arr);
// 设置该窗口显示列表
setListAdapter(adapter);
//界面布局文件中应该包含id为"@+id/android:list"的ListView
android:id="@+id/android:list"
...
/>
(4)、使用SimpleAdapter创建ListView
public class SimpleAdapterTest extends Activity
{
private String[] names = new String[]
{ "虎头", "弄玉", "李清照", "李白"};
private String[] descs = new String[]
{ "可爱的小孩", "擅长音乐的女孩", "擅长文学的女性", "浪漫主义诗人"};
private int[] imageIds = new int[]
{ R.drawable.tiger , R.drawable.nongyu
, R.drawable.qingzhao , R.drawable.libai};
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 创建一个List集合,List集合的元素是Map
List
<2>.CalendarView
android:layout_width="400dp"
android:layout_height="500dp"
android:firstDayOfWeek="2" //以星期一作为每周第一天
android:shownWeekCount="6" //该组件总共显示6个星期
android:selectedWeekBackgroundColor="#ffffcc" //被选中周的背景色
android:focusedMonthDateColor="#cc0066" //获得焦点月份的日期颜色
android:weekSeparatorLineColor="#000033"
android:unfocusedMonthDateColor="#c0c0c0" //没有焦点的日期文字的颜色
android:id="@+id/calendarView"
/>
cv = (CalendarView)findViewById(R.id.calendarView);
// 为CalendarView组件的日期改变事件添加事件监听器
cv.setOnDateChangeListener(new OnDateChangeListener()
{
public void onSelectedDayChange(CalendarView view, int year,int month, int dayOfMonth)
{
// 使用Toast显示用户选择的日期
Toast.makeText(CalendarViewTest.this,"你生日是" + year + "年" + month + "月" + dayOfMonth + "日" ,Toast.LENGTH_SHORT).show();
}
});
<3>.DatePicker/TimePicker、NumberPicker
android:id="@+id/datePicker"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:startYear="2000"
android:endYear="2012"
android:calendarViewShown="true"
android:spinnersShown="true"
/>
android:id="@+id/timePicker"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
/>
// 获取当前的年、月、日、小时、分钟
Calendar c = Calendar.getInstance();
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH);
day = c.get(Calendar.DAY_OF_MONTH);
hour = c.get(Calendar.HOUR);
minute = c.get(Calendar.MINUTE);
// 初始化DatePicker组件,初始化时指定监听器
datePicker.init(year, month, day, new OnDateChangedListener()
{
public void onDateChanged(DatePicker arg0, int year, int month, int day)
{
ChooseDate.this.year = year;
ChooseDate.this.month = month;
ChooseDate.this.day = day;
// 显示当前日期、时间
showDate(year, month, day, hour, minute);// 在EditText中显示当前日期、时间的方法
}
});
// 为TimePicker指定监听器
timePicker.setOnTimeChangedListener(new OnTimeChangedListener()
{
public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
{
ChooseDate.this.hour = hourOfDay;
ChooseDate.this.minute = minute;
// 显示当前日期、时间
showDate(year, month, day, hour, minute); // 在EditText中显示当前日期、时间的方法
}
});
android:id="@+id/np1"
android:layout_width="match_parent"
android:layout_height="80dp"
android:focusable="true"
android:focusableInTouchMode="true"
/>
// 设置np1的最小值和最大值
np1.setMinValue(10);
np1.setMaxValue(50);
// 设置np1的当前值
np1.setValue(25);
<4>.SearchView
android:id="@+id/sv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
public class Main implements SearchView.OnQueryTextListener extends Activity
{
// 设置该SearchView默认是否自动缩小为图标
sv.setIconifiedByDefault(true);
// 为该SearchView组件设置事件监听器
sv.setOnQueryTextListener(this);
// 设置该SearchView显示搜索按钮
sv.setSubmitButtonEnabled(true);
// 设置该SearchView内默认显示的提示文本
sv.setQueryHint("查找");
// 用户输入字符时激发该方法
@Override
public boolean onQueryTextChange(String newText)
{
if (TextUtils.isEmpty(newText))
{
// 清除ListView的过滤
lv.clearTextFilter();
}
else
{
// 使用用户输入的内容对ListView的列表项进行过滤
lv.setFilterText(newText);
}
return true;
}
// 单击搜索按钮时激发该方法
@Override
public boolean onQueryTextSubmit(String query)
{
// 实际应用中应该在该方法内执行实际查询
// 此处仅使用Toast显示用户输入的查询内容
Toast.makeText(this, "您的选择是:" + query
, Toast.LENGTH_SHORT).show();
return false;
}
}
<5>.TabHost(标签页)
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@android:id/tabs"
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@android:id/tabcontent"
>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/page1"
>
…
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/page2"
>
…
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/page3"
>
…
/>
tabHost.setup();
TabSpec tabSpec = tabHost.newTabSpec("page1");
//tabSpec.setIndicator("首页", getResources().getDrawable(R.drawable.i1));
tabSpec.setIndicator(createTabView("首页"));// createTabView()创建标题View
tabSpec.setContent(R.id.page1);
tabHost.addTab(tabSpec);
<6>.ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
>
......
/>
<7>.Notification
// 获取系统的NotificationManager服务
NotificationManager nm =
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification notify = new Notification.Builder(this)
// 设置打开该通知,该通知自动消失
.setAutoCancel(true)
// 设置显示在状态栏的通知提示信息
.setTicker("有新消息")
// 设置通知的图标
.setSmallIcon(R.drawable.notify)
// 设置通知内容的标题
.setContentTitle("一条新通知")
// 设置通知内容
.setContentText("恭喜你,您加薪了,工资增加20%!")
// 设置使用系统默认的声音、默认LED灯
//.setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_LIGHTS)
// 设置通知的自定义声音
.setSound(Uri.parse("android.resource://org.crazyit.ui/"+ R.raw.msg))
.setWhen(System.currentTimeMillis())
// 设改通知将要启动程序的Intent
.setContentIntent(pi).build();
// 发送通知
nm.notify(NOTIFICATION_ID, notify);
三、对话框
Android提供了4种常用的对话框:
1.AlertDialog:功能最丰富、实际应用最广的对话框
2.ProgressDialog:进度对话框,这个对话框只是对简单进度条的封装
3.DatePickerDialog:日期选择对话框,这个对话框只是对DatePicker的包装
4.TimePickerDialog:时间选择对话框,这个对话框只是对TimePicker的包装
< ---AlertDialog--- >
AlertDialog生成的对话框可分为4个区域:
1>.图标区
2>.标题区
3>.内容区
4>.按钮区
创建对话框步骤:
1>.使用创建AlertDialog.Builder对象
2>.调用AlertDialog.Builder的setTitle()或setCustomTitle方法设置标题
3>.调用AlertDialog.Builder的setIcon方法设置标题
4>.调用AlertDialog.Builder的相关方法设置对话框内容
5>.调用AlertDialog.Builder的setPositiviteButton、setNegativiteButton或setNeutralButton方法添加多个按钮
6>.调用AlertDialog.Builder的create()方法创建AlertDialog对象,再调用AlertDialog对象的show()方法将对话框显示出来
AlertDialog提供了6种方法来指定对话框的内容
1>.setMessage():设置对话框内容为简单文本
2>.setItems():设置对话框内容为简单列表项
3>.setSingleChoiceItems():设置对话框内容为单选列表项
4>.setMultiChoiceItems():设置对话框内容为多选列表项
5>.setAdapter():设置对话框内容为自定义列表项
6>.setView():设置对话框内容为自定义View
AlertDialog.Builder builder = new AlertDialog.Builder(this);//创建对象
builder.setTitle("对话框");// 设置对话框标题
builder.setIcon(R.drawable.tools);// 设置对话框的图标
builder.setMessage("对话框的测试内容\n第二行内容"); //设置简单内容
builder.setItems(items, new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
show.setText("你选中了《" + items[which] + "》");
}
});// 设置简单的列表项内容
builder.setSingleChoiceItems(items, 1, new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
show.setText("你选中了《" + items[which] + "》");
}
});// 设置单选列表项,默认选中第二项(索引为1)
builder.builder.setMultiChoiceItems(items,
new boolean[]{false , true ,false ,true}, null);
// 设置多选列表项,设置勾选第2项、第4项
builder.setAdapter(new ArrayAdapter(this , R.layout.array_item , items), null);// 设置自定义列表项
builder.setView(loginForm);// 设置对话框显示的View对象
setPositiveButton(builder);// 添加【确定】按钮
setNegativeButton(builder);//添加【取消】按钮
builder.create().show();//创建,显示对话框
builder.setPositiveButton("登录" , new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog,int which)
{
// 此处可执行登录处理
}
});
private AlertDialog.Builder setPositiveButton(AlertDialog.Builder builder)
{
// 调用setPositiveButton方法添加确定按钮
return builder.setPositiveButton("确定", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
show.setText("单击了【确定】按钮!");
}
});
}
< ---对话框风格窗口--- >
android:theme="@android:style/Theme.Dialog"//以对话框形式显示activity
< ---使用PopupWindow--- >
// 装载R.layout.popup对应的界面布局
View root = this.getLayoutInflater().inflate(R.layout.popup, null);
// 创建PopupWindow对象
final PopupWindow popup = new PopupWindow(root, 280, 360);
//popup.showAsDropDown(v);// 以下拉方式显示。
//将PopupWindow显示在指定位置
popup.showAtLocation(findViewById(R.id.bn), Gravity.CENTER, 20,20);
< ---使用DatePickerDialog/TimePickerDialog--- >
Calendar c = Calendar.getInstance();
// 直接创建一个DatePickerDialog对话框实例,并将它显示出来
new DatePickerDialog(DateDialogTest.this,
// 绑定监听器
new DatePickerDialog.OnDateSetListener()
{
@Override
public void onDateSet(DatePicker dp, int year,int month, int dayOfMonth)
{
EditText show = (EditText) findViewById(R.id.show);
show.setText("您选择了:" + year + "年" + (month + 1)+ "月" + dayOfMonth + "日");
}
}
//设置初始日期
, c.get(Calendar.YEAR)
, c.get(Calendar.MONTH)
, c.get(Calendar.DAY_OF_MONTH)).show();
Calendar c = Calendar.getInstance();
// 创建一个TimePickerDialog实例,并把它显示出来。
new TimePickerDialog(DateDialogTest.this,
// 绑定监听器
new TimePickerDialog.OnTimeSetListener()
{
@Override
public void onTimeSet(TimePicker tp, int hourOfDay,int minute)
{
EditText show = (EditText) findViewById(R.id.show);
show.setText("您选择了:" + hourOfDay + "时" + minute+ "分");
}
}
//设置初始时间
, c.get(Calendar.HOUR_OF_DAY)
, c.get(Calendar.MINUTE)
//true表示采用24小时制
, true).show();
< ---使用ProgressDialog创建进度对话框 --- >
// 调用静态方法显示环形进度条
ProgressDialog.show(this, "任务执行中", "任务执行中,请等待", false, true); //①环形进度对话框
ProgressDialog pd1 = new ProgressDialog(ProgressDialogTest.this);
// 设置对话框的标题
pd1.setTitle("任务正在执行中");
// 设置对话框显示的内容
pd1.setMessage("任务正在执行中,敬请等待...");
// 设置对话框能用“取消”按钮关闭
pd1.setCancelable(true);
// 设置对话框的进度条风格
pd1.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// 设置对话框的进度条是否显示进度
pd1.setIndeterminate(true);
pd1.show(); //②不显示进度的进度条对话框
// 将进度条的完成进度重设为0
progressStatus = 0;
// 重新开始填充数组。
hasData = 0;
ProgressDialog pd2 = new ProgressDialog(ProgressDialogTest.this);
pd2.setMax(MAX_PROGRESS);
// 设置对话框的标题
pd2.setTitle("任务完成百分比");
// 设置对话框 显示的内容
pd2.setMessage("耗时任务的完成百分比");
// 设置对话框不能用“取消”按钮关闭
pd2.setCancelable(false);
// 设置对话框的进度条风格
pd2.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// 设置对话框的进度条是否显示进度
pd2.setIndeterminate(false);
pd2.show(); //③显示进度条的进度对话框
四、菜单
< ------------选项菜单和子菜单----------- >
// 当用户单击MENU键时触发该方法
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// -------------向menu中添加字体大小的子菜单-------------
SubMenu fontMenu = menu.addSubMenu("字体大小");
// 设置菜单的图标
fontMenu.setIcon(R.drawable.font);
// 设置菜单头的图标
fontMenu.setHeaderIcon(R.drawable.font);
// 设置菜单头的标题
fontMenu.setHeaderTitle("选择字体大小");
fontMenu.add(0, FONT_10, 0, "10号字体");
fontMenu.add(0, FONT_12, 0, "12号字体");
// -------------向menu中添加普通菜单项-------------
menu.add(0, PLAIN_ITEM, 0, "普通菜单项");
// -------------向menu中添加文字颜色的子菜单-------------
SubMenu colorMenu = menu.addSubMenu("字体颜色");
colorMenu.setIcon(R.drawable.color);
// 设置菜单头的图标
colorMenu.setHeaderIcon(R.drawable.color);
// 设置菜单头的标题
colorMenu.setHeaderTitle("选择文字颜色");
colorMenu.add(0, FONT_RED, 0, "红色");
colorMenu.add(0, FONT_GREEN, 0, "绿色");
return super.onCreateOptionsMenu(menu);
}
@Override
// 选项菜单的菜单项被单击后的回调方法
public boolean onOptionsItemSelected(MenuItem mi)
{
//判断单击的是哪个菜单项,并针对性的作出响应。
switch (mi.getItemId())
{
case FONT_10:
edit.setTextSize(10 * 2);
break;
case FONT_12:
edit.setTextSize(12 * 2);
break;
case FONT_RED:
edit.setTextColor(Color.RED);
break;
case FONT_GREEN:
edit.setTextColor(Color.GREEN);
break;
case PLAIN_ITEM:
Toast toast = Toast.makeText(MenuTest.this, "您单击了普通菜单项" , Toast.LENGTH_SHORT).show();
break;
}
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// -------------向menu中添加子菜单-------------
SubMenu prog = menu.addSubMenu("启动程序");
// 设置菜单头的图标
prog.setHeaderIcon(R.drawable.tools);
// 设置菜单头的标题
prog.setHeaderTitle("选择您要启动的程序");
// 添加菜单项
MenuItem item = prog.add("查看经典Java EE");
//为菜单项设置关联的Activity
item.setIntent(new Intent(this , OtherActivity.class));
return super.onCreateOptionsMenu(menu);
}
< ------------上下文菜单----------- >
// 为文本框注册上下文菜单
registerForContextMenu(txt);
// 创建上下文菜单时触发该方法
@Override
public void onCreateContextMenu(ContextMenu menu, View source,
ContextMenu.ContextMenuInfo menuInfo)
{
menu.add(0, MENU1, 0, "红色");
menu.add(0, MENU2, 0, "绿色");
// 将三个菜单项设为单选菜单项
menu.setGroupCheckable(0, true, true); //第三个参数为true则为单选
//设置上下文菜单的标题、图标
menu.setHeaderIcon(R.drawable.tools);
menu.setHeaderTitle("选择背景色");
}
// 上下菜单的菜单项被单击时触发该方法。
@Override
public boolean onContextItemSelected(MenuItem mi)
{
switch (mi.getItemId())
{
case MENU1:
mi.setChecked(true);
txt.setBackgroundColor(Color.RED);
break;
case MENU2:
mi.setChecked(true);
txt.setBackgroundColor(Color.GREEN);
break;
}
return true;
}
< ------------使用XML资源文件定义菜单----------- >
//当用户单击MENU键时触发该方法
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflator = new MenuInflater(this);
// 状态R.menu.context对应的菜单,并添加到menu中
inflator.inflate(R.menu.my_menu, menu);
return super.onCreateOptionsMenu(menu);
}
menu/my_menu.xml
@Override
// 选项菜单的菜单项被单击后的回调方法
public boolean onOptionsItemSelected(MenuItem mi)
{
if(mi.isCheckable())
{
mi.setChecked(true); //②
}
// 判断单击的是哪个菜单项,并针对性的作出响应。
switch (mi.getItemId())
{
case R.id.font_10:
txt.setTextSize(10 * 2);
break;
......
}
return true;
}
// 为文本框注册上下文菜单
registerForContextMenu(txt);
// 创建上下文菜单时触发该方法
@Override
public void onCreateContextMenu(ContextMenu menu, View source,
ContextMenu.ContextMenuInfo menuInfo)
{
MenuInflater inflator = new MenuInflater(this);
// 状态R.menu.context对应的菜单,并添加到menu中
inflator.inflate(R.menu.context, menu);
menu.setHeaderIcon(R.drawable.tools);
menu.setHeaderTitle("请选择背景色");
}
menu/context.xml
- android:id="@+id/red"
android:title="@string/red_title"
android:alphabeticShortcut="r"/>
- android:id="@+id/green"
android:title="@string/green_title"
android:alphabeticShortcut="g"/>
// 上下文菜单中菜单项被单击时触发该方法。
@Override
public boolean onContextItemSelected(MenuItem mi)
{
mi.setChecked(true); //①
switch (mi.getItemId())
{
case R.id.red:
mi.setChecked(true);
txt.setBackgroundColor(Color.RED);
break;
......
}
return true;
}
< ------------使用PopupMenu创建弹出式菜单----------- >
// 创建PopupMenu对象
PopupMenu popup = = new PopupMenu(this, button);
// 将R.menu.popup_menu菜单资源加载到popup菜单中
getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
// 为popup菜单的菜单项单击事件绑定事件监听器
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener()
{
@Override
public boolean onMenuItemClick(MenuItem item)
{
switch (item.getItemId())
{
case R.id.exit:
// 隐藏该对话框
popup.dismiss();
break;
default:
// 使用Toast显示用户点击的菜单项
Toast.makeText(PopupMenuTest.this,"您单击了【" + item.getTitle() + "】菜单项", Toast.LENGTH_SHORT).show();
}
return true;
}
});
popup.show();
menu/popup_menu.xml
- android:id="@+id/search"
android:icon="@android:drawable/ic_menu_search"
android:title="查找" />
- android:id="@+id/add"
android:icon="@android:drawable/ic_menu_add"
android:title="添加" />
- android:id="@+id/edit"
android:icon="@android:drawable/ic_menu_edit"
android:title="编辑">
- android:id="@+id/copy"
android:title="复制" />
- android:id="@+id/cut"
android:title="剪切" />
- android:id="@+id/paste"
android:title="粘贴" />
- android:id="@+id/exit"
android:title="隐藏菜单" />
五、活动条ActionBar(安卓 3.0)
活动条ActionBar位于传统标题栏的位置,也就是显示的屏幕的顶部。ActionBar可显示应用的图标和Activity标题,还可以显示活动项(Action Item).
活动条ActionBar提供了如下功能:
1.显示选项菜单的菜单项(将菜单项显示成Action Item)
2.使用程序图标作为返回Home主屏或向上的导航操作
3.提供交互式View作为Action View
4.提供基于Tab的导航方式,可以切换多个Fragment
5.提供基于下拉的导航
android:theme="@android:style/Theme.Holo.NoActionBar" //关闭ActionBar
< --- 启动ActionBar --- >
// 获取该Activity的ActionBar,
// 只有当应用主题没有关闭ActionBar时,该代码才能返回ActionBar
ActionBar actionBar = getActionBar();
// 显示ActionBar
actionBar.show();
// 隐藏ActionBar
actionBar.hide();
< ------使用ActionBar显示选项菜单------ >
手机如果没有Menu键,可以将选项菜单显示成ActionItem
项目中推荐使用XML来定义菜单
- android:title="@string/font_size"
android:showAsAction="always|withText"
/*** android:showAsAction这个属性可接受的值有:
1、always:这个值会使菜单项一直显示在Action Bar上。
2、ifRoom:如果有足够的空间,这个值会使菜单项显示在Action Bar上。
3、never:这个值使菜单项永远都不出现在Action Bar上。
4、withText:这个值使菜单项和它的图标,菜单文本一起显示。
5.collapseActionView:折叠成普通菜单项
***/
android:icon="@drawable/font">
- android:id="@+id/font_10"
android:title="@string/font_10"/>
- android:id="@+id/font_12"
android:title="@string/font_12"/>
ActionBar actionBar = getActionBar();
// 设置是否显示应用程序图标
actionBar.setDisplayShowHomeEnabled(true);
// 将应用程序图标设置为可点击的按钮
actionBar.setHomeButtonEnabled(true);
// 将应用程序图标设置为可点击的按钮,并在图标上添加向左箭头
actionBar.setDisplayHomeAsUpEnabled(true);
android.R.id.home:点击应用图标时响应
< ------添加Action View -------- >
- android:id="@+id/search"
android:title="@string/menu_settings"
android:orderInCategory="100"
android:showAsAction="always"
android:actionViewClass="android.widget.SearchView"/> //添加搜索框
- android:id="@+id/progress"
android:title="@string/menu_settings"
android:orderInCategory="100"
android:showAsAction="always"
android:actionLayout="@layout/clock"/> //添加模拟时钟(自定义View)
clock.xml:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
< ---------使用ActionBar实现Tab导航---------- >
public class ActionBar_TabNav extends Activity implementsActionBar.TabListener
{
private static final String SELECTED_ITEM = "selected_item";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ActionBar actionBar = getActionBar();
// 设置ActionBar的导航方式:Tab导航
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// 依次添加3个Tab页,并为3个Tab标签添加事件监听器
actionBar.addTab(actionBar.newTab().setText("第一页")
.setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第二页")
.setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第三页")
.setTabListener(this));
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
if (savedInstanceState.containsKey(SELECTED_ITEM))
{
// 选中前面保存的索引对应的Fragment页
getActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(SELECTED_ITEM));
}
}
@Override
public void onSaveInstanceState(Bundle outState)
{
// 将当前选中的Fragment页的索引保存到Bundle中
outState.putInt(SELECTED_ITEM,
getActionBar().getSelectedNavigationIndex());
}
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction)
{
}
// 当指定Tab被选中时激发该方法
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction)
{
// 创建一个新的Fragment对象
Fragment fragment = new DummyFragment();
// 创建一个Bundle对象,用于向Fragment传入参数
Bundle args = new Bundle();
args.putInt(DummyFragment.ARG_SECTION_NUMBER,
tab.getPosition() + 1);
// 向fragment传入参数
fragment.setArguments(args);
// 获取FragmentTransaction对象
FragmentTransaction ft = getFragmentManager().beginTransaction();
// 使用fragment代替该Activity中的container组件
ft.replace(R.id.container, fragment);
// 提交事务
ft.commit();
}
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction)
{
}
}
public class DummyFragment extends Fragment
{
public static final String ARG_SECTION_NUMBER = "section_number";
// 该方法的返回值就是该Fragment显示的View组件
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
TextView textView = new TextView(getActivity());
textView.setGravity(Gravity.CENTER_HORIZONTAL);
// 获取创建该Fragment时传入的参数Bundle
Bundle args = getArguments();
// 设置TextView显示的文本
textView.setText(args.getInt(ARG_SECTION_NUMBER) + "");
textView.setTextSize(30);
// 返回该TextView
return textView;
}
}
< ---------使用ActionBar实现TabSwipe导航---------- >
public class ActionBar_TabSwipeNav extends FragmentActivity
implements ActionBar.TabListener
{
ViewPager viewPager;
ActionBar actionBar;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取ActionBar对象
actionBar = getActionBar();
// 获取ViewPager
viewPager = (ViewPager) findViewById(R.id.pager);
// 创建一个FragmentPagerAdapter对象,该对象负责为ViewPager提供多个Fragment
FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(
getSupportFragmentManager())
{
// 获取第position位置的Fragment
@Override
public Fragment getItem(int position)
{
Fragment fragment = new DummyFragment();
Bundle args = new Bundle();
args.putInt(DummyFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
// 该方法的返回值i表明该Adapter总共包括多少个Fragment
@Override
public int getCount()
{
return 3;
}
// 该方法的返回值决定每个Fragment的标题
@Override
public CharSequence getPageTitle(int position)
{
switch (position)
{
case 0:
return "第一页";
case 1:
return "第二页";
case 2:
return "第三页";
}
return null;
}
};
// 设置ActionBar使用Tab导航方式
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// 遍历pagerAdapter对象所包含的全部Fragment。
// 每个Fragment对应创建一个Tab标签
for (int i = 0; i < pagerAdapter.getCount(); i++)
{
actionBar.addTab(actionBar.newTab()
.setText(pagerAdapter.getPageTitle(i))
.setTabListener(this));
}
// 为ViewPager组件设置FragmentPagerAdapter
viewPager.setAdapter(pagerAdapter); //①
// 为ViewPager组件绑定事件监听器
viewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener()
{
// 当ViewPager显示的Fragment发生改变时激发该方法
@Override
public void onPageSelected(int position)
{
actionBar.setSelectedNavigationItem(position);
}
});
}
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction)
{
}
// 当指定Tab被选中时激发该方法
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction)
{
viewPager.setCurrentItem(tab.getPosition()); //②
}
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction)
{
}
}
main.xml:
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:textColor="#fff"
android:paddingTop="4dp"
android:paddingBottom="4dp" />
< ---------使用ActionBar实现下拉式导航---------- >
public class ActionBar_DropDownNav extends Activity implements
ActionBar.OnNavigationListener
{
private static final String SELECTED_ITEM = "selected_item";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ActionBar actionBar = getActionBar();
// 设置ActionBar是否显示标题
actionBar.setDisplayShowTitleEnabled(true);
// 设置导航模式,使用List导航
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
// 为actionBar安装ArrayAdapter
actionBar.setListNavigationCallbacks(
new ArrayAdapter(ActionBar_DropDownNav.this,
android.R.layout.simple_list_item_1,
android.R.id.text1, new String[]
{"第一页","第二页","第三页" }), this);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
if (savedInstanceState.containsKey(SELECTED_ITEM))
{
// 选中前面保存的索引对应的Fragment页
getActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(SELECTED_ITEM));
}
}
@Override
public void onSaveInstanceState(Bundle outState)
{
// 将当前选中的Fragment页的索引保存到Bundle中
outState.putInt(SELECTED_ITEM,
getActionBar().getSelectedNavigationIndex());
}
// 当导航项被选中时激发该方法
@Override
public boolean onNavigationItemSelected(int position, long id)
{
// 创建一个新的Fragment对象
Fragment fragment = new DummyFragment();
// 创建一个Bundle对象,用于向Fragment传入参数
Bundle args = new Bundle();
args.putInt(DummyFragment.ARG_SECTION_NUMBER, position + 1);
// 向fragment传入参数
fragment.setArguments(args);
// 获取FragmentTransaction对象
FragmentTransaction ft = getFragmentManager().beginTransaction();
// 使用fragment代替该Activity中的container组件
ft.replace(R.id.container, fragment);
// 提交事务
ft.commit();
return true;
}
}