DialogFragmentの作成

DialogFragmentの作成

DialogFragmentクラスを使ってダイアログを作成するには
FragmentActivityのサブクラスを作成する

まず、Javaで、FragmentActivityクラスのサブクラスを作成

onCreate()の中で
MyDialogFragmentクラスの生成、表示を実装

extends FragmentActivity

で継承しておく

次に、onCreate()の追加部分

//DialogFragment表示
FragmentManager manager = getSupportFragmentManager();

MyDialogFragment dialog = (MyDialogFragment)manager.findFragmentByTag("tag");

if(dialog == null){

dialog = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("message","Message");

dialog.setArguments(args);
dialog.show(manager, "tag");
}

次に、DialogFragmentのサブクラス作成

onCreateDialog()へダイアログの生成

onClick()へ
ok キャンセルボタンを押したときの処理を実装

このクラスでは

extends DialogFragment implements DialogInterface.OnClickListener

で継承しておく

まずは、onCreateDialog()の実装

@Override
public void onCreateDialog(Bundle savedInstanceState){

//値の取得
String message = getArguments().getString("message");

return new AlertDialog.Builder(getActivity()).

//タイトル設定
setTitle("Title")

//メッセージ設定
.setMessage(message)

//okボタンの設定
.setPositiveButton("ok",this)

//cancelボタンの設定
.setNegativeButton("cancel",this)

.create();
}

そして、ボタンクリックしたときの設定
switchで分岐させれるので、okとcancelの処理を
onClick()の中へかける

@Override
public void onClick(DialogInstance dialog, int which){

switch(which){

//okボタンクリックの場合
case AlertDialog.BUTTON_POSITIVE:
Toast.makeText(getActivity(), "ok", Toast.LENGTH_SHORT).show();
break;

//cancelボタンクリックの場合
case AlertDialog.BUTTON_NEGATIVE:
Toast.makeText(getActivity(), "cancel",Toast.LENGTH_SHORT).show();
break;
}
}

FragmentDialogに対して
setArguments()を使って値を渡しているのは
コンストラクタで値を渡すと
ダイアログが生成されるタイミングで値が破棄されることがあるから

Fragmentの作成

Fragmentの作成

Fragmentを使った画面の作成は
FragmentActivityのサブクラスを作成してから
Fragmentの生成、追加をする

Fragmentは、Activityへ配置する部品で
複数のFragmentの配置ができる

Fragmentは自分自身のライフサイクルを持つため
イベント処理、Activityの実行中でも追加、削除が可能

Fragmentのライフサイクルは
Activityのライフサイクルと連動しているので
Activityが休止状態になると
Fragmentも休止状態になる

また、Activityが破棄されるとFragmentも破棄される

まずは、FragmentActivityのサブクラスの作成

public class Fragment extends FragmentActivity implements onClickListener{

}

次に、FragmentのレイアウトファイルをXMLで作成

<LinearLayout
 xmlns:android="http://schemes.android.com/apk/res/android"

android:id="@+id/myfragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>

次に、JavaでFragmentのためのサブクラスを作成する
これには、レイアウトファイルをロードして生成する

extends Fragment

でFragmentを使えるようにする

今回は、動的にViewを追加する

@Override
public View onCreateView(LayoutInflater inflater , ViewGroup container, Bundle savedInstanceState){

return inflater.Inflate(R.layout.fragment, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState){

super.onViewCreate(view, savedInstanceState);

TextView text = (TextView)findViewById(R.id.text);
text.setGravity(Gravity.CENTER);
text.setText(getArguments().getString(“value”));
}

[/java]

次に、Fragmentを動的に追加する
onClick()をOverrideして
追加ボタンを押したタイミングで
Fragmentクラスを追加、更新する

@Override
public void onClick(View v){

FragmentManager manager = getSupportFragmentManager();
Fragment fragment = manager.findFragmentById(R.id.parent);

if(R.id.btn_add_code == v.getId() || R.id.btn_add_xml == v.getId()){

if(fragment == null){

FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.parent, getMyFragment(v.getId(), true), "MyFragment");

transaction.commit();

}else{
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.parent, getMyFragment(v.getId(), false));
transaction.commit();

}
}else if(R.id.btn_remove == v.getId() && fragment. != null){
FragmentTransaction transaction = manager.beginTransaction();
transaction.remove(fragment);
transaction.commit();
}
}

Fragmentの追加、更新には
FragmentManagerクラスの
beginTransaction()を使うことで
トランザクションを開始する

そして、次に追加、更新、削除した後に
commit()で、トランザクションをコミットする

FragmentManagerクラスの
findFragmentById()で
生成済みのFragmentが取得できないのなら
add()で、Fragmentを追加すればいい

Fragmentが生成済みなら
replace()でFragmentを更新できる

ActivityとServiceの連携

ActivityとServiceの連携

Activityと
Android Interface Definition Language
(AIDL)
を使ったサービスで連携できる

実装するには、まずAIDLインターフェースを定義する

srcフォルダの直下へ
拡張子 .aidlファイル作成

ソースは

package net.developapp.activityservice;

interface ActivityService{
int addString(String value);
String getString();
}

次に、サービス作成

ここではonBind()の実装
.Stubインターフェースの実装をする

@Override
public void onBind(Intent arg0){
return mBinder;
}

//AIDL Binder実装
private ActivityService.Stub Binder = new ActivityService.Stub(){

@Override
public int addString(String value) throws RemoteException{
mStringList.add(value);
return mStringList.size();
}

@Override
public String[] getString() throws RemoteException{

return mStringList.toArray(new String[mStringList.size()]);
}

};
[/java]

そして、Activityの実装
ここでは
ServiceConnectionの実装
Serviceのbind/unbindを実装をする

まず

extends ListActivity

でListActivityを使えるようにする

private ActivityService mService;

//メンバ変数宣言
private savedConnection

//ServiceConnection実装 mServiceConnection = new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder ibinder){

//ActivityServiceのインターフェース取得
mService = ActivityService.Stub.asInterface(ibinder);

//一覧内容更新
reloadList();
}

public void onServiceDisconnected(ComponentName name){
mService = null;
}
};

次に、onCreate()へ追記
ボタンを押したときの処理をする

findViewById(R.id.buttonadd).setOnClickListener(
new OnClickListener(){

@Override
public void onClick(View v){

EditText editString = (EditText)findViewById(R.id.editText);
if(mService != null){
try{
mService.addString(editText.getText().toString());
reloadList();

}catch(RemoteException e){
e.printStackTrace();
}
}

}
}

);

//ServiceのBind
Intent service = new Intent(this, ServiceActivity.class);
bindService(service, mServiceConnection, BIND_AUTO_CREATE);

次に、onDestroy()の実装

protected void onDestroy(){
super.onDestroy();

//Bind解除
unbindService(mServiceConnection);
}

そして、ユーザー関数reloadList()の実装

private void reloadList(){
try{
//ActivityServiceから文字列のリスト取得
String[] list = mService.getString();

//文字列のリストをListViewへ設定
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R..layout.sample_list_item_1, list);
setListAdapter(adapter);

}catch(RemoteException e){
e.printStackTrace();
}
}

Android Interface Definition Language 通称
AIDLの使いどころは
別アプリから共通処理としてServiceを呼び出したいとき

また、サーバーみたいに同時に複数の呼び出しがあるので
AIDLインターフェースは
完全にスレッドセーフで実装すること