颱風天, 適合寫點東西, 所以就把上次的PinterestRSSAggregator加上發佈到Google Drive功能, 第一次碰Google drive api, 不過還好Google已經有了一個node.js的module: http://bit.ly/1d1GImW,省去了重刻Google API的功(這module還頗有趣的, 利用了Google discovery API, 支援了相當多Google API, 但實際上各API的細節的實作卻不在這module之中), 不過一開始還是在Google drive上碰到了一些問題:

  1. 想說要存個設定檔, 但檔案如果可以被使用者看到, 就會有機會被他砍了
  2. 因為是要發佈rss檔, 所以最好可以有一靜態連結
  3. Google drive是允許在同一目錄有同名的檔案的, 這似乎跟Dropbox不一樣, 它真正獨一無二的識別是id不是檔名, 所以要更新某個檔案還得先找到它的id, 有點小麻煩
第一項的解法還蠻簡單, 只要使用app data就好, 這目錄比較單純, 它的id就叫做"appdata"(真是夠怪了, 這個id是固定的, 但使用者的根目錄的id卻不是, 還得先用about去取得), 我用它實作了一個放設定的(參考這, AppConfig), 放在這目錄的好處是不會被使用者看到並刪除掉, 但要注意的一點是, 取得auth token時所做的認證用的scope必須包含"http://bit.ly/18JQG6D"

至於第二項的作法就是建立一個public folder, 並取得這目錄的webViewLink, 比如說是"http://bit.ly/1d1GH2a", 這樣你在這目錄下建的檔案, 例如 julianshen.rss 就可以用 “http://bit.ly/18JQHaw” 這連結來存取

via Blogger http://bit.ly/1d1GH2c


陽光….跟沙灘呀……真是好風景呀….躺著寫程式真不錯 (其實在顧包包)

昨天上飛機前, 把這兩天晚上寫的東西, PinterestRSSAggregator, 在上飛機之前放上了github….趁現在來補一些內容

會寫這東西的緣起在於這篇: http://bit.ly/1bxhUyZ

Pinterest目前沒API, 這RSS也只能取得一個人最近的資訊, 但常常我們要看的不會是自己去pin的, 而是自己所follow的人pin的最新資訊, 所以這樣的RSS用處就嫌少了點, 所以想說如果可以把自己所follow的全部集結成一個rss應該會很不錯, 因此就寫了這些東西

一開始碰到的問題點是, 沒API, 怎抓following的資訊? 從 http://bit.ly/1bxhUz2, 似乎每個被follow的人的link都有userWrapper這class, 這或許是個出發點, 所以第一個版本做了一個直接去抓網頁回來解析抓出含有這class的連結….但是…失敗了…因為抓回來的靜態網頁, 最多只有十二個人的連結, 超過就抓不到, 網頁上要滑鼠捲到最下面才會再load出其他的

後來想到的方法就是利用CasperJS, 模擬捲頁捲到最後的行為, 再把所有followings都抓回來….喔耶….這招居然行的通….把所有rss 的url再用Google Feed API去抓內容(我懶得parse RSS了), 再用feed這module生成新的RSS….大功告成….接下來只要讓他固定一段時間跑一次, 就有一個土炮的Pinterest API用了… (還真heavy的API :( )

via Blogger http://bit.ly/16QMjqT

看到Square發表的這個Retrofit - http://bit.ly/167v72a 蠻有趣的, 它的目的似乎是試圖的想要去簡化開發REST client, 開發者不用寫太多的邏輯, 只要寫一個Interface跟利用annotation就可以完成一個簡單的REST client:

public interface GitHubService {
@GET("/users/{user}/repos")
List<Repo> listRepos(@Path("user") String user);
}

因為開發者只需要寫interface和annotation, 實質上並不用寫任何的code, 真正實作的部份他用了Proxy class的技巧包裝起來了, 這作法讓我想起來很久之前我在之前的工作幫公司寫的一個legacy系統的wrapper, 那時有很多機器產生的interface, 如果人工一個個實作很浪費時間, Proxy class可以解決掉這一部分的問題, 同樣的在retrofit似乎也是想用這技巧節省實作

但可惜的是, 現在的retrofit並還沒加入OAuth的支援, 因此送出去的API部分並沒被oauth簽章過,不過所幸要解決這一部分也不難, 寫一個Client class搭配Signpost還是可以做到, 這邊範例繼承了OkClient(使用OkHttp) :



因為OkHttp也是一種HttpURLConnection, 因此Signpost搭配DefaultOAuthProvider和DefaultOAuthConsumer即可, 另外初始化RestAdapter時加上這個新的Client即可:

RestAdapter restAdapter = new RestAdapter.Builder() .setClient(new SignedOkClient(mConsumer))


via Blogger http://bit.ly/11OBeFb

前一篇寫了一個自訂義的layout - SimpleCellLayout, 前一個版本的問題就是, 必須是寫程式把child view加進這個layout之中, 而且針對像是欄與行的數目也必須在程式裡設定, 並無法寫到layout xml中, 所以這次的目邊就是要讓這個layout可以像下面這樣用layout xml來擺佈:


在這範例之中, 用到幾個像是col, row, gapsize, cellX這些在原生Android並不存在的屬性, 為了這些屬性, 就需要定義一個attrs.xml在res/values目錄內, attrs.xml 裡面要定義的就是這些樣式描述屬性, 這邊定義了: 給SimpleCellLayout本身用的col(欄數), row(行數), gapsize(間距大小), 以及給他的Child views用的cellX(格子的橫軸位置), cellY(格子的縱軸位置), colspan(格子寬), rowspan(格子高), 除了gapsize我們需要的跟實際螢幕上的大小有關, 所以格式定義為dimension外(就是可以用3dp, 1px這類的值), 其他都是整數就可

這些屬性, 到時候就是要放在xml標籤內的屬性

要用到這些屬性, 需要先在tag裡面定義一個新的name space, 如同在前面範例寫的:

xmlns:celllayout=“http://bit.ly/GEGVYd”
文件內的範例大多是apk/後面接著package name, 不過Android Studio卻是建議使用"res-auto", 定義了這個name space後, 便可以在後面的tag內使用像是"celllayout:col"這樣的屬性了

那在layout內又要怎處理這些屬性? ViewGroup有兩個建構子所需要帶的參數含有AttributeSet, 基本上只要從這兩個建構子處理就好

這範例內的initFromAttributes就是用來從AttributeSet擷取這些屬性, 前面attrs.xml有定義stylable, 所以基本上有一堆相對應的Resource ID可以使用,這邊只處理了col, row, 和gapsize, 因為只有這三個屬性直接跟這layout相關, 至於這layout的child views該怎處理呢? 它就要靠LayoutParams了, 我在SimpleCellLayout內定義了一個CellLayoutParams, 基本上這類別也有一個建構子是用來處理AttributeSet的


這邊比較重要的就是要overwrite掉generateLayoutParams, 因為ViewGroup原有的generateLayoutParams實作的是回傳ViewGroup.LayoutParams, 他並不認得CellLayoutParams, 但SimpleCellLayout靠的是CellLayoutParams來儲存layout所需的資訊, 原本用程式來加入view的範例部份, 我是手動產生一個CellLayoutParams來給child view, 但如果是放在layout xml, 並無法指定要用哪個LayoutParams類別, 這時候就要靠generateLayoutParams了 有趣的是, 雖然是我自訂的layout, 但在我做完這些後, Android studio的UI編輯器, 卻知道怎去依據我的layout把元件畫到正確的位子上面:



via Blogger http://bit.ly/1af6KAB

寫Android寫了這麼久, 才想到自己沒寫過custom layout, 剛剛花了點時間(主要時間還是花在跟Android studio和gradle搏鬥)寫了一個簡單的CellLayout (還很陽春) :

http://bit.ly/12nuhGn

寫custom layout還蠻簡單的, 在onMeasure決定自己和child views的大小, 在onLayout時把每個child views放到適當的位置, 目前還沒加入attibrtues的支援, 所以暫時還只能寫code自己把view加進去, 另外也還沒加檢查是不是會有重疊的views, 之後再來寫

這個layout跟GridView不同, 可以不用每個格子都是同一大小, 以下範例是把畫面劃成4x4的格子, 左上角的那張圖大小是2x2, 下方則是 4x2





via Blogger http://bit.ly/12nuj0X