タスクオブジェクトをボタンとして表示する
それでは、上記の仕様を実現するコードをみていきましょう。なお、本稿のサンプルコードは記事に添付していますので、ダウンロードし、併せてご覧ください。
まず、MainActivityのレイアウトファイルである「activity_main.xml」を変更します。
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ScrollView"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
各タスクはボタンとしてコードによってLinearLayout内に縦に配置していくのですが、タスクをたくさん登録すると、スマホの画面に収まらなくなります。そんなときには、スクロールバーが出れば便利なのですが、LinearLayoutはスクロールバーを表示しません。そこで、ScrollViewを使います。LinearLayoutをScrollViewで囲むことで、ボタンが1画面に収まらないときにスクロールバーが表示されます。
ScrollView―複数のButtonという単純な階層構造にしたい所ですが、ScrollViewは子コンポーネントを一つしか持つことができないため、ScrollView―LinearLayout―複数のButtonという形をとっています。
次にタスクをボタンとして、表示するコードをみていきましょう。onCreateメソッドで呼び出しているcreateButtonsメソッドがボタンを作成していきます。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// SDKの初期セットアップ(アプリで一回だけ)
NCMB.initialize(getApplication(), getString(R.string.app_key), getString(R.string.client_key));
currentUser = NCMBUser.getCurrentUser();
if (currentUser == null) {
// 未ログインのときは、
Intent intent = new Intent(MainActivity.this,LoginActivity.class);
startActivity(intent);
} else {
createButtons();
}
}
private void createButtons() {
LinearLayout LLayout = (LinearLayout) findViewById(R.id.main_layout);
LLayout.removeAllViews();
Button btn0 = new Button(this);
btn0.setText("タスクはまだ選択されていません");
btn0.setId(0);
btn0.setBackgroundColor(Color.GRAY);
btn0.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (v.getTag() == null) {
} else {
// 計測中のタスクがあるとき
finCurTask();(a)
}
}
});
Space spc = new Space(this);(1)
LLayout.addView(spc,600,10);
LLayout.addView(btn0,600,160);
getCurTask();(b)
まず、findViewById(R.id.main_layout)で、LinearLayoutオブジェクトを見つけて、removeAllViews()ですべての子コンポーネントを削除しています。onCreateメソッドが複数回呼びされても大丈夫なようにボタンを一旦、全部削除してから作成します。
btn0として「タスクはまだ選択されていません」とテキスト表示するボタンを作成します。このボタンが押された場合の処理は後述します。(1)でコンポーネント(ビュー部品)に空白をあけるためのSpaceのオブジェクトを作成し、まず配置します。縦方向に少し空白をあけてから、btn0を配置します。
getCurTaskメソッドの説明も後回しにして、タスクをボタンとして表示する部分の説明に進みましょう。
NCMBでは、データストアのクラスに対してクエリを発行して、オブジェクトを検索、取得することができます。
NCMBQuery<NCMBObject> query = NCMBQuery.getQuery("TaskClass");(2)
query.orderByDescending("updateDate");
query.findInBackground(new FindCallback<NCMBObject>() {
@Override
public void done(List<NCMBObject> result, NCMBException e){
for (int i =0 ,n = result.size(); i < n; i++ ) {
NCMBObject task = result.get(i);(3)
createButton(i,task.getObjectId(),task.getString("taskName"));
}
}
});
}
(2)では、NCMBQueryクラスのgetQueryメソッドでTaskClassから、クエリを作成しています。NCMBQueryでは、RDB同様に条件式によるレコードの抽出や並び替えが可能です。このサンプルではorderByDescending("updateDate")と更新日の降順に並べ替えしています。
findInBackgroundメソッドで非同期にオブジェクトを取得します。取得したオブジェクトはNCMBObject型のListであるresultに格納されますので、(3)で一つずつtaskオブジェクトに取り出します。そして、インデックスであるiとtask.getObjectId()で取得したオブジェクトID,task.getString("taskName")で取得したタスク名を引数にcreateButtonメソッドを呼び出します。
createButtonメソッドが各タスクをボタンとして、LinearLayoutに追加します。
private void createButton(int i,String objId,String taskName) {
LinearLayout LLayout = (LinearLayout) findViewById(R.id.main_layout);
Button btn = new Button(this);(4)
btn.setText(taskName);
btn.setTag(objId);
btn.setId(i+1);
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// 各タスクのボタンが押されたら
Button btn0 = (Button) findViewById(0);(5)
if (btn0.getTag() == null) {
// タスクが未選択のとき
// タスク名とObjIdのセット
Button btn = (Button)v;
btn0.setText(btn.getText());
btn0.setTag(btn.getTag());
btn0.setBackgroundColor(Color.RED);
getTask((String)btn.getTag());(6)
} else {
}
}
});
Space spc = new Space(this);
LLayout.addView(spc,600,10);
LLayout.addView(btn,600,160);
}
(4)でButtonオブジェクトbtnを生成して、setTextメソッドでタスク名を、setTagメソッドでオブジェクトIDを、setIdメソッドでインデックス+1をボタンのプロパティにセットします。setOnClickListenerメソッドで登録しているこのボタンのonClick時の処理の説明はちょっと後回しにします。addViewメソッドでSpaceとともにButtonを追加しています。
たとえば、TaskClassに「テスト」と「メールサーバー構築」というタスク名のレコードが登録されていると、次のようにボタンが3つ表示されました。
最初のボタンに「タスクはまだ選択されていません」と表示されているときは、まだ時間の計測を開始していません。
データストアのクラスに登録するオブジェクトのことをレコードと呼んだり、オブジェクトと呼んだりしています。NCMBのデータストアにおいてはレコード=オブジェクトと考えてください。RDBとの比較でレコードと考えた方がわかりやすいときはレコードと呼んでいます。

