Androidでラジオボタン

Androidでラジオボタン

Androidでラジオボタンを使うには
RadioButtonを使う

RadioButtonはいくつでも設置できるけど
同グループと判断するためには
RadioGroupを使って
RadioButtonを覆う必要がある

このあたりはjQueryMobileやっていると
概念的にわかりやすい

まず、レイアウトファイルで
RadioGroupの中へ
RadioButtonを設置する

<RadioGroup
android:id="@+id/radiogroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">

<RadioButton
android:id="@+id/rbtn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ボタン1"/>

<RadioButton
android:id="@+id/rbtn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="ボタン2"/>

<RadioButton
android:id="@+id/rbtn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ボタン3"/>

</RadioGroup>

次に、Javaでクリックイベント取得

RadioButtonのクリックイベント取得には
RadioButtonへ
setOnCheckedChangeListener
をセットして
クリックしたRadioButtonのidを判別する

RadioGroup radioGroup = (RadioGroup)findViewById(R.id.radiogroup);
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener(){

public void onCheckedChanged(RadioGroup group, int checkedId){

RadioButton rbtn = (RadioButton)findViewById(checkedId);

Toast.makeText(MainActivity.this, rbtn.getText()+"をタップしました", Toast.LENGTH_SHORT).show();
}
});

このように、処理するときにも
RadioGroupでまず判定して
そして各種ボタンが押されたときの処理を書く
今回は単純に押されたボタンをToastで表示

また、スマホの画面ではあまりやらなさそうだけど
タブレットなどの大きな画面で
ラジオボタンを横向にするなら
RadioGroupの
orientation=””
でhorizontalを設定すればいい

デフォルトでは、verticalなので縦向きになる

RSpec インストール

RSpec インストール

ドットインストールで扱う RSpec を行うため
ruby のバージョンアップ
しようとしたけど
わからないので、とりあえず ver 2.0.0 で実験

以前、ローカル開発環境構築ということで
vagrant で構築したマシンに
rbenv で ruby をインストールしたので
これを使うことにする

このとき参考にしたのが
#12 Rubyをrbenvで導入してみよう

このときのバージョンが
ruby 2.0.0p247

今回は
2.1.1p76
らしいけど
公式サイトを見ると
https://www.relishapp.com/rspec/docs/gettingstarted

Prerequisites

Ruby 1.8.7 or higher (2.0+ recommended)
となっているので、とりあえず 2.0.0 で実験

インストールそのものは
RSpec on Railsの始め方。

を参考にインストール

sudo gem install rspec

でインストール

version の確認は

rspec -v

で表示できる

Androidでチェックボックス

Androidでチェックボックス

チェックボックスを使うには
CheckBoxを使う

チェックイベントの取得には
setOnCheckedChangeListenerを使う

これを使うには、まずレイアウトファイルでチェックボックスを定義する

<CheckeBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>

次に、チェックイベントの取得
これはJavaで処理
CheckButtonに対して
setOnCheckedChangeListenerをセットすれば
ボタンイベントの取得ができるようになる

CheckBox checkbox = (CheckBox)findViewById(R.id.checkbox);

checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener(){

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){

Toast.makeText(MainActivity.this, "チェック状態は "+isChecked, Toast.LENGTH_SHORT).show();
}
});

また、チェックボックスで
チェック済みにしたいのなら
.setChecked(true)

チェックをはずすなら
.setChecked(false)
とすることで対処もできる

Toggleボタンのカスタマイズ

Toggleボタンのカスタマイズ

まずは、ToggleButtonの背景画像の用意

ToggleButtonのON/OFFの切り替えは
1つのリソースでは表現できないため
Selecter要素を使うことで状況に応じて表示するようにする

つまり、OFFの時の画像
ONの時の画像を用意する

リソースファイルは
Selecter_toggle_background.xml

ソースは

<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:drawable="@color/FlatLightAqua"/>
<item android:state_checked="false" android:drawable="@color/FlatLightPink"/>
</selector>

次に、作成した背景用のリソースを
background=””を使って実際のViewへ反映させる

<ToggleButton
android:id="@+id/tbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ Selecter_toggle_background"/>

ちなみに、Switchの場合は
ToggleButtonと違って
スイッチ部分と
スイッチ部分の裏にある背景とで
リソースが分かれる

まずは、switch_background.xml
というようにリソースファイルを用意

<selector
 xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/switch_bg_disabled_holo_dark" 
android:state_enabled="false"/>

<item android:drawable="@drawable/switch_bg_focused_holo_dark"
android:state_focused="true"/>
<item android:drawable="@drawable/switch_bg_holo_dark"/>
</selector>

次に、switch用のリソースの準備
これも別ファイルで用意
今回は、selector_switch_thumb.xml
定義するのは4つで
無効状態
有効状態
OFFの状態
Onの状態

ソースにすると



[/xml]

ここまでできたら、レイアウトファイルで
背景用リソースを
thumb属性を使ってViewへ反映させる
指定するのはリソースファイル名

<Switch
android:id="@+id/switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:thumb="selector_switch_thumb
"
android:track="@drawable/selector_switch_background"/>

となる

カスタマイズに使うリソースは
drawableリソースなら何でも使えるけど
shapeリソースや
9patchリソースでない場合、
デバイスのディスプレイサイズや解像度の違いが影響し
デザイン崩れが起こることがあるので注意

toggleボタンの使い方

toggleボタンの使い方

Androidでtoggleボタンは
ON/OFFの設定でよく使う

toggleボタンを使うには、まずレイアウトファイルで
ToggleButtonを設置する

<ToggleButtonbr>android:id="@+id/tbtn"<br clear="none"></br>
android:layout_width="wrap_content"<br clear="none"></br>
android:layout_height="wrap_content"<br clear="none"></br>
/><br clear="none"></br>




ボタンではなく、スイッチのほうを使いたいのなら


android:id=”@+id/switch”


android:layout_width=”wrap_content”


android:layout_height=”wrap_content”/>


[/xml]

わかりやすいのはSwitchのほうで
スライドさせてON/OFF切り替えになる

アイコンを付けると、toggleボタンでも使いやすくなる

レイアウトファイルに設定したら次に、
インスタンスの取得

まずは、toggleボタンの場合

final ToggleButton tb = (ToggleButton)findViewById(R.id.tbtn);

次に、Switchの場合

final Switch sw = (Switch)findViewById(R.id.switch);

ここまでできたら、次に
ON/OFFの切り替えリスナーを設定

まずは、toggleボタンの場合

tb.setOnClickListener(new checkedChangeListener(){

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
Toast.makeText(MainActivity.this,"Toggleボタンをおしたよ",Toast.LENGTH_SHORT).show();
}
});

次に、Switchの場合

sw.setOnClickListener(new onCheckedChangeedListener(){

@Override
public void onCheckedChangeed(CompoundButton buttonView, boolean isChecked){
Toast.makeText(MainActivity.this,"switch true",Toast.LENGTH_SHORT).show();
}
});

トーストで表示する文字は
getString()
でリソースから取得することもできる

ほとんどの場合、
R.string.文字列の変数
で指定する

setOnCheckedChanged()
をセットした状態で
ON/OFFを切り替えると、状況に応じて
isCheckedの値が変化する

isCheckedの値がtrueならON
falseならOFFになる

Androidでボタンに画像をセット

Androidでボタンに画像をセット

ボタンに画像をセットするなら
ImageButtonを使う

まずは、レイアウトファイルてわ設定

<ImageButton
android:id="@+id/imgBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/ic_launcher"/>

次にImageButtonのクリックイベント設定
これはJavaで書く

これほ、ImageButtonに対して
setOnClickListenerをセットする

Button ibtn = (Button)findViewById(R.id.imgBtn);
ibtn.setOnClickListener(new onClickListener(

@Override
public void onClick(View v){
Toast.makeText(MainActivity.this,"ImageButtonをクリックしました",Toast.LENGTH_SHORT).show();
}
));

ButtonとImageButtonの違いは、
アイコンボタンを作るときに違いがでる

Buttonでも
background=””

アイコン画像をセットすればアイコンボタンみたいになる
ただし
端末の大きさに合わせてボタンが伸びれば
そのぶん、画像も延びてしまう
さらに、背景に設定しているため
背景色の変更ができない

9patchを使ったり、アイコンの背景を透明にすれば対処できなくはないけど
手間がかかる

これに対してImageButtonを使えば
画像は src=””
背景は background=””
と分かれるため、管理しやすい
あと、src=””では
scaleType=””で伸縮方法の設定もできるので、
画像がボタンのサイズに伸びないようにできる

ContentProviderクラスについて

ContentProviderクラスについて

ContentProviderは、アプリにコンテンツを提供するAndroidの基本的な部分の一つ

コンテンツをカプセル化し
単一のContentProviderインターフェースをアプリに提供する

ContentProviderは、データを複数のアプリで共有するのに必須

例として、複数のアプリで使われる連絡先データは
ContentProviderに保存されなければならない

他のアプリとデータ共有しないのなら
SQLiteDatabaseで直接DB操作すればいい

ContentProviderを通じてリクエストされると
システムはURIクラスに対する権限を調べ
権限があるリクエストだけContentProviderへ渡す

ContentProviderは、
要求されたものに対して解析することができる

URIクラスを解析するのを助けるものとして
URIMatcherクラスがある

実装するべき主なメソッドとしては

onCreate()
プロバイダーの初期化

query(Uri,String[], String)
呼び出し者にデータを返す

insert(Uri,ContentValues)
ContentProviderへデータを新規追加する

update(Uri,ContentValues,String,String[])
ContentProviderにあるデータを更新する

delete(Uri,String,String[])
ContentProviderのデータを削除する

getType(Uri)
ContentProviderデータのMIMEタイプを返す

次にスレッドについて
データにアクセスするメソッドの
insert(Uri,ContentValues)
とか
update(Uri,ContentValues,String,String[])
などは、複数のスレッドから呼ばれる可能性があるため
スレッドセーフである必要がある

それ以外のスレッド
例えば、onCreate()などは
アプリのメインスレッドからのみ呼ばれるので
長時間処理を避ける必要がある

ContentResolverへのリクエストは、自動的に
適切なContentProviderInstanceへ配送されるため
サブクラスはプロセスをまたぐ呼び出しについて
詳細を気にする必要はない

API level 16で追加された項目は

インターフェース
android.content.ComponentCallbacks2を継承する

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
の追加

関連するフィーチャーは
ContentProvider.PipeDataWriter


これは、パイプにデータのストリームを書き出すインターフェース

コンストラクタは、
public ContentProvider()
これは、ContentProviderのインスタンスを返す

Android Serviceの定数

Android Serviceの定数

public static finalint START_CONTINUATION_MASK
ビットは、
onStartCommand(Intent,int,int)によって返され
killされた場合にサービスを継続する方法を説明する

説明は
START_STICKY
START_NOT_STICKY
START_REDELIVER_INTENT
START_STICKY_COMPATIBILITY
のいずれかになる

public static final int START_FLAG_REDELIVERY
このフラグは
サービスが以前に
START_REDELIVER_INTENT
を返したけど
そのIntentでstopSelf(int)を呼びだす前にkillされたので
Intentが依然配信されたものを再配信するときに
onStartCommand(Intent,int,int)の引数にセットされる

public static final int START_FLAG_RETRY
オリジナルは届かなかったか、
onStartCommand(Intent,int,int)から戻らなかったため
Intentがretryされるときに
onStartCommand(Intent,int,int)の引数にセットされる

public static final int START_NOT_STICKY
onStartCommand(Intent,int,int)から返される定数
サービスが開始されている間
つまり
onStartCommand(Intent,int,int)から戻ってきた後に
サービスのプロセスがkillされ
そこに配信するための新しい開始Intentがない場合
サービス開始状態から外し
Context.startService(Intent)
への今後の明示的な呼び出しまで再生成されなくなる

public static final int START_REDELIVER_INTENT
onStartCommand(Intent,int,int)から返される定数
サービスが開始されている間
つまり、
onStartCommand(Intent,int,int)から戻ってきた後に
サービスのプロセスがkillされた場合
サービスが再起動し、最後に配信されたIntentを
onStartCommand(Intent,int,int)を経由して再配信するためにスケジュールされる

public static final int START_STICKY
onStartCommand(Intent,int,int)から返される定数
サービスが開始されている間、
つまり
onStartCommand(Intent,int,int)から戻ってきた後に
サービスのプロセスがkillされた場合
サービスを開始状態のままにするが
配信されたIntentを保持しない

public static final int START_STICKY_COMPATIBILITY
onStartCommand(Intent,int,int)から返される定数
START_STICKYの互換バージョンになる
これは、killされた後に
onStartCommand(Intent,int,int)が呼び出されることを保証しない

Android Service関連メソッド

Android Service関連メソッド

public final Application getApplication()
このサービスを所有するアプリを返す

public abstract IBinder onBind(Intent intent)
サービスへの通信チャネルを返す
クライアントがサービスにBindできないならnullを返す

引数のintentは、Context.bindService()に与えられたこのサービスにbindするために使われるIntent

戻り値は、クライアントがサービスを呼び出すことができるIBinder

public void onConfigurationChanged(Configuration newConfig)
コンポーネントの実行中にデバイスのconfigurationが変更されると
システムにより呼び出される

Activityや他のコンポーネントとは違い
構成変更のときに再起動されないのて注意

引数のnewConfigは、新しいデバイスの設定

public void onCreate()
サービスが最初に作成されたときに、システムにより呼び出される
このメソッドの直接呼び出しはダメ

public void onDestroy()
長い間使用されず、削除されるサービスへ通知するためにシステムにより呼び出される
サービスは、この時点で保持しているすべてのリソース
つまり、スレッド、登録されたレシーバーなどをクリーンアップする必要がある

戻った後、このサービスオブジェクトへの
これ以上の呼び出しはなく、事実上死んでいることになる
このメソッドも直接呼び出しはダメ

public void onLowMemory()
システム全体のメモリが不足していると呼び出され、積極的に実行しているプロセスに倹約を求める
これが呼び出されるときの明確なポイントは定義されてないが
一般的には、サービスとkillされるのを回避したいフォアグラウンドUIをホストしているプロセスをkillする直前に
すべてのbackground processがkillされたときに呼び出される

public void onReBind(Intent intent)
前持ってすべてのクライアントが
onUnBind(Intent)で切断されたことが通知された後に
新しいクライアントがサービスに接続したときに呼び出される

onUnBind(Intent)がtrueを返すように
Overrideしたときのみ呼び出される

引数のintentは、
Context.bindServiceに与えられた
このサービスにbindするために使われたintent
その時点でIntentに含まれていた任意のExtraはここではみれない

public int onStartCommand(Intent intent, int flags, int startId)
クライアントがstartService(Intent)の呼び出しにより明示的にサービス開始するごとに
それに与えられたものと
開始要求を示す一意の整数トークンを定義され、
システムにより呼び出される

後方互換性のため、デフォルト実装では
onStart(Intent,int)を呼び出し
START_STICKY
または
START_STICKY_COMPATIBILITY
のいずれかを返す

引数のintentは、
startService(Intent)に与えられたIntent
サービスは、そのプロセスがなくなった後に再起動され
それ以前に
START_STICKY_COMPATIBILITY
以外のものを返しているなら
nullになることがある

flagsは、この開始要求に関する追加データ

0
START_FLAG_REDELIVERY
または
START_FLAG_RETRY
のいずれかになる
API Level 8,
API Level 16ではデフォルトが0
API level 9~15はSTART_FLAG_RETRYがデフォルトになる

startId
開始要求を表す一意の整数
stopSelfResult(int)と一緒に使う

戻り値は、サービスの現在の開始状態のためにシステムが使用すべきセマンティクスを示す
START_CONTINUATION_MASKビットに関連した定数のいずれかになる

public void onTaskRemoved(Intent rootIntent)
サービスが現在実行されており、ユーザーがアプリからのタスクを削除したときに呼び出される

ServiceInfo.FLAG_STOP_WITH_TASK
を設定すると、コールバックを受け取れなくなるが、代わりにサービスが停止になる

引数のrootIntentは、削除されたタスクを起動するため使われた元のrootIntent

public void onTrimMemory(int level)
OSがそのプロセスから不要なmemoryをtrimmingするのに良い時間だと判断したときに呼び出される
プロセスがbackgroundに入り
必要に応じて実行している多くの
background processを保持するのに十分なメモリがないときに発生する

引数のlevelは、trimのContext
動作しているアプリをtrimmingする量のヒントを与える

TRIM_MEMORY_COMPLETE
TRIM_MEMORY_MODERATE
TRIM_MEMORY_BACKGROUND
TRIM_MEMORY_UI_HIDDEN
TRIM_MEMORY_RUNNING_CRITICAL
TRIM_MEMORY_RUNNING_LOW
TRIM_MEMORY_RUNNING_MODERATE
のいずれかになる

public boolean onUnbind(Intent intent)
すべてのクライアントがサービスにより発行された特定のインターフェースから切り離されたときに呼び出される

デフォルト実装では、falseを返す

引数のintentは、
Context.bindServiceに与えられた、このサービスにbindするために使われたIntent
その時点でIntentに含まれていた任意のExtraは、ここではみれない

戻り値は
新しいクライアントがサービスにbindするときに
onRebind(Intent)を呼び出してほしいなら
trueを返す

public final void startForeground(int id, Notification notification)
サービスをForegroundで実行するようにする
この状態の間は、ユーザーに示されるために対応中の通知を与える

引数のidは、
NotificationManager.notify(int, Notification)ごとの
notificationのための識別子

notificationは、表示される通知

public final void stopForeground(boolean removeNotification)
より多くのメモリが必要なときにkillされていいように
Foreground状態からこのサービスを削除する

引数のremoveNotificationは、trueなら
以前のstartForeground(int,Notification)
で提供された通知を削除する

falseなら、後の呼び出しが削除
または、サービスが破棄されるまで残る

public final void stopSelf()
サービスがすでに開始されているなら停止する

public final void stopSelf(int startId)
stopSelf(int)の古いバージョンで、結果を返さない

public final boolean stopSelfResult(int startId)
startIdで開始された最新のサービスを停止する

引数のstartIdは、
onStart(Intent, int)で受信した最新の開始識別子

戻り値は、最新の開始要求とstartIdが一致し、サービスご停止されるならtrue
そうでないならfalse

protected void dump(FileDescriptior fd, PrintWriter writer, String[] args)
与えられたストリームへサービスの状態を印刷する
adb shell dumpsys activity サービス名
で実行したときに呼び出される

引数のfd は、dumpに送信されるRAWファイル記述子

writerは、状態をdumpするための
PrintWriterオブジェクト
この関数かれ戻るときに自動的にクローズされる

argsは、dump requestへの追加の引数