為了寫「香港天晴」的 widget,費了不少時間,中間還遇到一些奇怪的情況,特此記下。
Widget 還是不要做為可自訂大小的好
自從 Android 3.0 以來,Widget 可以設定為自訂大小 (resizeable) ,可根據不同的大小顯示不同的資訊,如以下的天氣 widget:
圖片來自 Android Developers
這樣可以以一個 widget 便代替以上四個 widget,減少一個程式有太多不同大小的 widget的情況 。
可是呢,實際做下去會有點問題:
- 你不會知道 widget 的大小
因為只能靠 onAppWidgetOptionsChanged() 獲取 widget 的最小和最大大小,但卻不能知道那大小等於桌面的多少個 cells。而因為 android 有太多的 screen size,在手機上 4 個 cells 的大小,在 tablet 上是只是 3 個 cells 。要顯示得好的話要做大量的測試。 - 不同 launcher 有不同的情況
不同 launcher 對 resizeable widget 的操作也有所不同。有些如 android 所言,會執行 onAppWidgetOptionsCHanged() ,有些卻不會:如 Samsung Galaxy S3 和 Sony Xperia Z。在他們的預設 launcher 上 resize widget 也不會 call onAppWidgetOptionsChanged(),做成不同程度的顯示問題。
勸大家暫時不是用 GridLayout 或 ScrollView 做 widget 的話,不要做可調較大小的 widget 吧。
RemoteView View ID 一定要存在
要更新 widget ,便要用 ViewID,在 RemoteViews 中更新:RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setTextViewText(R.id.textview, text_string);
在 ICS 以上,若 ID 在 layout 中沒有定義的話,是可以直接執行而不會有問題的。可是在 version 2.2 時,若 ID 不存在的話,widget 會直接顯示 Error view,而不會出現 Exception 的。這著實費了我一番功夫才找到問題所在。Widget 中沒有自訂字型
在 app 中,可以用以下的方法使用其他 webfonts:Typeface customTypeFace = Typeface.createFromAsset(getAssets(),
"fonts/custom_font.ttf");
((TextView)findViewById(R.id.custom_text_view)).setTypeface(customTypeFace);
可是在 Widget 中,由於只能使用 RemoteViews,所以不能執行 setTypeface。要使用 webfonts ,則只能將文字變成 bitmap,然後在 ImageView 顯示。問題來了,怎樣知道文字變成圖片後的長度和闊度呢?網上有不同的方法,但都不能因應 font size 而自動調整。幾經研究後,才找到以下的方法
Paint textPaint = new Paint();
textPaint.setTypeface(typeface);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTextAlign(Align.LEFT);
Rect bound = new Rect();
textPaint.getTextBounds(text, 0, text.length(), bound);
int imageViewSize = Math.max(Math.abs(bound.top), bound.width());
Bitmap myBitmap = Bitmap.createBitmap(imageViewSize, imageViewSize, Bitmap.Config.ARGB_8888);
Canvas myCanvas = new Canvas(myBitmap);
myCanvas.drawText(text, -bound.left + (imageViewSize - bound.width())/2, -bound.top + (imageViewSize -bound.height())/2, textPaint);
重點是 imageViewSize 的設定和最後 drawText 的 xy coordinate。不過我的 fonts 是正方形的,若大家用的為非方形的話,可能又有所不同。Android 2.x 支援
怎麼說呢?Android 2.x 跟 4.x 實在有點差異,很多時真不想再支援 2.x 版本。可是根據最新的調查,2.x的佔有率雖然首次被 4.x 超越,但也穩佔第二位,不支援它的話可是有大量用戶用不到的。圖片來源 Engadget
以上是我遇的問題,希望對大家寫 Widget 有用吧。
張貼留言