Android タイトルバーのカスタマイズ

まずは, タイトルバーをカスタマイズしたいアクティビティで,

//....

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);

//これらのメソッドの実行順序を変更するとカスタマイズエラーになる
 requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
 setContentView(R.layout.activity_main);
 getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.activity_main_title);

 //....
}

//....

次に, styles.xmlにカスタムのスタイルを追加する.

<resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- .... -->
     <style name="CustomTheme"parent="android:Theme">
        <!-- タイトルバーの高さ -->
        <item name="android:windowTitleSize">24dp</item>
        <!-- デフォルトのタイトルバーを無効にする --> <item name="android:windowTitleBackgroundStyle">@null</item>
     </style>
</resources>

 そして, マニフェスト (AndroidManifest.xml) にstyles.xmlで定義したスタイルを設定する.

    <application
        ....
        android:theme="@style/CustomTheme"> ....

最後に, タイトルバーのレイアウトをXMLで定義すればOK. ファイル名はアクティビティで指定したもの (今回の例だと, activity_main_title.xml)

<?xml version="1.0"encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="24dp"
     android:background="#CC0000">

     <TextView
          android:id="@+id/text_title"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_centerInParent="true"
          android:paddingLeft="8dp"
          android:textColor="#FFFFFF"
          android:textSize="16sp"
          android:textStyle="bold"
          android:text="@string/app_name"/>

</RelativeLayout>

ちなみに, こちらのサイトが非常に参考になりました.

Android レイアウトファイルでボタンのデザイン

Androidでは, レイアウトファイルのXMLを役割ごとに定義して順に読み込んでいくことで, 画像をできる限り利用しない, CSS3のような感じでボタンをデザインできる.

例えば, まずは, トップのレイアウトXMLを定義する.

button_background.xml

<?xml version="1.0"encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_layer_list_press" android:state_pressed="true" />
<item android:drawable="@drawable/button_layer_list" /></selector>

とりあえず, 通常状態とpresss時に読み込むレイアウトXML (layer-list) を定義する.

次に, 読み込まれるレイアウトXML (layer-list) を定義する.

button_layer_list.xml

<?xml version="1.0"encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_shadow" />
<item android:drawable="@drawable/button_round_rect" android:bottom="2dp" />
</layer-list>

bottomに2dpを設定しているのは, 通常時は下方向にシャドウを見せたいので.

次は, press時のlayer-listを定義.

button_layer_list_press.xml

<?xml version="1.0"encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_shadow" />
<item android:drawable="@drawable/button_round_rect" android:top="2dp"android:left="2dp"android:right="2dp" />
</layer-list>

top, left, rightに2dpを設定しているのは, ボタンを押した状態を表現したいので.

layer-listにより, ボタンのレイヤーを定義しました. 通常時とpress時は共通して, まず, シャドウを描画してその上に角丸の長方形 (ボタン本体) を描画するという定義になっています.

あとは, シャドウの定義と角丸の長方形をXMLで定義すればOKです,

button_shadow.xml

<?xml version="1.0"encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

     <solid android:color="#AAAAAA" />
     <size
          android:width="5dp"
          android:height="5dp" />
     <corners
         android:topLeftRadius="5dp"
         android:topRightRadius="5dp"
         android:bottomLeftRadius="5dp"
         android:bottomRightRadius="5dp" />

</shape>

button_round_rect.xml

<?xml version="1.0"encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners
    android:topLeftRadius="2dp"
    android:topRightRadius="2dp"
    android:bottomLeftRadius="2dp"
     android:bottomRightRadius="2dp" />

</shape>

これで, ボタンの定義は完了です. これらのXMLはdrawableディレクトリ以下に置いておきます.

あとは, Buttonウィジェットなどの定義で, ボタン定義のトップとなるbutton_background.xmlを読み込めば完成です.

 <Button
     android:layout_width="match_parent"
     android:layout_height="wrap_content"   
     android:background="@drawable/button_background"
     android:textColor="#666666"
     android:textSize="18sp"
     android:text="Button" />

今回は, 通常時とpress時は共通のシャドウとシェイプを利用しましたが, これらを別々のデザインにすることも可能です. そのためのXMLを定義して読み込むだけです.

慣れれば, CSS3でデザインするような感覚で簡単にかつ自由度の高いデザインが可能になると思います.

ちなみに, こちらのサイトが非常に参考になりました.

Photoshop 写真の一部分を選択する

Photoshopで写真の一部分 (オブジェクト) を選択する方法はいくつかありますが, もっとも精彩に選択できる方法は,

  1. マグネットツール or 多角形ツールでおおよそを選択
  2. クイックマスクモードで編集  -> ディテール部分を調整
  3. 画像描画モードで編集

久々に使ったので, 書いておきました.

Android ListViewのテキストのスタイルを設定する

こんな感じ

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice, urls) {
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
         TextView view = (TextView)super.getView(position, convertView, parent);

          //テキストのスタイル設定
          view.setTextSize(12);
          // ... etc

         return view;
    }
};

JavaScript Object.freezeの注意点

ECMAScript第5版で定義されたObjectのfreezeクラスメソッド.

不変オブジェクトを作成するためのメソッドだけども,

1つ落とし穴があるということを知った.

それは…, 再帰的には適用されないということ.

つまり, 以下のような場合は, 中身が変更できてしまう.

var recursiveObject = {
    a : 0,
     b : 'hoge',
     c : ['a', 'b', 'c'],
     d ] {a : 1, b : 2, c : 3}
};

この場合, Object.freezeを適用しても, 参照で配列や内側のオブジェクトを変更できてしまう.

Object.freezeの再帰処理は自前で実装するしかない.

Android SQLite フェッチ系の処理

public class Database extends SQLiteOpenHelper {
    //....

    //例えばすべてのレコードを取得するメソッド
    public List<Map<String, String>> fetchAll() {
        List<Map<String, String>> results = new ArrayList<Map<String, String>>();
        String[] columns = {"id"};
       Cursor cursor = this.getReadableDatabase().query("tablename", columns, null, null, null, null, "created_at DESC");

       //カーソルを先頭に移動させる必要あり !!
      if (cursor.moveToFirst()) {
           while (!cursor.isLast()) {
                //現在のカーソル位置のレコードを取得する処理

                cursor.moveToNext();
          }
      }

      //....

ポイントは, cursor.moveToFirst()でカーソルを先頭に移動させておくことです.