安卓基础学习_应用的界面编程

一、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" 
<!--通过checkMark设置该文本框的勾选图标-->
android:checkMark="@drawable/ok"
<!-- 通过android:background指定背景 -->
android:background="@drawable/bg_border" //红色边框,bg_border.xml如下
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置背景色为透明色 -->
	<solid android:color="#0000"/>
	<!-- 设置红色边框 -->
	<stroke android:width="4px" android:color="#f00" />
</shape>
<!-- 通过android:drawableLeft绘制一张图片 -->
android:background="@drawable/bg_border2" //圆角边框,渐变背景
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
<!-- 指定圆角矩形的4个圆角的半径 -->
	<corners 
	    android:topLeftRadius="20px"
	android:topRightRadius="5px"
	android:bottomRightRadius="20px"
	android:bottomLeftRadius="5px"/>
	<!-- 指定边框线条的宽度和颜色 -->
	<stroke android:width="4px" android:color="#f0f" />
	<!-- 指定使用渐变背景色,使用sweep类型的渐变
	颜色从红色→绿色→蓝色 -->
	<gradient 
	    android:startColor="#f00"
	    android:centerColor="#0f0"
	    android:endColor="#00f"
	    android:type="sweep"/>
</shape>
<!--文本框默认提示 -->
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如下所示
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<!-- 指定按钮按钮下时的图片 -->
	<item 
	    android:state_pressed="true"
		android:drawable="@drawable/red"
	/>
	<!-- 指定按钮松开时的图片 -->	
	<item 
	    android:state_pressed="false"
		android:drawable="@drawable/purple"
	/>
</selector>
<!--单选框 -->
<RadioGroup android:id="@+id/rg"
	android:orientation="horizontal"
	android:layout_gravity="center_horizontal">
	<!-- 定义两个单选框 -->
	<RadioButton 
	    android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:id="@+id/male"
		android:text="男"
		android:checked="true" />
	<RadioButton 
	    android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:id="@+id/female"
		android:text="女" />
</RadioGroup>
<!--复选框 -->
<CheckBox 
    android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="红色"
	android:checked="true"/>
<CheckBox 
    android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="蓝色"/>
<CheckBox 
    android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="绿色" />
<!-- ToggleButton状态开关按钮 -->
<ToggleButton 
android:id="@+id/toggle"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:textOff="横向排列"
	android:textOn="纵向排列"
	android:checked="true" />
<!-- Switch开关按钮 -->
<Switch android:id="@+id/switcher"
    android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:textOff="横向排列"
	android:textOn="纵向排列"
	android:thumb="@drawable/check"
	android:checked="true"/>
<!-- 模拟时钟 -->
<AnalogClock  
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" />
<!-- 数字时钟 -->
<DigitalClock
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	android:textSize="14pt"
	android:textColor="#f0f"
	android:drawableRight="@drawable/ic_launcher" />
<!-- 模拟时钟,并使用自定义表盘、时针图片 -->
<AnalogClock  
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	android:dial="@drawable/watch"
	android:hand_minute="@drawable/hand"/>
<!-- Chronometer计时器 -->
<Chronometer
	android:id="@+id/test"  
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	android:textSize="12pt"
	android:textColor="#ffff0000" />

2.ImageView及其子类
<!-- ZoomButton计缩放按钮 -->
<ZoomButton
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:id="@+id/btn_zoom_down"
	android:src="@android:drawable/btn_minus" />
<!-- ZoomControls缩放组件 -->
<ZoomControls 
    android:id="@+id/zoomControls1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"/>
<!-- QuickContactBadge关联联系人 -->
<QuickContactBadge
	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的数组资源
<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<String> adapter2 = new 
ArrayAdapter<String>(this, R.layout.checked_item, arr2);
// 为ListView设置Adapter
list2.setAdapter(adapter2);

(3)、基于ListActivity实现列表
String[] arr = { "孙悟空", "猪八戒", "唐僧" };
// 创建ArrayAdapter对象
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this,android.R.layout.simple_list_item_multiple_choice, arr);
// 设置该窗口显示列表
setListAdapter(adapter);
//界面布局文件中应该包含id为"@+id/android:list"的ListView
<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<Map<String, Object>> listItems = 
				new ArrayList<Map<String, Object>>();
		for (int i = 0; i < names.length; i++)
		{
			Map<String, Object> listItem = new HashMap<String, Object>();
			listItem.put("header", imageIds[i]);
			listItem.put("personName", names[i]);
			listItem.put("desc", descs[i]);
			listItems.add(listItem);
		}
		// 创建一个SimpleAdapter
		SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems,
			R.layout.simple_item, 
			new String[] { "personName", "header" , "desc"},
			new int[] { R.id.name, R.id.header , R.id.desc });
		ListView list = (ListView) findViewById(R.id.mylist);
		// 为ListView设置Adapter
		list.setAdapter(simpleAdapter);
		// 为ListView的列表项单击事件绑定事件监听器
		list.setOnItemClickListener(new OnItemClickListener()
		{
			// 第position项被单击时激发该方法。
			public void onItemClick(AdapterView<?> parent, View view,int position, long id)
			{
				System.out.println(names[position]+ "被单击了");
			}
		});
	}
}

(5)、扩展BaseAdapter实现不存储列表项的ListView
public class BaseAdapterTest extends Activity
{
	ListView myList;
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		myList = (ListView) findViewById(R.id.myList);
		BaseAdapter adapter = new BaseAdapter()
		{
			public int getCount()
			{
				// 指定一共包含40个选项
				return 40;
			}
			public Object getItem(int position)
			{
				return null;
			}
			// 重写该方法,该方法的返回值将作为列表项的ID
			public long getItemId(int position)
			{
				return position;
			}
			// 重写该方法,该方法返回的View将作为列表框
			public View getView(int position, View convertView , ViewGroup parent)
			{
				// 创建一个LinearLayout,并向其中添加2个组件
				LinearLayout line = new LinearLayout(BaseAdapterTest.this);
				line.setOrientation(0);
				ImageView image = new ImageView(BaseAdapterTest.this);
				image.setImageResource(R.drawable.ic_launcher);
				TextView text = new TextView(BaseAdapterTest.this);
				text.setText("第" + (position +1 ) + "个列表项");
				text.setTextSize(20);
				text.setTextColor(Color.RED);
				line.addView(image);
				line.addView(text);
				// 返回LinearLayout实例
				return line;
			}
		};
		myList.setAdapter(adapter);
	}
}

以上方法完全适用于AdapterView的其他类:GridView、Spinner、Gallery、AdapterViewFlipper等。

自动完成文本框(AutoCompleteTextView)的功能和用法
<!-- 定义一个自动完成文本框,指定输入一个字符后进行提示 -->
<AutoCompleteTextView
	android:id="@+id/auto"
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content" 
	android:completionHint="请选择您喜欢的图书:"
	android:dropDownHorizontalOffset="10dp"
	android:completionThreshold="1"/>
<!-- 定义一个MultiAutoCompleteTextView组件 -->
<MultiAutoCompleteTextView
    android:id="@+id/mauto"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:completionThreshold="1"/>

网格视图(GridView)功能与用法
<GridView  
	android:horizontalSpacing="1pt"
	android:verticalSpacing="1pt"
	android:numColumns="4"
	android:gravity="center"
	……
/>

// 创建一个List对象,List对象的元素是Map
List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
for (int i = 0; i < imageIds.length; i++)
{
	Map<String, Object> listItem = new HashMap<String, Object>();
	listItem.put("image", imageIds[i]);
	listItems.add(listItem);
}
// 创建一个SimpleAdapter
SimpleAdapter simpleAdapter = new SimpleAdapter(this,listItems, R.layout.cell, new String[] { "image" },new int[] { R.id.image1 });
// 使用/layout/cell.xml文件作为界面布局
// 为GridView设置Adapter
grid.setAdapter(simpleAdapter);

可展开的列表组件(ExpandableListView)
<ExpandableListView
	android:id="@+id/list"
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content" 
	android:childIndicator="@drawable/ic_launcher"
/>
public class ExpandableListViewTest extends Activity
{
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		//创建一个BaseExpandableListAdapter对象
		ExpandableListAdapter adapter = new BaseExpandableListAdapter()
		{
			int[] logos = new int[]
			{
				R.drawable.p,
				R.drawable.z,
				R.drawable.t
			};
			private String[] armTypes = new String[]
				{ "神族兵种", "虫族兵种", "人族兵种"};
			private String[][] arms = new String[][]
			{
				{ "狂战士", "龙骑士", "黑暗圣堂", "电兵" },
				{ "小狗", "刺蛇", "飞龙", "自爆飞机" },
				{ "机枪兵", "护士MM" , "幽灵" }
			};
			// 获取指定组位置、指定子列表项处的子列表项数据
			public Object getChild(int groupPosition, int childPosition)
			{
				return arms[groupPosition][childPosition];
			}
			public long getChildId(int groupPosition, int childPosition)
			{
				return childPosition;
			}
			public int getChildrenCount(int groupPosition)
			{
				return arms[groupPosition].length;
			}
			private TextView getTextView()
			{
				AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
						ViewGroup.LayoutParams.MATCH_PARENT, 64);
				TextView textView = new TextView(ExpandableListViewTest.this);
				textView.setLayoutParams(lp);
				textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
				textView.setPadding(36, 0, 0, 0);
				textView.setTextSize(20);
				return textView;
			}
			// 该方法决定每个子选项的外观
			public View getChildView(int groupPosition, int childPosition,
					boolean isLastChild, View convertView, ViewGroup parent)
			{
				TextView textView = getTextView();
				textView.setText(getChild(groupPosition, childPosition).toString());
				return textView;
			}
			// 获取指定组位置处的组数据
			public Object getGroup(int groupPosition)
			{
				return armTypes[groupPosition];
			}
			public int getGroupCount()
			{
				return armTypes.length;
			}
			public long getGroupId(int groupPosition)
			{
				return groupPosition;
			}
			// 该方法决定每个组选项的外观
			public View getGroupView(int groupPosition, boolean isExpanded,
					View convertView, ViewGroup parent)
			{
				LinearLayout ll = new LinearLayout(ExpandableListViewTest.this);
				ll.setOrientation(0);
				ImageView logo = new ImageView(ExpandableListViewTest.this);
				logo.setImageResource(logos[groupPosition]);
				ll.addView(logo);
				TextView textView = getTextView();
				textView.setText(getGroup(groupPosition).toString());
				ll.addView(textView);
				return ll;
			}
			public boolean isChildSelectable(int groupPosition,
					int childPosition)
			{
				return true;
			}
			public boolean hasStableIds()
			{
				return true;
			}
		};
		ExpandableListView expandListView = (ExpandableListView) findViewById(R.id.list);
		expandListView.setAdapter(adapter);
	}
}

列表选择框(Spinner)的功能和用法
<!-- 定义了一个Spinner组件,指定该显示该Spinner组件的数组 -->
<Spinner
	……
	android:entries="@array/books" 
	android:prompt="@string/tip"
/>

<Spinner
	android:id="@+id/spinner"
	android:prompt="@string/tip"
	......
/>
String[] arr = { "孙悟空", "猪八戒", "唐僧" };
// 创建ArrayAdapter对象
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this,android.R.layout.simple_list_item_multiple_choice, arr);
// 为Spinner设置Adapter
spinner.setAdapter(adapter);

画廊视图(Gallery)的功能和用法(已经过时,用ViewPager和HorizontalScrollView代替,新平台上尽量少用Gallery组件)
<!-- 定义一个Gallery组件 -->
<Gallery 
	android:id="@+id/gallery"
	android:layout_marginTop="2dp" 
	android:unselectedAlpha="0.6" //未被选中时的透明度
	android:spacing="2pt"
	......
/>
BaseAdapter adapter = new BaseAdapter()
{
	public int getCount()
	{
		return imageIds.length;
	}
	public Object getItem(int position)
	{
		return position;
	}
	public long getItemId(int position)
	{
		return position;
	}
	// 该方法的返回的View就是代表了每个列表项
	public View getView(int position, View convertView, ViewGroup parent)
	{
		// 创建一个ImageView
		ImageView imageView = new ImageView(GallaryTest.this);
		imageView.setImageResource(imageIds[position]);
		// 设置ImageView的缩放类型
		imageView.setScaleType(ImageView.ScaleType.FIT_XY);
		// 为imageView设置布局参数
		imageView.setLayoutParams(new Gallery.LayoutParams(75, 100));
		TypedArray typedArray = obtainStyledAttributes(R.styleable.Gallery);
	imageView.setBackgroundResource(typedArray.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0));
		return imageView;
	}
};
gallery.setAdapter(adapter);

AdapterViewFlipper的功能与用法
AdapterViewFlipper继承了AdapterViewAnimator,它也会显示Adapter提供的多个View组件,但它每次只能显示一个View组件,程序可通过showPrevious()和showNext()方法控制该组件显示上一个、下一个组件,还可以调用startFlipping()控制它“自动播放”下一个View组件。
----自动播放的图片库----
<AdapterViewFlipper
	android:id="@+id/flipper"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:flipInterval="5000" //每个五秒自动切换
	android:layout_alignParentTop="true"
/>

BaseAdapter adapter = new BaseAdapter()
{
	public int getCount()
	{
		return imageIds.length;
	}
	public Object getItem(int position)
	{
		return position;
	}
	public long getItemId(int position)
	{
		return position;
	}
	// 该方法的返回的View就是代表了每个列表项
	public View getView(int position, View convertView, ViewGroup parent)
	{
		// 创建一个ImageView
		ImageView imageView = new ImageView(AdapterViewFlipperTest.this);
		imageView.setImageResource(imageIds[position]);
		// 设置ImageView的缩放类型
		imageView.setScaleType(ImageView.ScaleType.FIT_XY);
		// 为imageView设置布局参数
		imageView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		return imageView;
	}
};
flipper.setAdapter(adapter);

// 显示上一个组件
flipper.showPrevious();
// 显示下一个组件
flipper.showNext();
// 开始自动播放
flipper.startFlipping();
// 停止自动播放
flipper.stopFlipping();

StackView的功能与用法
StackView也是AdapterViewAnimator的子类,它也用于显示Adapter提供的系列View。StackView将会以”堆叠”的方式来显示多个列表项。程序可通过showPrevious()和showNext()方法控制该组件显示上一个、下一个组件。
为了控制StackView显示的View,StackView提供了两种控制方式:
1>.拖走StackView中处于顶端的View,下一个View将会显示出来
2>.将上一个View拖进StackView,将使之显示出来
<StackView
	android:id="@+id/mStackView"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:loopViews="true" //循环
/>

stackView = (StackView) findViewById(R.id.mStackView);
// 创建一个List对象,List对象的元素是Map
List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
for (int i = 0; i < imageIds.length; i++)
{
	Map<String, Object> listItem = new HashMap<String, Object>();
	listItem.put("image", imageIds[i]);
	listItems.add(listItem);
}
// 创建一个SimpleAdapter
SimpleAdapter simpleAdapter = new SimpleAdapter(this,listItems, R.layout.cell, new String[] { "image" },new int[] { R.id.image1 });
// 使用/layout/cell.xml文件作为界面布局		
stackView.setAdapter(simpleAdapter);

// 显示上一个组件
stackView.showPrevious();
// 显示下一个组件
stackView.showNext();

4. ProgressBar及其子类
ProgressBar的用法
<!-- 定义一个大环形进度条 -->
<ProgressBar
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content"
	style="@android:style/Widget.ProgressBar.Large"
/>
<!-- 定义一个中等大小的环形进度条 -->
<ProgressBar
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content"
/>
<!-- 定义一个小环形进度条 -->
<ProgressBar
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content"
	style="@android:style/Widget.ProgressBar.Small"
/>
<!-- 定义一个水平进度条 -->
<ProgressBar
	android:id="@+id/bar"
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content"
	android:max="100"
	style="@android:style/Widget.ProgressBar.Horizontal"
/>
<!-- 定义一个水平进度条,并改变轨道外观 -->
<ProgressBar
	android:id="@+id/bar2"
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content"
	android:max="100"
	android:progressDrawable="@drawable/my_bar"
	style="@android:style/Widget.ProgressBar.Horizontal"
/>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
	<!-- 定义轨道的背景 -->
	<item 
	    android:id="@android:id/background"
		android:drawable="@drawable/no" 
	/>
	<!-- 定义轨道上已完成部分的样式 -->
	<item 
	    android:id="@android:id/progress"
		android:drawable="@drawable/ok" 
	/>
</layer-list>

显示在标题上的进度条
//设置窗口特征:启用显示进度的进度条
requestWindowFeature(Window.FEATURE_PROGRESS);  //①
//显示带进度的进度条。
setProgressBarVisibility(true);
//设置进度条的进度
setProgress(4500);
//隐藏带进度的进度条。
setProgressBarVisibility(false);

//设置窗口特征:启用不显示进度的进度条
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); //②
//显示不带进度的进度条。
setProgressBarIndeterminateVisibility(true);
//隐藏不带进度的进度条。
setProgressBarIndeterminateVisibility(false);

拖动条(SeekBar)的功能和用法
<!-- 定义一个拖动条,并改变它的滑块外观 -->
<SeekBar
	android:id="@+id/seekbar"
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content" 
	android:max="255"
	android:progress="255"
	android:thumb="@drawable/ic_launcher" //拖动条上的滑块
/>

星级评分条(RatingBar)
<!-- 定义一个星级评分条 -->	
<RatingBar 
	android:id="@+id/rating"
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	android:numStars="5" //5颗星
	android:max="255"
	android:progress="255"
	android:stepSize="0.5" //最小值0.5
/>

5.ViewAnimator及其子类
ViewAnimator是一个基类,它继承了FrameLayout,因此它表现出了FrameLayout的特征,可以将多个View组件”叠”在一起。
ViewSwitcher的功能与用法
ViewSwitcher代表了视图切换组件,它本身继承了FrameLayout,因此可以将多个View层叠在一起,每次只显示一个组件,当程序控制从一个View切换到另一个View时,ViewSwitcher支持指定动画效果。
为了给ViewSwitcher添加多个组件,一般通过调用ViewSwitcher的setFactory(ViewSwitcher.ViewFactory)方法为之设置ViewFactory,并由该ViewFactory为之创建View即可。

<!-- 定义一个ViewSwitcher组件 -->
<ViewSwitcher
	android:id="@+id/viewSwitcher"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent" 
/>
switcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
switcher.setFactory(new ViewFactory()
{
	// 实际上就是返回一个GridView组件
	public View makeView()
	{
		// 加载R.layout.slidelistview组件,实际上就是一个GridView组件。
		return inflater.inflate(R.layout.slidelistview, null);
	}
});

ImageSwitcher的用法
1>.为ImageSwitcher提供一个ViewFactory,该Factory生成的View组件必须是ImageView
2>.需要切换图片时,只需要调用ImageSwitcher的setImageDrawable(Drawable drawable)、setImageResource(int resid)和setImageURI(Uri uri)

<!-- 定义一个ImageSwitcher组件 -->
<ImageSwitcher android:id="@+id/switcher"
	android:layout_width="300dp"
	android:layout_height="300dp"
	android:layout_gravity="center_horizontal"
	android:inAnimation="@android:anim/fade_in"
	android:outAnimation="@android:anim/fade_out"
/>
// 获取显示图片的ImageSwitcher
switcher = (ImageSwitcher)findViewById(R.id.switcher);
// 为ImageSwitcher设置图片切换的动画效果
switcher.setFactory(new ViewFactory()
{
	public View makeView()
	{
		// 创建ImageView对象
		ImageView imageView = new ImageView(Main.this);
		imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
		imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
		// 返回ImageView对象
		return imageView;
	}
});

TextSwitcher的用法
1>.TextSwitcher需要设置一个ViewFactory,该Factory生成的View组件必须是TextView
2>.需要切换文本时,只需要调用TextSwitcher的setText();方法修改即可
<!-- 定义一个TextSwitcher,并指定了文本切换时的动画效果 -->
<TextSwitcher
    android:id="@+id/textSwitcher"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:inAnimation="@android:anim/slide_in_left"
	android:outAnimation="@android:anim/slide_out_right"
	android:onClick="next"
/>
textSwitcher = (TextSwitcher) findViewById(R.id.textSwitcher);
textSwitcher.setFactory(new ViewSwitcher.ViewFactory()
{
	public View makeView()
	{
		TextView tv = new TextView(TextSwitcherTest.this);
		tv.setTextSize(40);
		tv.setTextColor(Color.MAGENTA);
		return tv;
	}
});
// 调用next方法显示下一个字符串
next(null);
// 事件处理函数,控制显示下一个字符串
public void next(View source)
{
	textSwitcher.setText(strs[curStr++ % strs.length]); 
}

ViewFlipper的功能与用法
	ViewFlipper是继承了ViewAnimator,它调用了addView(View v)添加多个组件,一旦向ViewFlipper中添加了多个组件后,ViewFlipper可以使用动画控制多个组件切换的效果。
	ViewFlipper与AdapterViewFlipper有较大的相似性,他们的区别是:ViewFlipper需要开发者通过addView(View v)添加多个组件,而AdapterViewFlipper则只要传入一个Adapter,Adapter将会负责提供多个View。

<ViewFlipper
	android:id="@+id/details"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:persistentDrawingCache="animation"
	android:flipInterval="1000" >
	
	<ImageView
		android:src="@drawable/ee"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content">
	</ImageView>
	......添加组件......
	<ImageView
		android:src="@drawable/ee"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content">
	</ImageView>
</ViewFlipper>

6.其他杂项组件
<1>.Toast
Toast具有如下两个特点:
☆.Toast提示信息不会获得焦点
☆.Toast提示信息过一段时间会自动消失

<-----创建一个简单的Toast提示信息----->
Toast toast = Toast.makeText(Main.this, "简单的提示信息", Toast.LENGTH_SHORT);
toast.show();

<-----创建一个带图片的Toast提示信息----->
Toast toast = new Toast(Main.this);
// 设置Toast的显示位置
toast.setGravity(Gravity.CENTER, 0, 0);
// 创建一个ImageView
ImageView image = new ImageView(Main.this);
image.setImageResource(R.drawable.tools);
// 创建一个LinearLayout容器
LinearLayout ll = new LinearLayout(Main.this);
ll.setBackgroundColor(Color.BLACK);
// 向LinearLayout中添加图片、原有的View
ll.addView(image);
// 创建一个ImageView
TextView textView = new TextView(Main.this);
textView.setText("带图片的提示信息");
// 设置文本框内字体的大小和颜色
textView.setTextSize(30);
textView.setTextColor(Color.MAGENTA);
ll.addView(textView);
// 设置Toast显示自定义View				
toast.setView(ll);
// 设置Toast的显示时间
toast.setDuration(Toast.LENGTH_LONG);
toast.show();
 
 
<2>.CalendarView
<!--CalendarView-->
<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
<!-- 定义一个DatePicker组件 -->
<DatePicker 
	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"
/>
<!-- 定义一个TimePicker组件 -->
<TimePicker 
	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中显示当前日期、时间的方法
	}
});

<!-- 定义一个NumberPicker组件 -->
<NumberPicker
	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
<!-- 定义一个SearchView -->
<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(标签页)
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/tabhost"
>
	<LinearLayout
	android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
	>
		<TabWidget
		android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:id="@android:id/tabs"
		/>
		<FrameLayout
		android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:id="@android:id/tabcontent"
		>
			<LinearLayout
			android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:id="@+id/page1"
			>
			<TextView
							   />
			</LinearLayout>
		
		<LinearLayout
			android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:id="@+id/page2"
			>
			<TextView
							   />
			</LinearLayout>
			
		<LinearLayout
			android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:id="@+id/page3"
			>
			<TextView
							   />
			</LinearLayout>
		</FrameLayout>
	</LinearLayout>
</TabHost>

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
<!-- 定义ScrollView,为里面的组件添加垂直滚动条 -->
<!-- ScrollView里最多只能包含一个组件 -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent"
	android:layout_height="match_parent" >
<!-- 定义HorizontalScrollView,为里面的组件添加水平滚动条 -->	
<HorizontalScrollView
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content" >
	<LinearLayout 
		android:orientation="vertical"
		android:layout_width="match_parent"
		android:layout_height="fill_parent" 
	>
		<TextView 
		...... 
		/>
	</LinearLayout>
</HorizontalScrollView>
</ScrollView>

<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<String>(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
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:title="@string/font_size"
	      android:icon="@drawable/font">
		<menu>
			<!-- 定义一组单选菜单项 -->
			<group android:checkableBehavior="single">
				<!-- 定义多个菜单项 -->
				<item
					android:id="@+id/font_10"
					android:title="@string/font_10"/>
				<item
					android:id="@+id/font_12"
					android:title="@string/font_12"/>
			</group>
		</menu>
	</item>
	<!-- 定义一个普通菜单项 -->
	<item android:id="@+id/plain_item"
		android:title="@string/plain_item">
	</item>
	<item android:title="@string/font_color"
		android:icon="@drawable/color">
		<menu>
			<!-- 定义一组允许复选的菜单项 -->
			<group>
				<!-- 定义3个菜单项 -->
				<item
					android:id="@+id/red_font"
					android:title="@string/red_title"/>
				<item
					android:id="@+id/green_font"
					android:title="@string/green_title"/>					
			</group>
		</menu>
	</item>
</menu>
@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
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
	<!-- 定义一组单选菜单项目 -->
	<group android:checkableBehavior="single">
		<!-- 定义2个菜单项 -->
		<item
			android:id="@+id/red"
			android:title="@string/red_title"
			android:alphabeticShortcut="r"/>
		<item
			android:id="@+id/green"
			android:title="@string/green_title"
			android:alphabeticShortcut="g"/>					
	</group>
</menu>
// 上下文菜单中菜单项被单击时触发该方法。
@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
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
	<item
		android:id="@+id/search"
		android:icon="@android:drawable/ic_menu_search"
		android:title="查找" />
	<item
		android:id="@+id/add"
		android:icon="@android:drawable/ic_menu_add"
		android:title="添加" />
	<item
		android:id="@+id/edit"
		android:icon="@android:drawable/ic_menu_edit"
		android:title="编辑">
		<menu>
			<item
				android:id="@+id/copy"
				android:title="复制" />
			<item
				android:id="@+id/cut"
				android:title="剪切" />			
			<item
				android:id="@+id/paste"
				android:title="粘贴" />			
		</menu>
	</item>
	<item
		android:id="@+id/exit"
		android:title="隐藏菜单" />
</menu>

五、活动条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来定义菜单
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
	<item 
	    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">
		<menu>
			<!-- 定义一组单选菜单项 -->
			<group android:checkableBehavior="single">
				<!-- 定义多个菜单项 -->
				<item
					android:id="@+id/font_10"
					android:title="@string/font_10"/>
				<item
					android:id="@+id/font_12"
					android:title="@string/font_12"/>		
			</group>
		</menu>
	</item>
</menu>

ActionBar actionBar = getActionBar();
// 设置是否显示应用程序图标
actionBar.setDisplayShowHomeEnabled(true);
// 将应用程序图标设置为可点击的按钮
actionBar.setHomeButtonEnabled(true);
// 将应用程序图标设置为可点击的按钮,并在图标上添加向左箭头
actionBar.setDisplayHomeAsUpEnabled(true);

android.R.id.home:点击应用图标时响应

< ------添加Action View -------- >
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
	android:id="@+id/search"
	android:title="@string/menu_settings"
	android:orderInCategory="100"
	android:showAsAction="always"
	android:actionViewClass="android.widget.SearchView"/> //添加搜索框
<item
	android:id="@+id/progress"
	android:title="@string/menu_settings"
	android:orderInCategory="100"
	android:showAsAction="always"
	android:actionLayout="@layout/clock"/> //添加模拟时钟(自定义View)
</menu>

clock.xml:
<AnalogClock
    xmlns:android="http://schemas.android.com/apk/res/android"
	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:
<android.support.v4.view.ViewPager
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/pager"
	android:layout_width="match_parent"
	android:layout_height="match_parent">
	<!-- 定义导航状态条组件 -->
	<android.support.v4.view.PagerTitleStrip 
		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" />	
</android.support.v4.view.ViewPager>

< ---------使用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<String>(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;
	}
}

你可能感兴趣的:(安卓基础学习_应用的界面编程)