ExpandableListViewっぽいものを独自で実装してみる
ExpandableListViewの使い方覚えるが面倒で、更にカスタマイズしてみたけど開閉ボタンの消し方が分からなかったので、結局それっぽものを自作してみた。
※drawableのxmlは省略
ヘッダーのレイアウト
list_header.xml
<?xml version="1.0" encoding="utf-8"?> <com.sample.RowHeader xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/header"> <TextView android:id="@+id/header" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textColor="#FFFFFFFF" android:textSize="20sp"/> </com.sample.RowHeader>
列のレイアウト
list_row.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/row"> <TextView android:id="@+id/row" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textColor="#FF000000" android:textSize="15sp"/> </LinearLayout>
メイン
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/virtual_listview" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > </LinearLayout>
ヘッダークラス
RowHeader.java
package com.sample; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; public class RowHeader extends LinearLayout { public boolean mIsExpanded; public List<View> mRows; public RowHeader(Context context, AttributeSet attr) { super(context, attr); mIsExpanded = false; mRows = new ArrayList<View>(); } public boolean isExpanded() { return mIsExpanded; } public void expand() { mIsExpanded = true; for (final View v : mRows) { v.setVisibility(View.VISIBLE); } } public void collapse() { mIsExpanded = false; for (final View v : mRows) { v.setVisibility(View.GONE); } } public List<View> getRows() { return mRows; } public int getRowCount() { return mRows.size(); } public void addRow(View row) { mRows.add(row); } }
メイン
package com.sample; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends Activity { private Map<String, List<String>> map; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); map = new HashMap<String, List<String>>() { { put("哺乳類", new ArrayList<String>() {{ add("イヌ"); add("ネコ"); add("イルカ"); }} ); } { put("鳥類", new ArrayList<String>() {{ add("スズメ"); add("ペンギン"); }} ); } { put("魚類", new ArrayList<String>() {{ add("ブリ"); }} ); } }; // 擬似リストビュー final LinearLayout listView = (LinearLayout) findViewById(R.id.virtual_listview); for (final Entry<String, List<String>> set : map.entrySet()) { // ヘッダーのレイアウトを取得してテキストを設定 RowHeader headerLayout = (RowHeader) View.inflate(this, R.layout.list_header, null); TextView headerText = (TextView) headerLayout.findViewById(R.id.header); headerText.setText(set.getKey()); // ヘッダークリックイベント headerLayout.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { RowHeader headerView = (RowHeader) v; // ヘッダーが親から見て何番目にあるかを取得 int index = listView.indexOfChild(headerView); if (headerView.getRowCount() == 0) { // 0の場合は子どもがまだ生成されていない List<String> rows = set.getValue(); for (String row : rows) { LinearLayout rowLayout = (LinearLayout) View.inflate(MainActivity.this, R.layout.list_row, null); TextView rowText = (TextView) rowLayout.findViewById(R.id.row); rowText.setText(row); // ヘッダーの次のインデックスにどんどん追加 listView.addView(rowLayout, ++index); headerView.addRow(rowLayout); } } if (headerView.isExpanded()) { headerView.collapse(); // 閉じる } else { headerView.expand(); // 開く } } }); listView.addView(headerLayout); } } }
アニメーションがうまくつかねー
>>2011/07/25 追記
expandableListView.setGroupIndicator(null)
でインジケーター消せた<<2011/07/25
node.jsに触れてみた
node.js公式
インストール
wget http://nodejs.org/dist/node-v0.4.1.tar.gz tar zxvf node-v0.4.1.tar.gz cd node-v0.4.1 ./configure make make install
Hello node.js!!
公式にあるサンプルを実行してみる。
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(8124, "127.0.0.1"); console.log('Server running at http://127.0.0.1:8124/');
サーバーにブラウザでアクセスすると「Hello World」が表示された!
なんだかオラわくわくしてきたぞ!
仕事で使うことはないけどな!!
初心者に厳しいAndroid開発環境構築
Androidネタがたまってきたので、まず開発環境構築から。
よくWindowsで…とかMacで…とかってあるけど、基本的にそんなの関係ねぇ、ということを認識して欲しいです。
eclipseのダウンロード
Eclipse公式(英語)
http://www.eclipse.org/downloads/
*1
デフォルトで日本語がいい!
MergeDoc
http://mergedoc.sourceforge.jp/
*2
Androidプラットフォームのインストールとエミュレータ起動
%SDK_HOME%tools/android を実行してAndroid SDK and AVD Managerを起動。
[Available packages]を選択し[Packages available for download]の[Android Repository]を展開。
・Android SDK Tools
・SDK Platform Android 3.0
にチェックをいれてインストール。(結構時間がかかる)
完了したら[Virtual devices]を選択し[New]。
NameとTarget(Android3.0)を設定して[Create AVD]。
作成したAVDを選択して[Start]で[Launch Options]が開くので[Scale display to real size]にチェックを入れて
Screen Size: 68
Monitor dip: 160 *3
で[Launch]。
*4
なぜかMOTOROLA XOOMが立ち上がります。(これまた結構時間がかかる)
MOTOROLA XOOM公式
http://www.motorola.com/Consumers/US-EN/Consumer-Product-and-Services/Tablets/ci.MOTOROLA-XOOM-US-EN.overview
>>2011/07/25 追記
XOOMじゃなくてこれがAndroid3.0のUIだったのね。。。<<2011/07/25
KDDI公式
http://www.kddi.com/corporate/news_release/2011/0228a/index.html
Android ADT Pluginのインストール
Name: Android ADT Plugin (任意)
Location: https://dl-ssl.google.com/android/eclipse/
Developer Toolが出てくるのでチェックしてすべてインストール・再起動。
eclipseにAndroid SDKのパスを設定
設定画面に[Android]の項目が増えてるので選択。
※ここでレポートを送信するみたいなダイアログが出るので消す。これ重要。
SDK LocationにAndroid SDKへのパスを設定しApply。
一覧にプラットフォーム名等ずらっとでれば設定完了。
Androidプロジェクトの作成
eclipseツールバーのこれクリック(たぶんデフォルトは左から5つ目)
Contents: Create project from existing sample
Build Target: Android 3.0
を選択して[finish]。
※最初はSamplesのプルダウンをApiDemosがおすすめ
生成されたプロジェクトを選択して[Run As]→[Android Application]でアプリケーションのインストールが開始・起動。
※コンソールにこんなエラーが出ちゃった場合
You must perform a full uninstall of the application. WARNING: This will remove the application data!
Please execute 'adb uninstall com.example.android.apis' in a shell.
%SDK_HOME%/platform-toolsにadbってのがあるので、書いてあるとおりに
adb uninstall com.example.android.apis
を実行し、再度Run As Android Applicationしましょう。
Linq with inheritable Dao
Linq to SQLでDAOパターンかつCRUDな感じにしたくてInterfaceとかabstractでいろいろやっていたのだが、ジェネリックでシンプルに解決できそうなのでメモ。
DBの後始末等いろいろ雑なのはご愛嬌。
ポイントは
public class BaseDao : IDisposable { protected MyDatabase ctx; public BaseDao() { this.ctx = new MyDatabase(Resources.ConnectionString); } public T Find<T>(T entity) where T : class { <del>try {</del> return (from o in this.ctx.GetTable<T>() where o == entity select o).Single<T>(); <del>} catch (Exception e) { throw e; }</del> } public IEnumerable<T> FindAll<T>() where T : class { try { return from o in this.ctx.GetTable<T>() select o; } catch (Exception e) { throw e; } } public void Put<T>(T entity) where T : class { try { this.ctx.GetTable<T>().InsertOnSubmit(entity); this.ctx.SubmitChanges(); } catch (Exception e) { throw e; } } public void Delete<T>(T entity) where T : class { try { this.ctx.GetTable<T>().DeleteOnSubmit(entity); this.ctx.SubmitChanges(); } catch (Exception e) { throw e; } } #region IDisposable Members public MyDatabase GetContext() { return this.ctx; } public void Dispose() { this.ctx.Dispose(); } #endregion }
あ、Updateがねぇや。まぁ、あとはこれを継承して使うと。
C#の情報って@○T(伏字)とかばっかで古いのしか見つからないんだけど、みんなどうしてんの??
今回参考にしたのはこちら。
http://blogs.msdn.com/b/msmossyblog/archive/2009/01/11/linq-to-sql-poormans-dao-crud.aspx
【2010/12/05 追記】
例外処理が仕方が間違っている。
Findについてはクエリをreturnしているだけなので、この時点では評価は行われていませんと。
これを実際にforeachなどするときに例外処理すべし。
参考にさせていただきました。
http://d.hatena.ne.jp/gsf_zero1/20091204/p3
eclipseでlift
やっぱりIDE使った方が学習効率がいってもんで、
eclipseにliftプロジェクトを作成してみます。
プロジェクトの作成まではこちら。
http://d.hatena.ne.jp/ktdk/20100507
作成したらディレクトリの中に入って、
mvn eclipse:eclipse
これでeclipseに必要なファイルとか作成されます。
eclipseを起動して、Scalaプラグインを入れましょう。
URL:http://www.scala-lang.org/scala-eclipse-plugin
プラグインのインストールが完了したら、
[ファイル]>[インポート]>[一般]>[既存プロジェクトをワークスペースへ]で
該当するプロジェクトをインポートします。
次にコマンドラインから以下を実行。
mvn -Declipse.workspace="[ワークスペースのディレクトリ名]" eclipse:add-maven-repo
あと、プロジェクトのプロパティからJavaのビルドパスを開いて、
変数にM2_REPOを追加する。(%USER%はユーザー名ディレクトリ)
M2_REPO = %USER%\.m2\repository
んで[実行]>[実行の構成]>[Scalaアプリケーション]に新規構成を追加し、
プロジェクト名:helloworld (例)
メインクラス:RunWebApp
と入力して実行。
Jettyが正常に起動すればOKです。
lift入門
scalaをいじってみたけど、実際に何か作ってみないとよくわからんので、
Twitter、foursquareも使っているというliftに入門してみた。
環境
プロジェクトの作成
ここからが本番です。以下を実行。
mvn archetype:generate -U \ -DarchetypeGroupId=net.liftweb \ -DarchetypeArtifactId=lift-archetype-basic \ -DarchetypeVersion=1.1-M8 \ -DarchetypeRepository=http://scala-tools.org/repo-releases \ -DremoteRepositories=http://scala-tools.org/repo-releases \ -DgroupId=demo.helloworld \ -DartifactId=helloworld \ -Dversion=1.0
archetype:create とご説明している方もいらっしゃいますが、現在は generate になっているみたい。
DarchetypeVersion は1.0だとサーバー起動後にアクセスエラーになりました。(scalaのバージョンが悪かったのかな?)
【2010/05/17 追記 >>】
http://scala-tools.org/repo-releases/net/liftweb に、
Archetypeごとのリポジトリがあるので、バージョンを随時チェック。
現時点の最新は 2.0-M5。
【<< 2010/05/17 追記】
んで
cd helloworld mvn jetty:run ... [INFO] Started Jetty Server [INFO] Starting scanner at interval of 5 seconds.
と実行して、http://localhost:8080/ にアクセスすると以下の画面が表示されます。
(初回起動時は結構時間がかかります)
起動ポートを変えたい場合は、
mvn jetty:run -Djetty.port=80
ってやればおk。
基本的な導入自体はすごく簡単だけど、やっぱり気をつけなくちゃいけないのが、
言語とフレームワークのバージョン。rails もなんか怪しいときあったし。
もっと実例が増えることに期待。