以下實作一組重複發生的 淡出-移動-淡入 動畫,
套用在半透明gradient drawable上面可以製造出原件閃亮亮的效果
2014年3月29日 星期六
2013年12月4日 星期三
grep + less with color
grep -R --color=always "search string" * | less -R
若只有--color的話預設為--color=auto,pipe with less使用的話不會有顏色
less -R才會翻譯顏色escape charactor
2013年11月26日 星期二
linux 使用swap memory
最近嘗試在aws ec2 上deploy 一個ror的project
但因為使用的是free trail instace所以memory很小,deploy的時候會噴cannot allocate memory
要切一塊disk空間作為swap memory以解決這個問題
首先先確認是否已經存在swap memory:
如果沒有會顯示如下
在確認沒有swap memory後檢查我們是否有足夠的硬碟空間,我們要做一塊512mb的swap memory所以要至少這麼多
開始建立swap memory
接著使用這個空間
不過只是這樣重開機的話會失去效用,所以要把這塊swap memory加入fstab(file system table)中
加入這行
記得把Swappiness設定為0, 這樣可以確保os只有在緊急的時候(例如不swap就噴out of memory)才做swap動作,增加效能
但因為使用的是free trail instace所以memory很小,deploy的時候會噴cannot allocate memory
要切一塊disk空間作為swap memory以解決這個問題
首先先確認是否已經存在swap memory:
sudo swapon -s
如果沒有會顯示如下
Filename Type Size Used Priority
在確認沒有swap memory後檢查我們是否有足夠的硬碟空間,我們要做一塊512mb的swap memory所以要至少這麼多
df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 7.9G 3.5G 4.1G 47% / udev 288M 12K 288M 1% /dev tmpfs 119M 176K 118M 1% /run none 5.0M 0 5.0M 0% /run/lock none 296M 0 296M 0% /run/shm
開始建立swap memory
sudo dd if=/dev/zero of=/swapfile bs=1024 count=512k sudo mkswap /swapfile執行完會顯示
Setting up swapspace version 1, size = 262140 KiB no label, UUID=xxxxxxxxxxxxxxxxxxxxxxxxxxx
接著使用這個空間
sudo swapon /swapfile
不過只是這樣重開機的話會失去效用,所以要把這塊swap memory加入fstab(file system table)中
sudo vim /etc/fstab
加入這行
/swapfile none swap sw 0 0
記得把Swappiness設定為0, 這樣可以確保os只有在緊急的時候(例如不swap就噴out of memory)才做swap動作,增加效能
sudo su - echo 0 > /proc/sys/vm/swappiness exit
2013年11月11日 星期一
Android: 使用LightingColorFilter 來做使用image background的button的onClick特效
以往我在做用其他image為background的button的onClick特效時,都要準備好兩張image,
一張為按下去前,一張為按下去後,實為麻煩.
後來發現只要使用Android sdk內建的LightingColorFilter就可以用一張圖達到不錯的類似效果:
一張為按下去前,一張為按下去後,實為麻煩.
後來發現只要使用Android sdk內建的LightingColorFilter就可以用一張圖達到不錯的類似效果:
mTestBtn.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() ==MotionEvent.ACTION_DOWN)
v.getBackground().setColorFilter(new LightingColorFilter(0xFF999999, 0xFF000000));
else if(event.getAction() ==MotionEvent.ACTION_UP)
v.getBackground().clearColorFilter();
return false;
}
});
2013年11月5日 星期二
Android: 當資料庫越來越肥大 之 容易擴充的DB架構
使用這樣的寫法在修改或擴增database的時候可以比較舒服(我覺得啦XD)
不過如果只是要寫一個小小且不太會擴充的db那就先不需要這把牛刀了!
後面有完全沒有整理過(囧)的範例code,可能看code比較好懂.
此架構大致分為五個部分:
我是另外建立了一個application class來確保db在被任何activity使用前已經初始劃完成.
剩下的就讓code自己來解說吧XD
不過如果只是要寫一個小小且不太會擴充的db那就先不需要這把牛刀了!
後面有完全沒有整理過(囧)的範例code,可能看code比較好懂.
此架構大致分為五個部分:
DBHelper
- 這個就是一般在寫db的時候繼承SQLiteOpenHelper而來的class,這邊增加了一些function讓操作更便利一點.擔負起了依照schema來建立table、實際操作db等重責大任.
- 這個class是獨立於project的,可以直接貼到別的project.
DBSchema
- 掌握了整個db的架構,建立實體以後會喂给DBHelper的constructor吃.
- 這個class幾乎也獨立於不同project,除了要在變數定義的時候告知這個project中table的相關資訊.另外加入新的Table時也記得要在這裡增加定義.
DBTable
- 每一個table有自己專屬的class,所以加入新table的時候基本上不會動到舊的架構.
- 提供的method儘量不存取到自己以外的table.
- 提供存取自己table 的method给data provider使用.
Data Provider
- 扮演db的adapter角色,可以存取多個db並且將資料處理組合後以便使用.
- app的其他部分需要存取資料理當只會使用到Provider,不會直接使用DBTable.
- Provider理當是唯一會直接使用到DBTable的class.
- 可以視需求增加不同的data provider
Global initialization
因為DBHelper是採用singleton,所以用application context來做初始化.我是另外建立了一個application class來確保db在被任何activity使用前已經初始劃完成.
建立一個新的table步驟:
- 先建立一個table class.
- 去Schema中加入Table資訊.
- 接著就可以在data provider中使用這個table.
剩下的就讓code自己來解說吧XD
2013年10月16日 星期三
Android: 建立一個configure class當作參數以增加constructor的彈性
如果初始化一個class所需要設定的參數太多,會造成這個class的constructor過長,這個情況可以利用自定義一個config class作為參數給constructor吃來解決.
這樣做有幾個特點:
用法:
接下來介紹config class的實作,架構如下:
使用final qualifier有兩個用意
(ps2. final 變數除了在宣告的時候直接assign值外唯一的設定機會是在constructor中)
藉由Builder的幫助來建立fields為final的config class
config class的constructor吃一個Builder物件作為參數
這邊加上static是因為static inner class不用reference到outer class 的instance,才可以直接用以下方式建立:
大概就是這樣,最後附上一段之前寫的code作為範例
這樣做有幾個特點:
- 可以確保在物件建構前設定所有建構時所需要的資訊
- 統一參數設定時機
- config class中對於optional的參數可以有default值
- 設定參數時可以有很大的自由度不用依照constructor規定的參數順序.
- 不代表之後不能變動參數,還是可以加入function 如MyClass.setNewHeight()
用法:
//usage
//為何要使用Builder與其實作後面說明
MyClassConfig config = MyClassConfig.Builder()
.setHeight(100)
.setWidth(50)
.setXXX(...)
.setYYY(...)
.build();
MyClass mc = new MyClass(config);
//constructor
MyClass(MyClassConfig config)
{
this.height = config.height;
this.width = config.width;
//other initialization
...
}
接下來介紹config class的實作,架構如下:
public class MyClassConfig {
//1.config class fields
...
//2.config class constructor
...
//3.static inner builder class:
public static class Builder
{
// 3.1 builder fields
...
// 3.2 builder constructor
...
// 3.3 builder setter
...
// 3.4 build() function
...
} // end of builder
}//end of MyClassConfig
1. config class fields
//首先定義fields,使用final qualifier來確保config建構的時候要完成全部的設定
final int height;
final int width;
...
使用final qualifier有兩個用意
- 確保全部的設定在config建構的時候就會完成
- MyClass要可以直接存取這些fields所以不能是private但又不希望config建構後fields還會被更動
(ps2. final 變數除了在宣告的時候直接assign值外唯一的設定機會是在constructor中)
藉由Builder的幫助來建立fields為final的config class
2.config class constructor
config class的constructor吃一個Builder物件作為參數
public MyClassConfig(Builder pBuilder)
{
this.height = pBuilder.height;
this.width = pBuilder.width;
...
}
3.static inner builder class
這邊加上static是因為static inner class不用reference到outer class 的instance,才可以直接用以下方式建立:
new MyClassConfig.Builder();
最後是builder 的實作
public static class Builder{
//3.1 builder fields
private int height;
//可以在這邊設定default value,如果build過程中沒有被更改,default value會被assign到最後build出來的config class中
private int width = 100;
//3.2 builder constructor
//如果建立config的時候需要一些外部資訊可以當作builder constructor的參數傳入
public Builder(){};
//3.3 builder setter
//設定config參數的functions, 回傳自己是為了可以達到method chaining的效果
//i.e., builder.setHeight(100).setWidth(100).build();
public Builder setHeight(int h)
{
this.height = h;
return this;
}
public Builder setWidth(int w)
{
this.width = w;
return this;
}
//3.4 build function
//最後建立出config的function
public MyClassConfig build()
{
return new MyClassConfig(this);
}
}
大概就是這樣,最後附上一段之前寫的code作為範例
package itri.u9lab.towolf.ratiofixer;
public class RatioLayoutConfig {
final int virtualWidth;
final int virtualHeight;
final boolean isFullScreenMode;
/*
* constructor
*/
public RatioLayoutConfig(Builder pBuilder)
{
this.virtualHeight = pBuilder.virtualHeight;
this.virtualWidth = pBuilder.virtualWidth;
this.isFullScreenMode = pBuilder.isFullScreenMode;
}
/*
* config builder
*/
public static class Builder
{
private int virtualWidth = 768;
private int virtualHeight =1230;
boolean isFullScreenMode = false;
public Builder()
{
}
public Builder setVirtualSize(int pWidth,int pHeight)
{
virtualWidth = pWidth;
virtualHeight = pHeight;
return this;
}
public Builder setFullScreen(boolean mode)
{
isFullScreenMode = mode;
return this;
}
public RatioLayoutConfig build()
{
return new RatioLayoutConfig(this);
}
}//end of builder
public static RatioLayoutConfig getDefaultConfig()
{
return new Builder().setFullScreen(false).setVirtualSize(768, 1230).build();
}
}
訂閱:
文章 (Atom)