搜尋文章

2013年9月3日 星期二

使用android support V7 Demo

1.引入android-support-v7-appcompat、android-support-v7-gridlayout、android-support-v7-mediarouter三個android-support-v7的library。
先點選File/New/other/Android/Android Project from Existing Code,再點選Browse選擇androidSDK資料夾裡的extras/android/support/v7/appcompat、gridlayout、mediarouter按確定(這邊要分三次做),然後把project to import裡的專案給勾選起來,還有下面的copy projects into workspace也要勾選起
來之後按finish就可以了。

2.更改library SDK Version。
在android-support-v7-appcompat專案資料夾上按右鍵點選propertices然後選擇androidSDK的版本這邊要選擇android4.0,API LEVEL14。
在android-support-v7-mediarouter專案資料夾上按右鍵點選propertices然後選擇androidSDK的版本這邊要選擇android4.2,API LEVEL17,之後在下面Library的地方點選add然後選擇android-support-v7-appcompat再按OK。

3.加入android support V7 Demo。
先點選File/New/other/Android/Android Sample Project,之後選擇android4.1(Min SDK 7、Target SDK 17)然後選擇Support7Demos[Android Support Library]然後再按finish加入專案。

4.為support V7 Demo加入support V7 Library。
一樣在Support7Demos的資料夾上按右鍵點選propertices,然後再Library的地方按add加入第一個步驟引入的android-support-v7-appcompat、android-support-v7-gridlayout、android-support-v7-mediarouter這三個Library就可以發佈了。


2013年8月27日 星期二

AS3 Rect & java Rect 傻傻分不清~

今天在看android用canves畫圖案,有用到drawRect跟drawRoundRect這兩個方法,一個是畫矩形的另一個也是畫矩形的不過可以再多畫圓角。
這兩個方法都要帶一個Rect進去,想說Rect這東西在AS3的時候就用過很多次了,就覺得這四個值分別是帶x、y、width、height,然後就這樣帶進去了,想當然是畫出很奇怪的型狀或是根本沒圖形。在試驗很多次之後才發現原來AS3的Rect跟java的Rect是不一樣的阿~~

AS3裡如果是帶Rect(100,100,200,200)的值的話,會在x 100,y 100的地方畫一個寬200高200的矩形,不過在java裡這四個值分別是起始點與結束點,前面兩個值是起始點,後面兩個值是結束點,所以跟上面一樣帶Rect(100,100,200,200)的值的話,其實畫出來的會是在x 100,y 100的地方畫一個寬100高100得值,因為第三個值-第一個值=寬,第四個值-第二個值=高。

結案 !

2013年6月12日 星期三

android-透過webView加上userAgent


用userAgent判斷使用者是電腦或是行動裝置觀看網頁這一篇

記錄了如何用navigator.userAgent去判斷是在行動裝置上觀看網頁還是用電腦看

但如果是要在android上判斷是在行動裝置上的瀏覽器看還是用應用程式裡面的webView看的話

就需要再webView上下一點工夫了

下面直接上code

WebVIew mWebView = new WebView(context);
//先用webview的getSettings()取得webSettings再用getUserAgentString()
//取得userAgent,這邊取出來的值會跟在網頁用js的navigator.userAgent取的
//值是一樣的
String userAgentStr = mWebView.getSettings().getUserAgentString();
//之後用setUserAgentString()設定新的userAgent
//這邊設定新的UserAgent的時候用記得用舊的UserAgent去加入新的字串
//不然UserAgent的瀏覽器及系統訊息都會被你設定的新字串覆蓋過去
mWebView.getSettings().setUserAgentString(userAgentStr+"/ON_WEBVIEW");


之後在網頁上把UserAgent alert出來就可以看到剛剛新加入的字串了
Mozilla/5.0 (Linux; U; Android 4.1.2; zh-tw; GT-P3100 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30/ON_WEBVIEW

再來就是作一樣的判斷
var userAgent = navigator.userAgent;
if(/ON_WEBVIEW/i.test(userAgent)){
          //是否在webview上面看
     }

javascript-用userAgent判斷使用者是電腦或是行動裝置觀看網頁

要判斷是否再行動裝置上或是電腦上觀看網頁

甚至要判斷是哪個瀏覽器都可以用 navigator.userAgent

這個屬性會返回使用者的瀏覽器及使用系統

返回值是一個字串所以可以用陣則式或是找字串的相關方法判斷



var userAgent = navigator.userAgent;

     if(/Android/i.test(userAgent)){
          //是否為Android
     }else if(/iPhone|iPad/i.test(userAgent)){
          //是否為iPhone或iPad
     }else if(/Windows/i.test(userAgent)){
   //使否是用電腦觀看
     }

     //判斷瀏覽器
     if(/Chrome/i.test(userAgent)){
           //是否為Chrome
     }else if(/Firefox/i.test(userAgent)){
           //是否為Chrome
     }

如果不知道要用什麼字串判斷的話,就先把navigator.userAgent給alert出來看吧 !

另外在android上如果是要判斷是在android上的browser還是在webView上面看的話

就要在android上的webView動手腳了~

要如何動手腳可以看這一篇透過webView加上userAgent

android-canvas set bitmap IllegalStateException error

最近在android上試做了一個畫筆的功能

然後要能把畫的圖片儲存跟讀取

讀取的方法我是用BitmapFactory.decodeFile把檔案圖片轉成bitmap

然後再把這個bitmap畫在canvas上,但時候遇到了一個error

錯誤訊息是這樣的

java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor

股溝了一下發現也有人遇到這樣的問題

其原因是被載入的bitmap是不可被改變的,所以也不能用來畫在canvas上

如果是把bitmap帶入canvas的建構涵式的話就會出現上面的錯誤訊息

但如果是用canvas.setBitmap()的話只會出現這樣的錯誤訊息

java.lang.IllegalStateException

這一點真的想要抱怨一下android,錯誤訊息劈哩啪啦列了一大堆

唯一看到有用的訊息就是這一串然後也講得不清不楚了

但我想錯誤的原因應該都是一樣的,都是不可改變bitmap

解決的方法是把載入的bitmpa在複製一份出來用就好了~

Canvas mCanvas ;
File bimapFile = new File("mmt\sdcard","pic.png");
Bitmap orgBitmap = BitmapFactory.decodeFile(bimapFile.getAbsolutePath());
Bitmap copyBitmap = orgBitmap.copy(Bitmap.Config.ARGB_8888, true);

//用建構帶入bitmap或是用setBitmap方法帶入都可以
mCanvas = new Canvas(copyBitmap)

//or
//mCanvas = new Canvas();
//mCanvas.setBitmap(copyBitmap)

2013年6月3日 星期一

starling-AssetManager使用方法

在starling 1.3版中多增加了許多功能其中一個就是AssetManager。

AssetManager顧名思義就是用來管理素材的class

這邊就來記錄一下要如何使用


1.用Embed素材加入Texture
//先Embed圖片
[Embed(source="assets/bg.jpg")]
public static const BG:Class;

//先實體化AssetManager
vra am:AssetManager = new AssetManager();

//再把圖片加入AssetManager中
//第一個參數是這個texture在AssetManager中所註冊的名字
//第二個參數當然就是要放進AssetManager的texture
am.addTexture("BG", Texture.fromBitmap(new BG()));


//要從AssetManager抓取texture使用的話就使用getTexture方法
//參數就帶當初註冊名字
am.getTexture("BG");

//另外如果想知道所有有註冊的texture的名字可以使用getTextureNames方法
//這個方法會列出所有註冊過的名字
am.getTextureNames();

已經註冊的名字是不能重複註冊的,不然會報Error。

add的方法除了addTexture外還有addSound、addTextureAtlas

其實使用的方法都大同小異只是差在要丟什麼類型素材而已。




2.用enqueue方法加入素材,enqueue方法可以一次塞很多參數進去

也就是一次可以載入很多素材,就像他的名字一樣用列隊的方式依序載入

素材,而且enqueue是很強大的,它除了可以使用檔案路徑之外還可以

使用靜態的類別,甚至是可以搜尋整個資料夾路徑並且分門別類的幫你

自動載入自動註冊(AIR),下面就繼續記錄用不同的參數類型來使用enqueue載入素材。




第一種方法使用路徑載入檔案,使用檔案路徑的方式載入素材時比較要注意的地方是

AssetManager會自動使用檔案的檔名來註冊,例如是載入assets/bg.jpg這個

路徑裡的圖片,就會用bg這個名字來註冊,所以要用getTexture()方法取texture時

也是要用這個名字。

//一樣還是先實體化AssetManager
var am:AssetManager = new AssetManager();


am.enqueue("assets/bg.jpg");

//也可以一次給很多路徑中間用逗號格開就好
am.enqueue("assets/1.jpg","assets/2.jpg","assets/3.jpg");



第二種方法使用靜態類別載入,下面有一個用來embed檔案的靜態類別
package src.embed
{
 /**
  * ...
  * @author kuro
  */
 public class EmbedAsset 
 {
   
   //textureAtlas的圖片
   [Embed(source = "assets/lee.png")]
   public static const lee:Class;
   //textureAtlas的xml
   [Embed(source = "assets/leeXml.xml" , mimeType = "application/octet-stream")]
   public static const LeeAtlasXml:Class;
   
   //圖片
   [Embed(source="assets/bg.jpg")]
   public static const BGG:Class;
   
   //聲音
   [Embed(source="assets/yours.mp3")]
   public static const bgSound:Class;
   
   //字型
   [Embed(source="assets/font.png")]
   public static const font:Class
   [Embed(source="assets/font.fnt", mimeType="application/octet-stream")]
   public static const FontXml:Class
 }

}


使用靜態類別當作素材來源時要注意的地方是,AssetManager是用class名稱來註冊的

當要embed動畫所需要的textureAtlas素材的時候要注意一件事那就是

textureAtlas素材的圖片名稱跟embed的class名稱要一樣

但xml的名稱就不一定要跟embed的class名稱一樣了。


如果有去看過原始碼的話,就會發現AssetManager是先把class的lee先註冊到了

texture的Dictionary裡,之後載入textureAtlas的xml之後發現被註冊到

texture的Dictionary裡的lee是作為textureAAtlas需要的素材,所以就把

texture的Dictionary裡的lee移除掉,然後重新用lee這個名字去textureAAtlas的

Dictionary裡註冊,所以當textureAtlas註冊名字之後,你用getTexture()方法去

找lee的這個texture是找不到的,你只能用lee這個名字並且使用getTextureAtlas()這個方法

找到已經加入的textureAtlas素材。

//使用的話就這樣使用
var am:AssetManager = new AssetManager();

am.enqueue(EmbedAsset);

var lee:MovieClip = new MovieClip(mAssetManager.getTextureAtlas("lee").getTextures("lee_idle"), 24);
Starling.juggler.add(lee);
addChild(lee);


剛剛有說了註冊的名字是使用class名稱,所以如果是用靜態類別載入素材的話

要取得bg.jpg這張圖片就要用BGG的這個名稱。


如果是要取得聲音的話

可以用AssetManger裡的playSound("註冊的名字")取得聲音並且播放

playSound方法是會返回一個soundChannel,在呼叫這個方法時還可以帶

有關soundChannel的參數給他可給可不可。



如果是字型的話AssetManager會自動註冊字型到textField裡面,不用再呼叫

TextField.registerBitmapFont()註冊字型,而且也沒有方法可以抓取

載入進來的bitmapFont圖片,另外跟textureAtlas比較不一樣的地方是

要使用的時候不是用class的名稱,是要用這個字型的名稱,那字型的名稱

要去哪裡找呢?請把.fnt的這個檔案打開,其實裡面也是xml的結構

在第二行的地方會看到face="Brisk",這個face的地方就是字型的名稱

所以就要用Brisk這個名字,下面是使用方法

var text:TextField = new TextField(700, 100, "", "Brisk", 50, 0x000000, false);
   
text.hAlign = HAlign.LEFT;
text.text = "This is Bitmap Font Generator Test !";
addChild(text);

再來就是要講使用AIR在行動裝置上時要怎麼AssetManager

用AIR的話第一個還是可以使用上面所說的靜態類別的方法因為

那是把素材內嵌至swf裡比較沒有路徑的問題,但如果沒有要用embed的話

可以先把素材一起放在app的資料夾底下需要的時候在叫來用就好了

那要怎麼把宿才放在app資料夾底下呢?這邊我是用flash cs6所以我就來

講一下怎麼做。

第一步:選取檔案/android設定(如果是ios的話就是ios設定)

第二步:會看到下面有一個包含的檔案,然後會有三顆按鈕分別是

加入檔案、刪除檔案、加入資料夾,如果是只有幾個檔案的話可以

選擇加入檔案,但如果是有很多素材在同一個資料夾裡的話就可以選

加入資料夾,這樣這個資料夾裡的素材就都會被加入了

加入了檔案之後就要來看程式要怎麼寫了
//使用File類別,然後用applicationDirectory的屬性取得app根目錄
var appDir:File = File.applicationDirectory;

//之後再使用File的resolvePath()方法取得相對路徑
//如果是直接寫檔案路徑的話就會找到app/assets/bg.jpg;
am.enqueue(appDir.resolvePath("assets/bg.jpg"));

//這邊也可以直接寫資料夾名稱,AssetManager會自動搜尋可以用的
//全部素材並且載入註冊,非常的方便
am.enqueue(appDir.resolvePath("assets"))

再來講一下如何抓取檔案讀取的進度,AssetManager裡有一個loadQueue()

這也是呼叫AssetManager開始異步載入列隊裡的素材,這個方法必須帶一個function

給他,以便AssetManager callBack回來載入的進度

mAssetManager.loadQueue(onProgress);

private function onProgress(number:Number):void {
 var percent:int = Math.round(number * 100);
 trace("progress = " + percent + " %");
 if (number == 1) {
      (mStarling.root as Game).start(am);
 }
}



另外AssetManager 也可以載入網路上的資源下來,就把路徑換成http路徑就好了

還有載入的方法可以混著用類似像是下面這樣

//可以同時擺路徑也可以擺靜態類別
am.enqueue("asset/bg,jpg",EmbedAsset);

有關AsetManager的document可以來這邊看

AssetManager

2013/07/17更新

後來又自己鬼打牆遇到了一些問題,就再來記錄一下

1.用enqueue()放入要載入的檔案後,要記的要用loadQueue()載入檔案阿 !
就算沒有要知道載入進度也是一樣

2.在air的時候如果要用enqueue()掃資料夾的檔案的時候
要記得資料夾要跟fla檔案放在一起(用flash ide編譯的話)
這樣用appDir.resolvePath("assets")才會找的到檔案
千萬不要放在不同層,因為就算在路徑上加上../
air應用程式在找的時候也是從app路徑下開始找
所以還是找不到