編輯:Android開發實例
到目前為止,我發現RemoteView會用在兩個地方:一個是在AppWidget,另外一個是在Notification.
先從官方對他的定義來看:
RemoteView--
A class that describes a view hierarchy that can be displayed in another process. The hierarchy is inflated from a layout resource file, and this class provides some basic operations for modifying the content of the inflated hierarchy.
RemoteView描述一個view,而這個view是在另外一個進程顯示的。它inflate於layout資源文件。並且提供了可以修改過view內容的一些簡單基礎的操作。
從這個定義我們就知道RemoteView是用來描述一個垮進程顯示的view。從而你就會明白為什麼AppWidget和Nofication需要用到它了。
1,AppWidget---RemoteView
我們都知道AppWidgetProvider是一個BrocaseReceiver,只是接受到Enable, Update,disale,delete這些message,而真正顯示界面的是AppWidgetHostView(這是在Launcher裡面實現的)這中間就是通過RemoteView來溝通。通過RemoteView告訴Launcher你想要的AppWidget是長什麼樣。
2,Notification--RemoteView
若你想自定義你的Notification也必須通過RemoteView.因為你定義的Nofication和顯示Notification也是兩個不同的進程。
在android 2.2之前,RemoteView只支持一些簡單的view:TextView, Framelaout..不支持ListView和GridView等復雜的view,它的操作也是簡單的click。在網上有人說是通過@RemoteView這個標簽確定RemoteView是否支持view.在view的源文件加上@RemoteView這個標簽就可以支持了。這個我還沒有去試試過。 (在htc sence ui 中我們可以看到有用到listview,gridview,這是怎麼做到的呢,看下面說明)
在android 3.0,Google加強這方面,下面來源官方文檔:
Expanded Home screen widgets
Home screen widgets are popular with users because they offer fast access to application-specific data directly from the home screen. Android 3.0 lets developers take home screen widgets to the next level, offering more types of content and new modes of interaction with users. Developers can now use more standard UI widget types home screen widgets, including widgets that let users flip through collections of content as 3D stacks, grids, or lists. Users can interact with the home screen widgets in new ways, such as by using touch gestures to scroll and flip the content displayed in a widget.
2.Android AppWidget 如何支持復雜的View
整理自:http://407827531.iteye.com/blog/605736
一直想知道如何在AppWidget裡面添加 ListView,EditText 這些復雜的View.我們知道要在AppWidget裡添加 View都是通過RemoteView來做到了,然而RemoteView本身功能很弱,支持的操作很少,而且支持RemoteView的Widget很少:
在Dev Guide中有下面這段:
A RemoteViews object (and, consequently, an App Widget) can support the following layout classes:所以從這裡可以知道,為什麼在AppWidget裡添加EditText會顯示LoadError了,因為本身它就不支持這些復雜的 Widget.
* FrameLayout
* LinearLayout
* RelativeLayout
And the following widget classes:
* AnalogClock
* Button
* Chronometer
* ImageButton
* ImageView
* ProgressBar
* TextView
Descendants of these classes are not supported.
疑問1:為什麼Google Search會有EditText呢?
其實這些都是假象,並不是AppWidget支持EditText.
具體怎麼回事,我猜有兩種情況:
1.一種確實是EditText但確不是AppWidget 支持的,而是集成到Home裡面去了。
2.最新的SDK 1.6中,顯示在桌面的EditText只是一個ImageView,而這個ImageView的背景就是EditText的截圖了。我們點中這個“EditText”後,會調起一個Activity,
而這個Activity就是復雜輸入的EditText,並且會全屏顯示。所以我們就誤以會那是一個單純的EditText.
疑問2:HTC Hero Sense UI的人都看到了,它的AppWidget是確實支持復雜Widget的,比如:Bookmark, Widget:ListView/GridView,Twitter Widget:EditText.
這些確實是我們可以看到的,但它是怎麼做到的呢?我也很想知道,AppWidget支持到那麼強大,甚至超過了本身AP的功能,很搶眼。但不管是怎麼實現的,我想人家肯定是花了大力氣去做到了,我猜想可能是將Google 提供的AppWidget進行了比較大的改動。我們查看一下framework下的appwidget:
[email protected]-pjq ~/android/donut $ ls frameworks/base/core/java/android/appwidget/ -lh所以我想HTC一定是將這裡給改動了,以支持復雜的Widget,有知道內情的透露一點最好了。
total 60K
-rw-r--r-- 1 pjq users 7.9K 2009-09-29 21:49 AppWidgetHost.java
-rw-r--r-- 1 pjq users 12K 2009-09-29 21:49 AppWidgetHostView.java
-rw-r--r-- 1 pjq users 14K 2009-09-29 21:49 AppWidgetManager.java
-rw-r--r-- 1 pjq users 691 2009-09-29 21:49 AppWidgetProviderInfo.aidl
-rw-r--r-- 1 pjq users 5.6K 2009-09-29 21:49 AppWidgetProviderInfo.java
-rwxr-xr-x 1 pjq users 6.3K 2009-09-29 21:49 AppWidgetProvider.java
-rw-r--r-- 1 pjq users 1.5K 2009-09-29 21:49 package.html
要知道RemoteView的功能很少,特別是對事件處理的能力,都需要通過PendingIntent,傳到BroadcastReceiver 去處理。所以這裡對一些事件處理也僅限於比較簡單事件:比如說:Button Clicked,其它的我好像還沒怎麼用過,orz…. 對復雜的View:比如ListView(當然這裡還不支持,打個比方),ListView裡面那麼多Item,要設置Listener,要傳值,這些 RemoteView都不能像一個單純的Activity那樣處理。
3.實踐探索
寫這篇文章的時候,我已經實現了在 AppWidget裡顯示ListView/GridView這些復雜的Widget了,我這裡只說顯示,並不是說我已經能讓AppWidget支持 ListView/GridView了。所以我這裡更傾向於教你如何在AppWidget裡支持顯示ListView/GridView這些復雜的 Widget.
我們知道AppWidget只支持RemoteView,那哪些Widget是RemoteView呢,我來教你搜一下:
[email protected]-pjq ~/android/donut/frameworks/base/core/java/android/widget $ grep -i -n -A 1 @remoteview *.java就是這些了,類名前面加了”@RemoteView”,和我前面列出的那些是不是一樣的呢?–對了,就是這些了,所以以後你想知道你在AppWidget支持哪些Widget就可以像我這樣去搜一下就知道了,這樣最適時。
AbsoluteLayout.java:40:@RemoteView
AbsoluteLayout.java-41-public class AbsoluteLayout extends ViewGroup {
--
AnalogClock.java:39:@RemoteView
AnalogClock.java-40-public class AnalogClock extends View {
--
Button.java:58:@RemoteView
Button.java-59-public class Button extends TextView {
--
Chronometer.java:45:@RemoteView
Chronometer.java-46-public class Chronometer extends TextView {
--
FrameLayout.java:47:@RemoteView
FrameLayout.java-48-public class FrameLayout extends ViewGroup {
--
ImageButton.java:66:@RemoteView
ImageButton.java-67-public class ImageButton extends ImageView {
--
ImageView.java:55:@RemoteView
ImageView.java-56-public class ImageView extends View {現在沒什麼問題。
--
LinearLayout.java:44:@RemoteView
LinearLayout.java-45-public class LinearLayout extends ViewGroup {
--
ProgressBar.java:122:@RemoteView
ProgressBar.java-123-public class ProgressBar extends View {
--
RelativeLayout.java:66:@RemoteView
RelativeLayout.java-67-public class RelativeLayout extends ViewGroup {
--
TextView.java:186:@RemoteView
TextView.java-187-public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
寫到這裡我已經將最關鍵的內容都已經寫出來了,還不明白?
其實簡單點講就是在一個Widget類前面加上”@RemoteView”,加上了它就等於說RemoteView可以支持它, RemoteView支持就等於是AppWidget支持這它了。
好了,現在你只需要自定義一些你需要的Widget,加上”@RemoteView”標記,你就可以在AppWidget裡使用它了。
關於如何自定義一個Widget你完全可以參照frameworks/base/core/java/android/widget已有的這些Widget.依樣加一個。
其實如果你需要自定義一個Widget,比如說支持ListView,你可以先在一個activity裡實現它,然後將它移到framework下面去。
這裡說一下可能需要注意的地方:
1.如果有多個文件,需要Package的時候,名字最好按照這樣的形式:android.widget.bookmark
其中bookmark就是你要添加一個Widget存放的地方,這樣的話你就可以在frameworks/base/core/java/android/widget 目錄下新增bookmark文件夾,將java文件放在這個目錄下。
如果你新增的Widget只有一個java文件就可以不用這樣了,可以完全按照已經存在的Widget的樣子,直接將java文件放到frameworks/base/core/java/android/widget目錄下。
2.資源文件存放:
frameworks/base/core/res/res
資源文件都放到這個目錄下。
3.資源的引用:
要用這樣的方式引用:com.android.internal.R.drawable.**
4.記著在這個Customer Widget類名前加上”@RemoteView”標記.
這些都做完了,你就已經將一個自定義的Widget添加到framework了。之後要做的工作就是編譯整個工程了,重新生成SDK。
最後你就可以在AppWidget引用你新加的這個Widget了:com.widget.bookmark.***。
至此,你已經用上了你新加的這個Widget,並且可以加到AppWidget.
在新加Widget的時候可能會遇到的一些問題:
1.構造函數初始化問題。
如果在XML裡寫的layout不能直接指定哪個構造函數進行初始化,如果你不確定會跑哪個構造函數,最好在每個構造函數裡對加上log,這樣你就知道初始化時會跑哪個構造函數,並將初始化的工作加到裡面。我當時就遇到了這個問題,因為用XML寫layout,你不能顯示調用哪個構造函數進行初始化,如果你將初始化的操作放到一個不會自動跑到的構造函數裡面,那面你運行的時候就好像沒添加到Widget一樣。
2.其它的再說吧。
一、啰嗦 之前有讀者反饋說,你搞這個所謂的最佳實踐,每篇文章最後就給了一個庫,感覺不是很高大上。其實,我在寫這個系列之初就有想過這個問題。我的目的是:給出最實用
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個
1、完整生命周期 上圖是Android Activity的生命周期圖,其中Resumed、Paused、Stopped狀態是靜態的,這三個狀態下的Activit
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個