一、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; } }