岡山女子エンジニア日誌

プログラミングについて勉強したことを書きます。

もくもく会を一年間開催して

この記事は「もくもく会に行ってきた話 Advent Calendar 2016」の2日目の記事です。

 

こんばんは。

月一で岡山スマホアプリ開発もくもく会Android)を主催しております者です。

この記事を書きながら、岡山スマホアプリ開発もくもく会を開催し始めてからもう一年経ったのか、と感じます。去年の今頃は開催してみたいと思い始めたぐらいだったような気がします。

 

開催するまではかなり気張っていましたが、最近はゆるーーくもくもく会に挑んでしまっています。

丁度一年を機に、また来年気張って開催できるようにこの一年のもくもく会をゆるく振り返ってみようと思います。

 

技術本

最初の一回目は、去年の一月に開催したのですが、図書館で技術本などを借りてきたり、かなり気張っていました。

第二回からは技術本をわざわざ借りて用意するほど必要じゃないかな、と感じて持っている本だけ持っていくようになりました。

 

LT(ライトニングトーク) 

第四回のときは気張ってLTを実施してみたりしましたが、慣れてないのでぐだぐだになってしまいました。いつかリベンジしたい、と思いつつ今年はできませんでした。

来年こそはLTを成功させたいです。

 

もくもく会のHP

5月頃から岡山スマホアプリ開発もくもく会HPを作ろう!と、考えていたのですが、未だ果たされていないです

岡山スマホアプリ開発もくもく会でサーバーを借りてアプリ開発のテストなんかに使えたりしてもいいかなーなんて考えていたのですが、維持費のことを考えると手も足もでませんでした(言い訳)。

これから一ヶ月ほど実家でゆっくりと育児休暇をとる予定なので、その間にHPのレイアウトでも作れたらなと考えております。

 

参加者

第二回のときはかなり参加人数が少なかったですが、最近はだいたい安定して同じくらいの人数で集まっていただいています。

何度か繰り返し来てくださる方や、遠方から遥々来てくださる方までいてとても嬉しかったです。

もくもく会で参加してくださる方に会うといつも開催しててよかった、と思います。

参加してくださる方にも少しでも参加してよかったと思ってもらえるようなもくもく会にしていきたいです。

 

コミュニケーション

第二回のときはシーンとなりすぎてしまって、もっと参加者同士で気軽に話せるような雰囲気作りを、と考えていました。

でも、もくもく会ですからもくもくしたい人もいる、という意見もいただいて、もくもく会でのコミュニケーションって難しいな、と感じました。

もくもく会でベストなコミュニケーションとは

来年の課題です。

 

 

まとめ

思い返すと、本当にたくさんの方々に助けていただいたお陰で、一年間開催し続けられたな、と思います。本当にありがたいです。

来年もちょっとずつよくして(迷走して?)いきながら、続けていけたらいいなと思っています。

とりあえずは、「定期開催で長く続くもくもく会」になれるのを第一目標で頑張っていきたいです。

第一回「岡山Androidもくもく会」

参加していただいた皆様、お疲れさまでした。お忙しい中のご参加ありがとうございました。

お陰様で充実した時間を過ごすことができました(^^)

参加していただいた方たちもそう感じていただけたのか不安ですが、無事に終えれた事にホッとしております。

開催まで

Javaをしたことがない方でもAndroidアプリ開発ができるように、Javaの勉強からできるようにワークショップを作ろうか、とか色々考えていました。

結局、準備できたのは図書館で借りてきたJavaの技術本と買ったAndroid Studioの技術本とJavaの構文のメモでした。

会場の準備は、会場となったギークハウス岡山の住人で参加者の方にしていただきました。本当にありがたいです・・・。

次にギークハウス岡山で開催するときは、私が片付けます><

いよいよスタート

初めて主催したイベントなので、ドキドキしながらのスタートでした。スタートしてからは、それぞれやる事を決めてもくもくしていました。

もくもくしたり、談笑したり、質問したり、終始とてもいい雰囲気だったと思います。そんな感じだったので、開催する前のドキドキは安心に変わりました。

ちゃんともくもく会になってる・・・!!と感動しました。

それもこれも、開催までの間にアドバイスしてくださった皆様、参加してくださった皆様、会場となったギークハウス岡山の皆様のお陰です!

本当にありがとうございます!

振り返って

第一回「Androidもくもく会」は、私にとっては大成功でした。

しかし、失敗もあります。

会場の様子の写真を撮り忘れてしまいました・・・。気付いたときにはすでに時遅し・・・。やらかしました。

アンケートも準備しておけばよかったです・・・。

次回の課題ですね。

 

Androidアプリ開発の初心者の方には、「まるばつクイズアプリ」を作ってもらう事にしました。

毎回何か簡単に作れるお題を考えて、それを初心者の方の目標にしようと思っていました。

でも、今日のもくもく会で、技術本を読んで自分で目標設定してもくもくされている方がいたので、次からは技術本や解説サイトを準備して、それぞれで目標設定してもらうのがいいのかな、と思いました。

 

手探りですが、少しずつ良くしていければいいな、と思います。

最後に

皆様、本当にありがとうございました!

第二回もよろしくお願いいたします。

ギー岡で振り返る2015

もう今年の1月に何していたかとかは忘れてしまいました・・・(笑)

3月くらいまでの記憶が曖昧です。2月までは頑張って授業受けてテストとレポートに追われていたと思います。

3月は何してたかな・・・就職どうしようってなって、企業調べてたと思います。

前期の授業は2つしかとってなかったです。6月くらいまで就活用にプログラム書いていました。結局完成させれなかったです。

7月にギー岡に入居しました。

それからは濃かったですねー。

8月の頭にあったギークハウスデイに参加しました。8月下旬にあった福島ゲームジャムにも参加しました。

9月・・・何してたっけな・・・多分、Androidを始めた月です!

10月には、高梁ゲームジャムに参加しました。

11月はあっという間に通り過ぎて行きました。

12月もあっという間に通り過ぎました。Android開発講座に参加しました。Rails Girlsに参加しました。

 

振り返ると、今までギーク系のイベントに参加したことなかったのですが、今年になって初めて参加してとても楽しかったです!

来年はもっとたくさんのイベントに参加したいです!

ギー岡に入居したのは大きかったです。ギークな人と知り合えて、いろんな話を聞かせてもらえて本当に楽しいし、刺激になりました。

皆様ありがとうございました。来年もよろしくお願いします!

良いお年を!

ギークハウス岡山に住んで変われたこと

この記事はギークハウスAdvent Calendar 2015の16日目の記事です。

ギークハウス岡山に住むまでのいきさつ

ギークハウス岡山に住み始める前までは、周りに趣味でプログラミングしてる人なんていなくて、ずっと一人でプログラミングの勉強してきていました。

私がプログラミングを始めたきっかけは、小さい頃からゲームが好きで、ゲームを作ってみたい!と思ったことからでした。大学に入るときにC++の本を買い、勉強し始めました。本を買ったはいいけど、そんなに読まずにネットで調べてC++の入門サイトで勉強していました。なぜそういう勉強方法になったのか今では覚えていませんが、今にして思えばネットで調べることに慣れるのに丁度良かったと思います。

詰まったらしばらく放置して(1ヶ月ぐらいやってなかったり、2〜3日やってなかったり)、また再開して、でも分からなかったらまた放置して…って感じでかなりだらだら勉強をしていました。でも、ずっと続けていたのは、バグがつぶせたときのスッキリ感が凄く気持ち良かったからだと思います。

そうして勉強していたものの、きっかけとなったゲーム作りは全くできませんでした。それは、多分、自分の中で作りたいゲームがなかったからゲームを完成させるという具体的なビジョンが持てなかったからだと思います。

そんな感じで特に何かを完成させるということはなくだらだら勉強していましたが、ずっと続けてきました。それは、何よりもプログラミングが楽しいと感じられたからだと思います。そうしているうちに「プログラミングをする仕事をしたい」、と思うようになっていきました。

しかし、どうすればいいのか分かりませんでした。ネットで調べてみてもわからなかったし、周りにプログラミングをしている人もおらず、どうしていいのか分からないまま就職の時期を迎えました。

プログラマーを募集しているゲーム会社を調べると、一次審査に作品の提出が必要だと書いてあって、作品を作ろうとするも完成させることができず、ただ締め切りが過ぎていきました。今年はもう無理だ、諦めよう、でもプログラマーになりたい…どうしよう、何か行動したい。と考えていた時にたまたま深夜のテレビ番組でギークハウス岡山が紹介されていました。

最初はこんなのもあるんだなーくらいにしか思っていなかったのですが、母にここ行けばいいんじゃない、と言われ(本人はきっと軽い気持ちで言ったのでしょうが)、自分の中でギークハウス岡山に入居するという選択肢ができました。考えているうちに、何か行動したいならこれはチャンスかもしれない、と思うようになると早速ギークハウス岡山のHPをググりました。

HPを見ているうちに入居したら今の現状を変えられるかもしれない、と思うようになり、一応両親に相談してみると意外とあっさり許可が取れ、コンタクトをとってみることにしました。

初めてギークハウス岡山に行った時に、プログラマーはいないと言われて少し面食らったのを覚えています。しかし、プログラマーが集まるイベントをギークハウス岡山で開催する、ということを聞いて入居を決意しました。

 

ギークハウス岡山に住んでから

初めて参加したイベントがギークハウスデイ2015で、そこでUnityを使ったアプリケーションの作成を一緒にさせてもらえました。他の人と一緒に開発する、というのは初めてでとても緊張したのを覚えています。しかし、今までずっと一人で勉強してきた私にとっては他の人と一緒に開発する、ということが新鮮で、凄く楽しかったです。

そこで初めてアプリケーションを完成させる、という経験ができました。今まで何も完成させたことがなかった私にとってはそれが凄く嬉しくて、その時に初めてギークハウスに入居してよかった!と思いました。

ギークハウスデイ2015を通して岡山Unity勉強会さんと知り合うことができ、福島ゲームジャムと高梁市ゲームジャムに参加することができました。

そこでゲームを作って気づいたことがあります。私はやっぱり一人でのアプリケーション開発がかなり苦手だ、ということです。作るアプリケーションのアイデアがどうしてもまとめれないのです。今まで何も完成させることができなかったのは、技術が足りてないからだ、と思っていましたが、それだけじゃなく、作るものの構想ができてなかったんだな、と気付きました。

もう一つ、今までゲーム開発ができたら楽しいんだろうな、と憧れも抱いていましたが、実際に作ってみると、ゲーム開発よりもプログラムの勉強をするほうが楽しい、ということが分かりました。

これらは、ずっと一人でだらだらとしていたら気づけなかったことです。ギークハウスに住み始めてから、刺激的で貴重な体験をすることができました。

 

ギークハウス岡山に住んでから変われたこと

だらだらと書いてしまいましたが、私がギークハウス岡山に住んで変われたことは、

  • アプリケーションを完成させる経験ができた
  • ギークの人たちと交流を持つことができた
  • プログラミングがより楽しくなった
  • SNSの重要性が分かった(お恥ずかしながら、ごく最近です。イベントを開催する計画を立てて初めて分かりました。)
  • 本当に一人だけの独学には限界がある(ギークハウスに入居してから5ヶ月間の技術力の伸びは、3年間の独学より遥かに大きいです。びっくり!)

などなど、挙げるともうきりがないです(笑)

ギークハウスに住むことは、自分を変えるきっかけになりました。

 

最後に

貴重な経験をさせていただき、色々なことを学ばせていただけて、ギークハウスに入居してから関わってきた全ての方々に心から感謝します。

ギークハウス岡山に入居してよかったー!!心からそう思います。

 

<宣伝 class="岡山Android勉強会"> 岡山にAndroidのコミュニティがないので、作っていこうとしております。そのための活動として、1/17(日)にギークハウス岡山で「岡山Androidもくもく会」を開催します。</宣伝>

※リツートしていただいてありがとうございます!!

AndroidStudio開発講座に参加して勉強したこと

2015/12/12に開催された「有山圭二氏によるAndroid Studio開発講座」に参加しました。

【2015/12/12】有山圭二氏によるAndroid Studio開発講座 - 日本Androidの会 香川支部

こちらのイベントです!

 

スピードについていけず(AndroidStudioも動かなくなったし・・・というのは言い訳ですね(><;))、とりあえず理解できたことをまとめようと思います。

 

目次

 

ショートカットキー

エラーに飛ぶ

F2

ShiftF2

 

修正候補を選択する、 文字列リソースの作成、 レイアウトの作成

Mac

Optionreturn

 

Windows

Altreturn

 

Code Generation

Mac

CommandN

 

Windows

Altinsert

 

Code Generation

変数名が「mName」のように最初に「m」などをつけている場合、そのままCode Generationをすると、getterの名前が「getmName」になってしまいます。そうならないために、NamingPreficを設定する必要があります。

まず、[Preferences]を開きます。次に、左のタグの[Editor]>[Code Style]>[Java]を開き、右のタグの[Code Generation]を開きます。そこの[Naming]の[Field:][Name prefix:]に「m」を書くといいみたいです。

 

Butter Knife

Butter Knifeは、Jake WhartonさんによるAnroid用のView Injectionライブラリみたいです。

Butter Knifeを使うと、「findViewById」が楽にかける・「onClickListener」が楽にかけるみたいです。

Butter Knifeを使うには、まず、[file]>[Project Structure]を開きます。ショートカットキーはMacだと「command + ;」です。

次に、左の[Modules]>[app]を開き、上のタグの[Dependencies]を開きます。「+」をクリックするとライブラリを選ぶダイアログが出てくるので、そこで「butterknife」を検索すると、「com.jakewharton:butterknife:7.0.1」があるのでそれを選んで、「OK」します。すると、ネットにアクセスしてButter Knifeのライブラリを取ってきます。終わるまでしばらくかかるので待ってあげてください。

あとは、こちらのサイトを参考にしてください。下に「findViewById」が楽にかけるサンプルを載せておきます。

public class MainActivity extends AppCompatActivity {
@Bind(R.id.button)
Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ButterKnife.bind(this);
}

//以下略
 

まとめ

ここに載せたもの以外にも、「リファクタリング」と「ユニットテスト(JUnit4)」の説明もされていましたが、よくわからなかったので、ここでは書きません。調べていつか記事を書こうと思います。

この後に、出席者からあらかじめ伺っていた質問に答えられていました。最初にもうすぐ発売される「Android Studioではじめる簡単Androidアプリ開発」をご紹介されていました。AndroidStudio1.5に対応していて、1月4日に発売されるそうです。ぜひお買い求めを!

 

貴重なお話をしてくださった有山圭二様、このような素晴らしいイベントを開催してくださった日本Androidの会香川支部様、当日お世話になった皆様、ありがとうございました。

AndroidStudio カスタムビューの作り方

自分で作ったカスタムビューをレイアウトファイルで配置するまでの手順を書きます。カスタムビューを作ると、そのビューの使い回しができ、とても便利だと思います。また、カスタムビューを使うと、レイアウトファイルが複雑にならなくていいかもしれないです。
AndroidStudioを始めたばかりの人でも分かりやすいように書いていきたいと思っています。
調べていると、カスタムビューは二種類に分けることができるんじゃないか、と思いました。他では分けていないと思うので、一般的ではないですが、ここではカスタムビューをカスタムレイアウトとカスタムビューの二種類に分けて書いていきます。

目次

カスタムレイアウト

カスタムレイアウトでは、ViewGroupクラスのサブクラスを継承したクラスを作ります。レイアウトxmlファイルを使ってカスタムビューをデザインできます。もちろんJavaでもコンポーネントの追加ができますが、ここでは紹介しません。
ここで作るサンプル

f:id:to-2a721:20151202010056p:plain

EditTextに文字を入力して「送信」Buttonを押すと、EditTextの下のTextViewがEditTextの内容に変わり、EditTextは空になります。
大雑把な手順
1. res/layoutフォルダの中に、レイアウトファイルを作る。
2. ViewGroupのサブクラスを継承したjavaクラスを作る。
3. メインのレイアウトファイルにカスタムレイアウトを配置する。
詳しい説明
1.res/layoutフォルダの中に、レイアウトファイルを作る。
res/layoutフォルダの中に作りたいカスタムレイアウトのxmlファイルを作る。

f:id:to-2a721:20151201225836p:plain

f:id:to-2a721:20151201230053p:plain

f:id:to-2a721:20151201230108p:plain

サンプル「res/layout/custom_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">

<EditText
android:layout_width="250dp"
android:layout_height="wrap_content"
android:id="@+id/editText" />

<Button
android:layout_width="70dp"
android:layout_height="wrap_content"
android:text="送信"
android:id="@+id/button" />

</LinearLayout>

<TextView
android:layout_width="320dp"
android:layout_height="wrap_content"
android:text="New Text"
android:gravity="center"
android:id="@+id/textView"
android:textSize="50px" />

</LinearLayout>
このレイアウトファイルは、以下の図のような構造になっています。
エディットテキスト ボタン
テキストビュー
2. ViewGroupのサブクラスを継承したjavaクラスを作る。
javaフォルダの中に新しいjavaクラスを作る

f:id:to-2a721:20151201234139p:plain

f:id:to-2a721:20151202000118p:plain

f:id:to-2a721:20151202000126p:plain

サンプル「java/***/CustomLayout.java
package com.***.***.***;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;


public class CustomLayout extends LinearLayout implements View.OnClickListener {
private TextView text;
private EditText editText;

public CustomLayout(Context context, AttributeSet attr) {
super(context, attr);

View layout = LayoutInflater.from(context).inflate(R.layout.custom_layout, this);

text = (TextView)layout.findViewById(R.id.textView);
editText = (EditText)layout.findViewById(R.id.editText);
Button button = (Button)layout.findViewById(R.id.button);
button.setOnClickListener(this);
}

public void onClick(View view) {
if(view.getId() == R.id.button) {
text.setText(editText.getText());
editText.setText(null);
}
}
}
CustomLayoutクラスは、ViewGroupクラスのサブクラスであるLinearLayoutを継承し、OnClickListenerインターフェイスを実装しています。
LinearLayoutクラスは、先ほど作成したレイアウトのルートがLinearLayoutなので、継承させています。
ViewGroupについては、こちらのサイトをご覧ください。
OnClickListenerは、ボタンが押されたことを知るために実装させています。
OnClickListenerについては、

こちらのサイトを参考にさせていただきました。
コンストラクタでは、まず、親クラスのコンストラクタを呼び出しています。
次の
LayoutInflater.from(context).inflate(R.layout.custom_layout, this);
この文では、先ほど作ったレイアウトファイルを設定しています。
詳しくは、こちらのサイトをご覧ください。
OnClick( )関数では、テキストビューのテキストをエディットテキストの内容に変えて、エディットテキストを空にしています。
3. メインのレイアウトファイルにカスタムレイアウトを配置する。
サンプル「res/layout/activity_main.xml」(デフォルトからいじっていなければこの名前になっているはず。)
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<com.example.kondoutomoko.android_test.CustomLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<com.example.kondoutomoko.android_test.CustomLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<com.example.kondoutomoko.android_test.CustomLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>
このレイアウトファイルでは、先ほど作ったカスタムレイアウトを縦に3つ並べています。

カスタムビュー

カスタムビューでは、Viewクラスを継承したクラスを作ります。
先ほどのカスタムレイアウトではあまり意味がないので書きませんでしたが、MainActivityのsetContentView(View) メソッドの引数には、レイアウトファイルのIDだけでなく、Viewクラスのサブクラスも渡すことができます。先ほどのカスタムレイアウトでは、CustomLayoutクラスを渡すことができます。この記事では、setContentView(View)メソッドにクラスを渡す方法は省略させていただきます。
ここで作るサンプル

f:id:to-2a721:20151205153737p:plain

それぞれのコンポーネントをタップすると、色が変わります。
大雑把な手順
1. Viewクラスを継承したJavaクラスを作る。
2. メインのレイアウトファイルにカスタムビューを配置する。
詳しい説明
1.Viewクラスを継承したJavaクラスを作る。
サンプル「java/***/CustomView.java
package com.***.***.***;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;


public class CustomView extends View {
private int status;
private Paint paint;
private Rect rect;

public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);

Init();
}

private void Init() {
status = 0;
paint = new Paint();
paint.setColor(getColor());
rect = new Rect();
}

@Override
protected void onSizeChanged(int w, int h, int old_w, int old_h) {
rect.left = w/10;
rect.top = h/10;
rect.right = w*9/10;
rect.bottom = h*9/10;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

canvas.drawRect(rect, paint);
}

@Override
public boolean onTouchEvent(MotionEvent e) {
if(e.getAction() == MotionEvent.ACTION_DOWN) {
status = (status >= 2) ? 0 : status+1;
paint.setColor(getColor());
invalidate();
}
return true;
}

private int getColor() {
int color;

switch(this.status) {
case 0:
color = Color.RED;
break;
case 1:
color = Color.GREEN;
break;
case 2:
color = Color.BLUE;
break;
default:
color = Color.BLACK;
}
return color;
}
}

Viewクラスを継承しています。コンストラクタでは、親クラスのコンストラクタを呼び、メンバ変数を初期化しています。カスタムビューでは、onSizeChanged()メソッドとonDraw()メソッドをオーバーライドする必要があります。
onSizeChanged()メソッドでは、コンポーネントの元のサイズと変更後のサイズを得ることができます。
onDraw()メソッドでは、コンポーネント上に画像や図形などを描画することができます。
2. メインのレイアウトファイルにカスタムビューを配置する。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<com.example.kondoutomoko.android_test.CustomView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_weight="1" />

<com.example.kondoutomoko.android_test.CustomView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_weight="1" />

<com.example.kondoutomoko.android_test.CustomView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_weight="1" />

</LinearLayout>
カスタムビューを縦に3つ並べています。
全ての「android:layout_weight」に1を設定しているので、それぞれのコンポーネントの高さはルートのLinearLayoutの高さの三分の一になっています。

styleableプロパティの使い方

独自のプロパティを設定するには、styleableプロパティを使います。
先ほどのカスタムレイアウトにstyleableプロパティを設定し、汎用性を持たせてみます。
ここで作るサンプル

f:id:to-2a721:20151205031937p:plain

カスタムレイアウトのサンプルと比べると、Buttonのテキストが変わっています。また、「削除」Buttonを押してもTextViewのテキストが変わらないようになっています。
大雑把な手順
1. 「res/values」フォルダの中にxmlリソースファイルを作る。
2. リソースファイルで定義したプロパティをCustomLayoutクラスで読み込む。
3. メインのレイアウトファイルで、リソースファイルで定義したプロパティに値をセットする。
詳しい説明
1. 「res/values」フォルダの中にxmlリソースファイルを作る。
カスタムレイアウトでレイアウトファイルを追加したのと同様に、「res/values」フォルダの中に「custom_layout_attr.xml」を作成する。
サンプル「res/values/custom_layout_attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomLayout">
<attr name="EnableToSend" format="boolean"></attr>
<attr name="ButtonName" format="enum">
<enum name="send" value="0" />
<enum name="save" value="1" />
<enum name="delete" value="2" />
</attr>
</declare-styleable>
</resources>
declare-styleableラベルのname属性の値が識別子となります。プロパティを読み込むクラスと同じ名前にします。
attrラベルでプロパティを定義します。format属性に設定できる値は、下の図の通りです。
意味
boolean boolean値。(例:true)
integer int値。(例:2)
float float値。(例:1.6)
string 文字列。(例:"あいう" or "@string/***")
enum 列挙型。(例:{ a=1, b=2, c=3 })
flag ビットフラグ。(例:{ a=1, b=2, c=4 })
dimension dimension単位。(例:100dp)
color 色。(例:"#ABCDEF" or "@color/***)
reference リソースIDの参照。(例:"@drawable/***"等)
2. リソースファイルで定義したプロパティをCustomLayoutクラスで読み込む。
CustomLayout.javaを下のサンプルのように変更する。赤い文字のところが変更したところになります。
サンプル「java/***/CustomLayout.java
package com.***.***.***;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;


public class CustomLayout extends LinearLayout implements View.OnClickListener {
private TextView text;
private EditText editText;
private boolean mEnableToSend;
private int mButtonName;

public CustomLayout(Context context, AttributeSet attr) {
super(context, attr);
View layout = LayoutInflater.from(context).inflate(R.layout.custom_layout, this);

TypedArray a = context.obtainStyledAttributes(
attr, R.styleable.CustomLayout, 0, 0);
try {
mEnableToSend = a.getBoolean(R.styleable.CustomLayout_EnableToSend, true);
mButtonName = a.getInteger(R.styleable.CustomLayout_ButtonName, 0);
} finally {
a.recycle();
}

text = (TextView)layout.findViewById(R.id.textView);
editText = (EditText)layout.findViewById(R.id.editText);

Button button = (Button)layout.findViewById(R.id.button);
button.setOnClickListener(this);
switch(mButtonName) {
default:
case 0:
button.setText("送信");
break;
case 1:
button.setText("保存");
break;
case 2:
button.setText("削除");
break;
}
}

public void onClick(View view) {
if (view.getId() == R.id.button) {
if (mEnableToSend)
text.setText(editText.getText());
editText.setText(null);
}
}
}
まず、
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomLayout, 0, 0);
この文で a に「custom_layout_attr.xml」で定義したプロパティを読み込んでいます。
次に、
getBoolean()やgetInteger()でプロパティに設定した値を読み込んでいます。これらの関数の第二引数は初期値となっています。他のフォーマットを読み込む関数も用意されています。詳しくは、こちら(Android developerのReference)をご覧ください。
そして、とても重要なことがあります。obtainStyledAttributes()で取得したTypedArrayは、共用資源なので、必ずrecycle()を呼ぶ必要があります。
後の変更は重要ではないので、説明は省略します。
3. メインのレイアウトファイルで、リソースファイルで定義したプロパティに値をセットする。
コンポーネント毎にそれぞれ値を設定することで、同じカスタムレイアウトでも違う機能や見た目を提供することができます。
サンプル「res/layout/activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<com.example.kondoutomoko.android_test.CustomLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
custom:EnableToSend="true"
custom:ButtonName="send" />

<com.example.kondoutomoko.android_test.CustomLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
custom:EnableToSend="true"
custom:ButtonName="save" />

<com.example.kondoutomoko.android_test.CustomLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
custom:EnableToSend="false"
custom:ButtonName="delete" />

</LinearLayout>

上から3行目の、
では、http://schemas.android.com/apk/res-autoという長ったらしいURLをcustomで表すよ、という宣言になっています。
同じコンポーネントでもstyleableプロパティに設定する値を変えることで、違う機能や見た目を提供することができます。

まとめ

私がカスタムビューをカスタムレイアウトとカスタムビューに分けた理由は、以下の3点からです。
1. 継承するクラスが違う
2. カスタムビューでは、onDraw()メソッドをオーバーライドする必要があるが、カスタムレイアウトではしない
3. カスタムレイアウトではレイアウトファイルを読み込むことができるが、カスタムビューではできない
既存のコンポーネントを配置する場合はカスタムレイアウトを作り、オリジナルのビューを作りたい場合はカスタムビューを作る、というふうに使い分けることができると思います。
styleableプロパティを上手に設定できると、他のアプリケーションでも使いまわせるコンポーネントを作ることができそうです。