一、布局管理器

a) 线性布局

i. 有点像AWT编程中的FlowLayout,不同的是,Android的线性布局不会换行,当组件一个挨着一个的排列到头之后,剩下的组件将不会被显示出来;而FlowLayout中的组件会换行;

ii. 线性布局没有layout_gravity属性,设置无效。

b) 表格布局

i. 设置某列被设为Shrinkable,那么该列的所有单元格的宽度可以被收缩。

ii. 设置某列被设为Stretchable,那么该列的所有单元格的宽度可以被拉伸。

iii. 设置某列被设为Collapsed,那么该列的所有单元格会被隐藏。

c) 帧布局

i. 帧布局最有代表性的霓虹灯效果的原理:

For(int i=0;i<7-currentColor;i++){       Views[i].setBackgroundResource(colors[i+currentColor]);}     For(int i=7-currentColor,j=0; i<7; i++,j++){       Views[i].setBackgroundResource(colors[j]);}


ii.

Px(像素):每个px对应屏幕上的一个点。

Dip或dp:一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dip=1px。但随着屏幕密度的改变,dip与px的换算会发生改变。

Sp:主要处理字体的大小,可以根据用户的字体大小首选项进行缩放。

In:标准长度单位。

Mm:标准长度单位。

Pt:标准长度单位,1/72in

二、View子类

a) 时钟(AnalogClock、DigitalClock、Chronometer)

i. 第一第二个为模拟时钟和数字时钟,第三个为计时器。

ii. Chronometer的用法:

1. setBase(long base):设置计时器的起始时间

2. setFormat(String format):设置显示时间的格式

3. start():开始计时

4. stop():停止计时

5. setOnChronometerTickListener(Chronometer.OnChronometerTickListener):为计时器绑定时间监听,当计时器改变时触发该监听器。

iii. 获取系统时间的种类和区别(SystemClock):

1. System.currentTimeMillis(): 该时间是基于世界时间的,它返回的是从January 1, 1970 00:00:00 UTC到现在时间已经逝去了多多少millisecond,当我设置Android手机的系统时间时,会应该影响该值.

2. uptimeMillis(): 它表示的是手机从启动到现在的运行时间,且不包括系统sleep(CPU关闭)的时间,很多系统的内部时间都是基于此,比如Thread.sleep(millls),Object.wait(millis), andSystem.nanoTime()

3. elapsedRealtime(): 它表示的是手机从启动到现在的运行时间,且包括系统sleep(CPU关闭)的时间。

b) 图像视图(ImageView)

i. 使用之前最好先如下操作:

BitmapDrawable bitmapDrawable = (BitmapDrawable)image.getDrawable();If(!bitmapDrawable.getBitmap().isRecycled()){              bitmapDrawable.getBitmap().recycle();}

然后再设置image的值。

ii. 通过image可以得到Drawable对象,然后可以得到Bitmap对象,我们的主要操作都是针对Bitmap进行的,image只是在手机上显示的区域,而Bitmap则是你真实的图片,大小与显示的区域有不同。比如我们点击图片上某一个点,这个点的坐标是相对于image的坐标,但是如果我们需要对真实的图片进行操作的话,则需要将这个点的坐标进行相应的缩放倍数的增减。

c) 日期、时间选择器(DataPicker和TimerPicker)

i. 两个组件通过OnDataChangedListener、OnTimerChangedListener进行监听。

ii. 两个组件绑定鉴定的方式略有不同:

1.         dataPicker.init(year,month,day,new OnDataChangeListener(){public void onDataChange(Datapicker arg0,int year,int month,int day){       ChooseData.this.year = year;       ….       ….}}2.         timerPicker.setOnTimerChangedListener(new OnTimerChangedListener(){public void onTimerChanged(TimerPicker arg0,int hour,int minute){       ChooseData.this.hour = hour;       ….}}

d) 进度条——显示在标题上的进度条

i. 启用显示进度的进度条:

requestWindowFeature(Window.FEATURE_PROGRESS);

显示:

setProgressBarVisibility(true);

ii. 启用不显示进度的进度条:

requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

显示:

setProgressBarIndeterminateVisibility(true);

e) 拖动条(SeekBar)

i. 通过改变android:thumb属性来改变拖动条中滑块的样式,指定一个Drawable对象。

ii. 绑定一个OnSeekBarChangeListener监听器,实现onProgressChanged方法。

f) 选项卡(TabHost)

i. 定义TabHost组件,Activity继承TabActivity

ii. 调用TabActivity的getTabHost()方法获取TabHost对象。

iii. 通过TabHost对象的方法创建和添加选项卡:

1. newTabSpec(String tag):创建选项卡;

2. addTab(TabHost.TabSpec tabSpec):添加选项卡。

g) 可展开的列表组件(ExpandableListView)

i. android:childIndicator 显示在子列表项旁边的Drawable对象

ii. android:groupIndicator 显示在组列表项旁边的Drawable对象

h) 对话框

i. AlertDialog:功能最丰富、实际应用最广的对话框。

1. 带消息、带N个按钮的提示对话框

2. 带列表、带N个按钮的列表对话框

3. 带多个单选列表项,带N个按钮的对话框

4. 带多个多选列表项,带N个按钮的对话框

5. 对话框风格窗口,只需在AnidroidManifest.xml中定义android:theme=”@android:style/Theme.Dialog”

6. 自定义界面对话框

a) 创建AlertDialog.Builder对象,该对象是AlertDialog的创建器

b) 调用AlertDialog.Builder的方法为对话框设置图标、标题、内容等。

c) 调用AlertDialog.Builder的create()方法创建AlertDialog对话框

d) 调用AlertDialog的show()方法显示对话框。

ii. ProgressDialog:进度对话框,这个对话框只是对简单进度条的封装。

1.         OnCreate(Bundle savedInstanceState){Button.setOnclick…{       …}Handler…}2.         OnCreateDialog(int id, Bundle status){Switch(id){       Case …}}3.         onPrepareDialog(int id, Dialog dialog){             //该方法将//在onCreateDialog方法调用之后被调用switch(id){       case ….}}

iii. DataPickerDialog:日期选择对话框,这个对话框只是对DataPicker的包装。

iv. TimePickerDialog:时间选择对话框,这个对话框只是对TimePicker的包装。

i) 对话框窗口(PopupWindow)

i. 调用PopupWindow的构造器创建PopupWindow对象。

ii. 调用PopupWindow的showAsDropDown(View v)将PopupWindow作为v组件的下拉组件显示出来;或调用PopupWindow的showAtLocation方法将PopupWindow在指定位置显示出来。

j) Notification

i. 调用getSystemService(NOTIFICATION_SERVICE)方法获取系统的NotificationManager服务

ii. 通过构造器创建一个Notification对象

iii. 定义一个PendingIntent,传一个Intent到Notification,用于控制转向

iv. 为Notification设置各种属性

v. 通过NotificationManager发送Notification

k) 菜单和子菜单(SubMenu)

i. onCreateOptionsMenu(Menu menu)

ii. onOpeionsItemSelected(MenuItem mi)

三、事件处理

a) 基于监听的事件处理和基于回调的事件处理,基于回调的事件处理可用于处理一些具有通用性的时间,基于回调的事件代码会显得比较简洁,但对于某些特定的事件,无法使用基于回调的事件处理,只能采用基于监听的事件处理。

b) 基于监听的事件处理

i. 事件响应的动作实际上就是一系列程序语句,通常以方法的形式组织起来,但java是面向对象的编程语言,方法不能独立存在,所以必须以类的形式来组织这些方法,所以时间监听器的核心就是它所包含的方法——这些方法也被称为时间处理器(Event Handler)。

ii. Android的时间处理机制是一种委派式(Delegation)时间处理方式。

iii. 实现时间监听器的几种形式:

1. 内部类

a)

Public class A extends Activity{Public void onCreate(Bundle savedInstanceState){       …} Class AListener implements View.OnClickListener{       Public void onClick(View arg0){       …}}}

b) 优势:

i. 可以在当前类中复用该监听器;

ii. 因为监听器是外部类的内部类,可以自由访问外部类的所有界面组件。

2. 外部类

a)

  Public class A extends Activity{Public void onCreate(Bundle savedInstanceState){       …}}Public class AListener implements OnLongClickListener{       Public Boolean OnLongClick(View source){              …}}

b) 缺点:

i. 事件监听器通常属于特定的GUI界面,定义成外部类不利于提高程序的内聚性;

ii. 外部类形式的事件监听器不能自由访问创建GUI界面的类中的组件,编程不够简洁。

iii. 如果某个事件监听器确实需要被多个GUI界面所共享,而且主要是完成某种业务逻辑的实现,则可以考虑使用外部类的形式来定义时间监听器。

3. Activity本身作为事件监听器类

a)

  Public class AListener extends Activity implements OnClickListener{Public void onCreate(){       …} Public void onClick(View v){       …}}

b) 优点:简洁

c) 缺点:

i. 这种形式可能造成程序结构混乱,Activity的主要职责应该是完成界面初始化工作,但此时还需要包含时间处理器方法,从而引起混乱;

ii. 如果Activity界面类需要实现监听器接口,让人感觉比较怪异

4. 匿名内部类

5. 直接绑定到标签

a) <Button android:onClick=”clickHandler”/>

c) 基于回调的事件处理

i. 更加适用于应付那种事件处理逻辑比较固定的View,比如跟随手指的小球。

ii. 基于回调不比基于监听的方面:

1. 基于监听的事件模型分工更加明确,事件源、事件监听由两个类分开实现,因此具有更好的可维护性

2. Android的事件处理机制保证基于监听的事件监听器会优先被触发。

iii. 为了使用回调机制类处理GUI组件上所发生的事情,我们需要为该组件提供对应的事件处理方法——而java又是一种静态语言,我们无法为某个对象动态的添加方法,因此只能继承GUI组件类,并重写该类的事件处理方法来实现。以View为例,包含如下方法:

1. boolean onKeyDown(int keyCode,KeyEvent event);

2. boolean onKeyLongPress(int keyCode,KeyEvent event);

3. boolean onkeyShortCut(int keyCode,KeyEvent event):当一个键盘快捷键事件发生时触发该方法;

4. boolean onKeyUp(int keyCode,KeyEvent event);

5. boolean onTouchEvent(MotionEvent event);

6. boolean onTrackballEvent(MotionEvent event)

iv. 这些方法都返回一个boolean值,用来判断方法内部的事件是否向外传出,如果为true,则表示事件到此不传播出去;如果为false,则表示事件继续向外传播,直到true。

d) 两种事件处理例子:

i. 基于监听:

public class DrawView extends View{       …       public DrawView(Context context);       public void onDraw(Canvas canvas);}public class Demo extends Activity{       public void onCreate(Bundle savedInstanceState){              DrawView draw = new DrawView(this);              draw.setOnTouchListener(new OnTouchListener(){                     public boolean onTouch(View arg0,MotionEvent event){                            …}});}}


ii. 基于回调:

public class DrawView extends View{       …       public DrawView(Context context);                            public void onDraw(Canvas canvas);                            public void onTouchEvent(MotionEvent event);}DrawView直接放到界面布局中即可。


iii. 从上面两种情况来看,在这种事件处理逻辑比较固定的view,采用基于回调的方式会更好的提高程序的内聚性。

e) 响应系统设置的事件(Configuration)

i. 专门用于描述手机设备上的配置信息,这些配置信息既包括用户特定的配置项,也包括系统的动态设备配置。

ii. 使用方法:

1. 获取系统的Configuration对象。

Configuration cfg = getResources().getConfiguration();

2. 调用Configuration对象的属性来获取设备状态,具体有什么状态,查API。

3. 响应系统设置更改方法:onConfigurationChanged,用法和基于回调方法一样。

4. 因为动态的更改系统设置,因此需要授予应用更改系统设置的权限,并且设置Activity运行动态修改的系统设置,假如修改屏幕方向,则如下:

<activity android:configchanges=”orientation”>

<uses-permission android:name=”android.permission.CHANGE_CONFIGURATION”/>

f) Handler消息传递机制

i. Android平台不允许Activity新启动的线程访问该Activity里的界面组件,因此需要借助Handler来完成,重写Handler的handleMessage方法,当新线程发送消息时,该方法会被自动回调,因为该方法依然位于主线程,所以可以动态的修改Activity的组件。一个很常见的用法,我们在新启动的线程中不用Toast,而是一般放到Handler中写,原因就是此。

四、深入理解Activity

a) 用LauncherActivity开发启动Activity的列表(源码example)

i. extends LauncherActivity

ii. 定义需要跳转的类Class<?>[] clazzs = {…class,…class,…class….};

iii. 配置Adapter,setListAdapter(adapter);

iv. 重写intentForPosition方法

public Intent intentForPosition(int position){

return new Intent(…this,clazzs[position]);

}

b) PreferenceActivity的应用

i. 开发Android应用时,需要进行选项设置,这些选项设置会以参数的形式保存,习惯上用Preferences进行保存

ii. 继承PreferenceActivity,使用自定义的布局,新建xml文件夹,新建preferences.xml,其元素用法可以查api。

iii. 在onCreate中调用addPreferencesFromResource(..)方法加载指定的界面布局文件

addPreferencesFromResource(R.xml.preferences);

iv. 程序运行后,将会在/data/data/org.crazyit.activity/shared_prefs/路径下生产一个xml文件,导出后可以看到保存的设置参数。

c) 启动Activity

i. 两种方式

1. startActivity(Intent intent);

2. startActivityForResult(Intent intent,int requestCode)

ii. 第二种启动方式需要重写onActivityResult方法来接收数据

public void onActivityResult(int requestCode,int resultCode,Intent intent){

Bundle data = intent.getExtras();

}

iii. 传送数据Bundle

1. Bundle data = new Bundle();

data.putSerializable(“object”,o);

Intent it = new Intent(…,…);

intent.putExtras(data);

iv. 接收数据

1. Intent it = getIntent();

Bundle data = it.getExtras();

Object o = data.getSerializable(“object”);

v. 关闭Activity

1. 第二种启动方式关闭activity的时候需setResult以返回数据给启动前的Activity

Intent it = getIntent();

Bundle data = new Bundle();

data.putString(……);

…Activity.this.setResult(0,intent);

…Activity.this.finish();

d) Activity回调机制

i. 回调:对于一个具有通用性之的程序架构来说,程序架构完成整个应用的通用功能、流程,但在某个特定的点上,需要一段业务相关的代码——通用的程序架构无法实现这段代码,那么程序架构会在这个点上留一个“空”,可以以如下两种方式存在:

1. 以接口的形式存在:接口由开发者实现,实现接口时将会实现该接口的方法,那么通用的程序架构就会回调该方法来完成相关的处理。

2. 以抽象方法的形式存在:这些方法已经被定义好,开发者可以选择性的重写这些方法,通用程序框架就会回调该方法来完成业务相关的处理。这就是Activity的实现方式。

e) Activity的生命周期

i. 四个状态:

1. 活动状态:当前Activity位于前台,用户可见,可以获得焦点

2. 暂停状态:其他Activity位于前台,该Activity依然可见,只是不能获得焦点

3. 停止状态:该Activity不可见,失去焦点

4. 销毁状态:该Activity结束,或者Activity所在的Dalvik结束进程

ii. 回调方法:

1. onCreate(Bundle savedStatus)

2. onStart();

3. onRestart();

4. onResume();

5. onPause();

6. onStop();

7. onDestroy();

f) Activity和Servlet不同

i. Activity是Android窗口的容器,因此Activity最终以窗口的形式显示出来。而Servlet并不会生成应用界面,只是向浏览者生成文本响应。

ii. Activity运行于Android应用中,因此Activity的本质还是通过各种界面组件来搭建界面;而servlet则主要以IO流向浏览者生成文本响应,浏览者看到的界面其实是由浏览器负责生成的

iii. Activity之间的跳转主要通过Intent对象来控制;而servlet之间的跳转则主要由用户请求来控制。

五、Intent

a) Intent属性及intent-filter配置

i. Component属性用法

1. ComponentName comp = new ComponentName(….this,….class);

Intent it = new Intent();

it.setComponent(comp);

2. ComponentName comp = getIntent().getComponent();

comp.getPackageName()….comp.getClassName();

b) Action、Category、intent-filter

i. Action要完成的只是一个抽象的动作,这个动作具体由哪个组件(或许是Activity、或者是BroadcastReceiver)来完成,Action这个字符串本身并不管。比如Android提供的标准Action:Intent.ACTION_VIEW,它只表示一个抽象的查看操作,但具体查看什么、启动哪个Activity来查看,Intent.ACTION_VIEW并不知道——这取决于Activity的<intent-filter>配置,只要某个Activity的<intent-filter>配置中包含了该ACTION_VIEW,该Activity就有可能被启动

ii. AndroidManifest.xml中的<activity>元素中的<intent-filter>元素里通常可包含如下子元素:

0~N个<action>子元素

0~N个<categtory>子元素

0~1个<data>子元素

iii. 一个Intent对象最多只能包含一个Action属性,一个Intent对象可以包含多个Category属性 ,默认启动Category值为Intent.CATEGORY_DEFAULT

六、Android应用资源

a) resource型资源,主要为values中的资源,例如string/integer/bool、color、array、style、dimen、theme、attr,这些资源文件的根元素都是<resource>元素,其形式为:

<resource>

<string name=”…”>…</string>

<resource>

*其中array中包含三种子元素array、string-array、integer-array,每个子元素下包含item元素,例如:

<resource>

<array name=”aaa”>

<item>@string/c1</item>

</array>

</resource>

*其中style中包含两个子元素,name和parent,例如:

<resource>

<style name=”style1” parent=”…”>

<item name=”…”>…</item>

</style>

</resource>

*其中attr中包含两个子元素,attr和declare-styleable,例如:

<resource>

<attr name=”duration”>

</attr>

<declare-styleable name=”AlphaImageView”>

<attr name=”duration”/>

</declare-styleable>

</resource>

当我们定义好了自定义组件属性资源后,在界面布局引用的时候,需要引入属性资源所在包下的命名空间,为自定义组件制定一个duration属性,属性位于”http://schemas.android.com/apk/res/+项目子包”命名空间下;设置好引用后,自定义组件便可以使用duration属性,并赋值了。

当我们使用属性文件定义了属性,并给属性在界面布局中赋值了之后,接下来在自定义组件的构造器中通过AttributeSet对象来获取属性:

TypedArray typedArray =

context.obtainStyleAttributes(attrs,R.styleable.AlphaImageView);

int duration = typedArray.getInt(R.styleable.AlphaImageView_duration,0);

b) drawable型资源,主要为drawable中的资源,例如BitmapDrawable、NinePatchDrawable、StateListDrawable、ShapeDrawable、AnimationDrawable以及一些Drawable的其他各种子类对象,将这些对象放入drawable文件夹中,AndroidSDK就会在编译应用自动加载该对象,并在R资源清单类中生成该资源的索引。为了获得市级的drawable对象,Resources提供了Drawable getDrawable(int id)方法,可以根据R中的id来获得实际的drawable对象。

i. StateListDrawable根元素为<selector>,该元素可以包含多个<item>,item可指定如下属性:

1. android:color或android:drawable:指定颜色和drawable对象

2. android:state_xxx:指定一个特定状态

例如:

<selector>

<item android:color=”hex_color”

android:state_pressed=[“true”|”false”]/>

</selector>

ii. LayerDrawable根元素为<layer-list>,该元素可以包含多个<item>,item可指定如下属性:

1. android:drawable:指定作为LayerDrawable元素之一的Drawable对象

2. android:id:为该Drawable对象指定一个标识

3. android:buttom|top|left|button:它们用于指定一个长度值,用于指定将该Drawable对象绘制到目标组件的指定位置

例如:

<layer-list>

<item android:id=”@android:id/background”

android:drawable=”@drawable/grow”/>

</layer-list>

iii. ShapeDrawable根元素为<shape>,该元素可定制如下属性:

1. android:shape=[“rectangle”|”oval”|”line”|”ring”]:指定定义哪种类型的几何图形

2. corners:定义几何图形的四个角的弧度

3. gradient:定义使用渐变色填充

4. padding:定义几何图形的内边距

5. size:定义几何图形的大小

6. solid:定义使用单种颜色填充

7. stroke:定义为几何形状绘制边框

iv. ClipDrawable根元素为<clip>,该元素可指定如下属性:

1. android:drawable:指定截取的源Drawable对象

2. android:clioOrientation:指定截取方向,可设置水平截取或垂直截取

3. android:gravity:指定截取时的对齐方式

使用ClipDrawable对象时可调用setLevel(int level)方法来设置截取的区域大小,当level为0时,截取的图片片段为空;当level为10000时,截取整张图片。

例如:

<clip

android:drawable=”@drawable/shuangta”

android:clipOrientation=”horizontal”

android:gravity=”center”>

</clip>

v. AnimationDrawable根元素为<set>,该元素可指定如下属性:

1. alpha:设置透明度的改变

2. scale:设置图片进行缩放改变

3. translate:设置图片进行位移变换

4. rotate:设置图片进行旋转

定义动画的xml资源应该放在/res/anmi路径下

例如:

<set>

<alpha

android:fromAlpha=”float”

android:toAlpha=”float”/>

<scale

android:fromXScale=”float”

android:toXScale=”float”

android:fromYScale=”float”

android:toYScale=”float”

android:pivotX=”float”

android:pivotY=”float”/>

<translate

android:fromX=”float”

android:toX=”float”

android:fromY=”float”

android:toY=”float”/>

<rotate

android:fromDegrees=”float”

android:toDegrees=”float”

android:pivotX=”float”

android:pivotY=”float”/>

</set>

上面的pivot为变换的中心点

以上五个元素都可以指定一个android:interpolator属性,指定动画变化速度

如果想让<set>下所有的变化效果速度相同,则指定android:shareInterpolator=”true”

c) 原始xml资源,一般保存在res/xml路径下,需要解析

d) 菜单Menu资源,通常放在/res/menu目录下,根元素为<menu>,可指定如下子元素:

i. <item>:定义菜单项,可以指定如下属性:

1. android:id

2. android:title

3. android:icon

4. android:alphabeticShortcut:为菜单项指定字符快捷键

5. android:numericShortcut:为菜单项指定数字快捷键

6. android:checkable

7. android:visible

8. android:enable

ii. <group>:将多个<item>定义的菜单包装成一个菜单组,<group>可以指定如下常用属性:

1. checkableBehavior:指定改组菜单的选择行为,可指定为none、all、single

2. menuCategory:对菜单进行分类,指定菜单的优先级。有效值为container、system、secondary和alternatve

3. visibale

4. enable

例如:

<menu>

<item>

<menu>

<group>

<item>

<item>

</group>

</menu>

</item>

<item>

更多相关文章

  1. textView 属性总结
  2. 记录关于Gradle : Build Running的解决方法
  3. Android——初识OpenGL ES 2.0
  4. android的onCreateOptionsMenu()创建菜单Menu详解
  5. android service 学习
  6. Android开发周刊 第四期
  7. android 细节之禁用返回键
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android之Intent分析
  2. 解决ScrollView与ListView的冲突的方法
  3. Android不同版本获取当前wifi信息方法
  4. [深度报道]Android国内开发者陷盈利困局
  5. android使用selector修改TextView中的字
  6. Android和H5之间的交互
  7. 【Android-Error】Android 4.4.4 java.la
  8. 深入解析_Android的自定义布局
  9. Android Google Map(create md5, create
  10. Android实现点击事件的三种方法