1、常用五种布局:
LinearLayout、RelativeLayout、FrameLayout、AbsoluteLayout、TableLayout
线性布局 相对布局 帧布局 绝对布局 表格布局
开发中主要用线性布局和相对布局。
表格布局用于计算机布局等!
帧布局主要用于页面加载,霓虹灯等
绝对布局不怎么用
2、在TextView中设置该控件的gravity属性——表示:该控件的文本相对该控件的位置(文本内容排布)
例如:设置TextView的gravity=“right”——表示:TextView的文本相对该TextView的right显示
3、常用的UI组件:
#TextView及其子类:TextView, EditText, Button,
单键按钮RadioButton, 复选框CheckBox,
状态开关按钮ToggleButton, 开关Switch,
时钟AnalogClock,DigitalClock,
计时器Chronometer
#ImageView及其子类
#AdapterView及其子类:列表视图ListView, ListActivity,
Adapter接口及实现类,
自动完成文本框AutoCompleteTextView,
网格视图GridView,
可展开的列表组件ExpandableListView,
Spinner,
画廊视图Gallery,
AdapterViewFlipper,
StackView
#ProgressBar及其子类:进度条ProgressBar, 拖动条SeekBar,
星级评分条RatingBar
#ViewAnimator及其子类:ViewSwitcher, 图像切换器ImageSwitcher,
文本切换器TextSwitcher,
ViewFlipper
#杂项组件:Toast显示提示信息框,
日历视图组件CalendarView,
日期、时间选择器DatePicker, TimePicker,
数值选择器NumberPicker,
搜索框SearchView,
选项卡TabHost,
滚动视图ScrollView,
Notification
#对话框:使用AlertDialog创建对话框
对话框风格的窗口
使用PopupWindow
使用DatePickerDialog, TimePickerDialog
使用ProgressDialog创建进度对话框
#菜单:选项菜单和子菜单SubMenu
使用监听器来监听菜单事件
创建复选菜单项和单选菜单项
设置与菜单项关联的Activity
上下文菜单
使用XML文件定义菜单
使用PopupMenu创建弹出式菜单
#使用活动条(ActionBar): 启用ActionBar
使用ActionBar显示选项菜单
启用程序图标导航
添加Action View
使用ActionBar实现Tab导航
使用ActionBar实现下拉式导航
4、事件处理:
Android提供两种方式的事件处理:基于回调的事件处理和基于监听器的事件处理。
public void onClick(View v):该方法必须有一个View类型的形参,该形参代表被单击的UI组件,当用户单击该UI组件时,系统将会激发android:onClick属性所指定的方法。
基于回调的事件处理:主要做法就是重写Android组件特定的回调方法,或者重写Activity的回调方法。Android为绝大部分界面组件都提供了事件响应的回调方法,开发者只要重写它们即可。
一般来说,基于回调的事件处理可用于处理一些具有通用性的事件,基于回调的时间处理代码会显得比较简洁。但对于某些特定的时间,无法使用基于回调的事件处理,只能采用基于监听的事件处理。
在基于事件监听的处理模型中,事件监听器必须实现事件监听器接口。Android为不同的界面组件提供了不同的监听器接口,这些接口通常以内部类的形式存在。以View类为例,它包含了如下几个内部接口:
View.OnClickListener:单击事件的事件监听器必须实现的接口;
View.OnCreateContextMenuListener:创建上下文菜单事件的事件监听器必须实现的接口;
View.onFocusChangeListener:焦点改变事件的事件监听器必须实现的接口;
View.OnKeyListener:按键事件的事件监听器必须实现的接口;
View.OnLongClickListener:长单击事件的事件监听器必须实现的接口;
View.OnTouchListener:触摸屏事件的事件监听器必须实现的接口;
*:与普通java方法调用不同的是:普通java程序里的方法是由程序主动调用的,事件处理中的事件处理器方法是由系统负责调用的。
所谓事件监听器:其实就是实现了特定接口的java类的实例;通常有5种形式: 内部类形式、外部类形式、Activity本身作为事件监听器类、匿名内部类形式、直接绑定到标签。
如果某个事件监听器确实需要被多个GUI界面所共享,而且主要是完成某种业务逻辑的实现,则可以考虑使用外部类的形式来定义事件监听器类。
public class SendSmsListener implements OnLongClickListener { private Activity act; private EditText address; private EditText content; public SendSmsListener(Activity act, EditText address, EditText content) { this.act = act; this.address = address; this.content = content; } @Override public boolean onLongClick(View source) { String addressStr = address.getText().toString(); String contentStr = content.getText().toString(); // 获取短信管理器 SmsManager smsManager = SmsManager.getDefault(); // 创建发送短信的PendingIntent PendingIntent sentIntent = PendingIntent.getBroadcast(act, 0, new Intent(), 0); // 发送文本短信 smsManager.sendTextMessage(addressStr, null, contentStr, sentIntent, null); Toast.makeText(act, "短信发送完成", Toast.LENGTH_LONG).show(); return false; } }
上面的事件监听器类没有与任何GUI界面耦合,创建该监听器对象时需要传入两个EditText对象和一个Activity对象,其中一个EditText用于作为收信人号码,一个EditText用于作为短信内容。
public class SendSms extends Activity { EditText address; EditText content; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取页面中收件人地址、短信内容 address = (EditText) findViewById(R.id.address); content = (EditText) findViewById(R.id.content); Button bn = (Button) findViewById(R.id.send); bn.setOnLongClickListenter(new SendSmsListener(this, address, content)); } }
*:实际上不推荐将业务逻辑实现写在事件监听器中,包含业务逻辑的事件监听器将导致程序的显示逻辑和业务逻辑耦合,从而增加程序后期的维护难度。如果确实有多个实现监听器需要实现相同的业务逻辑功能,可以考虑使用业务逻辑组件来定义业务逻辑功能,再让事件监听器来调用业务逻辑组件的业务逻辑方法。
直接绑定到标签:对于很多Android界面组件标签而言,它们都支持onClick属性,该属性的属性值就是一个形如xxx(View source)的方法的方法名。
<Button android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "单击我" android:onClick = "clickHandler" />
在界面布局文件中为Button按钮绑定一个事件处理方法:clickHandler,这就意味着开发者需要在该界面布局对应的Activity中定义一个void clickHandler(View source)方法,该方法将会负责处理该按钮上的单击事件。
public void clickHandler(View source) { EditText show = (EidtText) findViewById(R.id.show); show.setText("bn按钮被单击了"); }
5、基于回调的事件处理:事件源与事件监听器是统一的,或者说事件监听器完全消失了。当用户在GUI组件上激发某个事件时,组件自己特定的方法将会负责处理该事件。为了使用回调机制类处理GUI组件上所发生的事件,只能继承GUI组件类,并重写该类的事件处理方法来实现。
Android为所有GUI组件都提供了一些事件处理的回调方法,以View为例,该类包含如下方法:
boolean onKeyDown(int keyCode, KeyEvent event): 当用户在该组件上按下某个按键时触发该方法。
boolean onKeyLongPress(int keyCode, KeyEvent event)
boolean onKeyShortcut(int keyCode, KeyEvent event)
boolean onKeyUp(int keyCode, KeyEvent event)
boolean onTouchEvent(MotionEvent event)
boolean onTrackballEvent(MotionEvent event)
基于回调的事件处理机制可通过自定义View来实现,自定义View时重写该View的事件处理方法即可。下面是一个自定义按钮的实现类:
public class MyButton extends Button { public MyButton(Content content, AttributeSet set) { super(context, set); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { super.onKeyDown(keyCode, event); // 返回true, 表明该事件不会向外扩散 return true; } }
对比Android提供的两种事件处理模型,不难发现基于监听的事件处理模型具有更大的优势:
基于监听的事件模型分工更明确,事件源、事件监听由两个类分开实现,因此具有更好的可维护性。
Android的事件处理机制保证基于监听的事件监听器会被优先触发。
但是,在某些特定情况下,基于回调的事件处理机制会更好地提高程序的内聚性——更适合于应付那种事件处理逻辑比较固定的View。