Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3098043
  • 博文数量: 94
  • 博客积分: 2599
  • 博客等级: 少校
  • 技术积分: 990
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-30 23:23
文章分类

全部博文(94)

文章存档

2012年(1)

2011年(7)

2010年(24)

2009年(61)

2008年(1)

我的朋友

分类:

2009-03-17 22:53:28

1. Custom Dialog

Android支持自定义窗口的风格:

1)首先在资源里面建立style的value;

example:

drawable/filled_box.xml

>
   
   
   
            android:right="10dp" android:bottom="10dp" />

PS:关于Styles的学习,可以参见:

2)设置当前activity的属性,两种方式:1.在manifest文件中给指定的activity增加属性

android:theme="@android:style/Theme.CustomDialog"。2.在程序中增加语句setTheme(R.style.Theme_CustomDialog);

PS1:如果只是将Acticity显示为默认的Dialog, 跳过第一步,只需要在manifest文中增加属性:android:theme="@android:style/Theme.Dialog"或者在程序中增加setTheme(android.R.style.Theme_Dialog).

PS2:其他创建Dialog的方法:创建类或者创建类。

Next Study:能不能在Activity已经打开以后动态修改当前Activity的风格?

在测试中发现,在onCreate()事件中增加setTheme(),必须在setContentView()之前,否则指定的Style不能生效

2.Custom Title

Android除了可以为指定的Activity设置显示风格,此外也可以为指定的Activity设置一些特效,比如自定义Title,没有Title的Activity或者增加一个ICON等。

有意思的一点是,这些特效并不是你想设置的时候就行设置,你需要在Activity显示之前向系统申请要显示的特效,这样才能在下面的程序中为这些特效进行设置。(这样是不是多此一举有待研究)

为一个Activity设置自定义Title的流程:

1)为自定义的Title建立一个layout(custom_title_1.xml)

< xmlns:android=" android:id="@+id/screen"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:orientation="vertical">
            android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:text="Left" />
            android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Right" />

关于为什么采用RelativeLayout,可以参见:http://code.google.com/android/devel/ui/layout.html

2)为activity设定自定义Title特效并指定Title的layout:

在onCreate()事件中增加:

requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.custom_title);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_1);

这三条语句的次序不能颠倒,依次为申请特效,创建view,设置特效属性。其中requestWindowFeature等价于getWindow().requestFeature()

3)在需要修改Title的地方,获取left_text或者right_text进行设置即可。

Next Study:Activity的其他显示特效

Window还有其他一些feature,比如FEATURE_CONTEXT_MENU,FEATURE_NO_TITLE,FEATURE_LEFT_ICON等,有待继续学习研究。


1. Forwarding

这个实现很简单,就是启动新的Activity或者Service后,增加一个finish()语句就可以了,这个语句会主动将当前 activity从历史stack中清除,这样back操作就不会打开当前activity。

做这个实验的时候,发现开发Android程序需要注意的一点小问题:增加新的activity时,不能只增加一个class,一定要记得要在manifest文件中增加该activity的描述。(这个简单的功能,未来google应该给增加吧)

“android:name中的点”意义:首先manifest会有一个默认指定的package属性,比如指定为"com.android.sample",如果我们增加的activity的实现也在这个package下,则android:name为实现的类名,这个类名前加不加点都没有关系,都会自动找到该实现,比如实现为forwardtarget,则android:name写成forwardtarget或者.forwardtarget都可以。唯一有区别的是,如果activity的实现是在默认包的子包里面,则前面这个点就尤为重要,比如activity的实现是com.android.sample.app.forwardtarget,则android:name必须写成.app.forwardtarget或者com.android.sample.app.forwardtarget。如果只写app.forwardtarget,通常编辑器就会提示该类找不到,但不巧的是,你恰好有一个类是app.forwardtarget,那你只有等着运行时报错吧。
所以建议养成习惯只要是默认package下面的类,无论是否是在子包里面,前面都要加上一个点,现在当前实现是在默认package下。

2.Persistent

这里的持久化其实就是本地配置文件的读写,实现方法是通过Activity.getPreferences(int)获取SharedPreferences对象,然后操作配置文件的读写,值得注意的是以下几点:

1)Activity.getPreferences(int mode)等价于Content.getSharedPreferences(String filename,int mode),这里面的filename就是当前class的名称,例如在PersistentTest类中调用getPreferences(0),等价于调用getPreferences("PersistentTest", 0)。如不想用class name做文件名,可以直接调用getSharedPreferences方法,自己指定配置文件的名称。

2)mode值的定义:

MODE_PRIVATE = 0,表示当前配置文件为私有文件,只有当前的应用可以访问。

MODE_WORLD_READABLE = 1,表示当前配置文件可以被其他应用读取。

MODE_WORLD_WRITEABLE = 2,表示当前配置文件可以被其他应用写入。

如果配置文件又想被人读又想被写人,怎么办呢,呵呵,当然是MODE_WORLD_READABLE&MODE_WORLD_WRITEABLE,真的怀疑设计android的人以前是做C/C++的。

3)SharedPreferences是个很有意思的实现,读取数据的时候,直接用get方法就可以了,可是写数据的时候,没用给set方法,呵呵,第一次用这个类一定会以为只能读不能写。如果要写数据的话,需要用editor()方法(为什么不是getEditor()呢?看来设计的人一定是做C/C++的)获取SharedPreferences.Editor类,然后用这个类的put方法写文件。为什么要这样做呢?好久没有看设计模式了,不知道他采用是哪种高级模式,等以后有时间,看看它的实现再做研究吧。

4)在这个实现中,读文件是放在onResume()中,写文件是在onPause()中,为什么要这么做呢,看字面意思,好像只有恢复和暂停的时候才会被执行,那程序第一次创建的时候会读文件吗?来让我们看看Activity的生命周期,就会发现这么做的巧妙之处:

看到了吧,在Activity运行的前后,无论状态怎么转移,onResume()和onPause()一定会被执行,与其说实现的巧妙,还不如赞一下这个生命周期的设计的巧妙,这个巧妙不是说说而已,有时间的话,看看MFC中一个windows或者dialog的生命周期,你就知道这个巧妙的含义了,我们可以省多少的事情啊!所以值得记住的是,在android中想在运行前后必须要执行的语句,就应该放在onResume()和onPause()中。

4)最后说一个对android小不爽的地方:drawable,什么鬼东西啊!在res/drawable放一个文件,访问的时候是drawable/name,如果在values里面建立一个drawable的变量,访问的时候也是drawable/name,例如在drawable目录下放入一个red.xml文件,访问的时候是@drawable/red,如果建立一个drawable的变量red,访问也是@drawable/red,这完全就是两个东西啊,虽然最新的编辑器会提示重名,但查找的时候真的很不方便啊,尤其是drawable变量,可以放在一个abc.xml中,以后资源文件多了,管理起来想想都头麻,就不能把其中一个改改名字吗?把drawable变量叫成drawable_value不行吗?


. Receive Result

这个实验描述了Activity之间的另外一种切换方式,通常Activity的切换方式是Activity1通过startActivity切换到Activity2, Activity2再通过startActivity切换到其他的Activity,但是有的时候我们需要启动一个新的Activity获取用户的输入,然后返回到原来的Activity,比如activity是一个通讯录列表,我们通过一个增加按钮打开另一个activity让用户输入新的联系人,输入后再返回通讯录列表。
这个时候,我们可以通过startActivityForResult(Intent, int)方法启动新的Activity,新的Activity通过setResult(int, Intent)方法返回老的Activity,这个时候会触发老的Activity的onActivityResult(int, int, Intent)方法,我们可以在这个方法的实现中处理返回事件。

startActivityForResult(Intent, int),其中int为Request Code,也是onActivityResult的第一个参数,通常一个Activity不仅仅只触发一个获取事件,比如上面提到的通讯录,可能会有一个增加联系人的事件,也可能会有一个修改联系人或给指定联系人增加一个电话的事件,但我们只有一个onActivityResult方法,所以我们需要这么一个Request Code区分是哪个事件的返回,这个值是用户自己定义的,而且完全是用户自己进行管理,很人性化。

setResult(int, Intent),其中的int是Result Code,它表示的是返回的状态,也是onActivityResult的第二个参数。这个参数需要特别注意一下,android为这个值提供了三个默认的常量。我们先看前两个,RESULT_CANCELED和RESULT_OK,这个从字面上很好理解,一个是运行取消,另一个是运行成功返回,当用户按BACK键时,Result Code就是RESULT_CANCELED。但我们看看他们分别对应的值,就会发现奇怪的地方,RESULT_CANCELED=0,RESULT_OK=-1!!!在其他系统中OK通常都是1,而在android,它是-1,这是为什么呢,来让我们看看第三个默认的常量,RESULT_FIRST_USER=1,明白了吧!android把所有大于0的数字都留给了用户自己,多么人性化啊!但是要注意了,如我前面所说,大部分系统都喜欢将大于0作为正确返回,小于0作为错误返回,所以很多人(包括我),喜欢用if(result > 0)表示返回成功,这个在android是不通行的,一定要特别注意!

此外在这个程序中,我们可以看到另外一件事情,关于TextView,如果我们要改变里面的内容,比如增加新的字段,需要将其设为可变长的,方法是mTextView.setText(mTextView.getText(), TextView.BufferType.EDITABLE);
修改内容的方法是通过TextView.getText()获取Editable对象,然后Editable对象进行编辑就可以了,Editable类似于StringBuffer,编辑之后会直接反映到TextView里面,不需要再setText();

2. SaveRestoreState

完全没有看懂这个Demo要演示什么效果,好像是onSaveInstanceState以及TextView的android:freezesText属性有关,但具体效果没有研究出来,留到以后再研究吧

3.Translucent

Android为透明效果提供了内置的Theme: android:style/Theme.Translucent,只需要把当前的activity的theme设置为这个Theme就可以达到完全透明的效果。

如果要半透明的话,可以增加一个继承该Theme的style即可,实现如下:

#e0000000

此外API Demo中提供了另一个实例,不用继承内置的Theme,可以自己完全创建一个新的style,实现透明效果,同时可以加一些其他特效,比如模糊化等,但我试了半天也没有搞定,完全复制代码,也没有出现这个效果,这个现在可能不是很重要的东西,等以后有时间再研究补充吧。

阅读(2831) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~