CodeZine(コードジン)

特集ページ一覧

MBaaSのクエリと集計処理を実装する

MBaaSと連携するAndroidアプリを作る 第5回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2014/10/28 14:00
目次

ListViewで表示する

 ここからは集計結果をListViewに追加していく処理に進んでいきます。getTaskNameメソッドは引数として渡されたtaskIdを使い、taskオブジェクトを取得して、そこからtaskNameを取得、集計した時間(sumTime)とともにaddToListviewメソッドに引数として渡して、呼び出します(1)

リスト15 getTaskNameメソッド以降
private void getTaskName(String taskId,final int sumTime) {
    NCMBQuery<NCMBObject> query = NCMBQuery.getQuery("TaskClass");
    query.getInBackground(taskId, new GetCallback<NCMBObject>() {
        @Override
        public void done(NCMBObject task, NCMBException e) {
            if (e == null) {
                // 成功
                addToListview(task.getString("taskName"),sumTime);(1)
            } else {
                // エラー
            }
        }
    });
}
private void addToListview(String taskName,int sumTime) {
    int hour = sumTime / 60;
    int min = sumTime % 60;
    dataList.add(new SumLog(taskName,String.format("%4d",hour)+ "時間" + String.format("%02d",min)+"分"));(2)
    adapter.notifyDataSetChanged();(3)
}

 addToListviewメソッドはそのタスク名と集計した時間をListViewへ追加します。

 以下は、ListViewに集計結果を追加した画像です。

集計結果をListViewに表示
集計結果をListViewに表示

 これだけのことなのですが、このあとまだたくさんコードが出てきます。ListViewにタスク名と集計した時間を2列表示したいので、ListViewをカスタマイズしているからです。

 本連載のテーマはMBaaSであるNCMBとの連携ですので、ListViewのカスタマイズについてはなるべくかいつまんで説明します。

 addToListviewメソッドのなかで、SumLogクラスのオブジェクトをaddしているdataListはSumActivityの先頭で宣言しているSumLog型のListです(2)。このdataListがListViewの表示の元になります。

 SumLogクラスはtaskNameとsumTimeプロパティを持ちます。

リスト16 SumLog.java
package jp.co.easier.stamptime;

public class SumLog {
      String taskName;
      String sumTime;

      public SumLog(String taskName, String sumTime){
        this.taskName = taskName;
        this.sumTime = sumTime;
      }

      public String getTaskName(){
        return taskName;
      }

      public String getSumTime(){
        return sumTime;
      }
}

 次に、adapterオブジェクトのnotifyDataSetChangedメソッドを呼び出していますが(3)、 adapterはSumLogAdapterクラスのオブジェクトです。

リスト17 SumLogAdapterクラス
private class SumLogAdapter extends BaseAdapter {

        @Override
        public int getCount() {(1)
          return dataList.size();
        }

        @Override
        public Object getItem(int position) {(2)
            return dataList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView((3)
            int position,
            View convertView,
            ViewGroup parent) {

            TextView textView1;
            TextView textView2;
            View v = convertView;

            if(v==null){
                LayoutInflater inflater =
                (LayoutInflater)
                getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = inflater.inflate(R.layout.row,null);(4)
            }
            SumLog sumLog = (SumLog)getItem(position);(5)
            if(sumLog != null){
            textView1 = (TextView) v.findViewById(R.id.textView1);
            textView2 = (TextView) v.findViewById(R.id.textView2);

            textView1.setText(sumLog.taskName);
            textView2.setText(sumLog.sumTime);
            }
        return v;
        }

    }

 SumLogAdapterクラスはSumActivityクラスのインナークラスであり、ListViewの基本的なアダプタであるBaseAdapterを継承しています。リスト8のSumActivityクラスのonCreateメソッドでlistView.setAdapter(adapter)として、listViewにこのadapterをセットしています(a)

[再掲]リスト8 SumActivity.java onCreateメソッドまで(抜粋)
public class SumActivity extends Activity {
    private TextView mTextFrom;
    private TextView mTextTo;
    private RadioGroup mRgSum;
    private List<SumLog> dataList = new ArrayList<SumLog>();
    private SumLogAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO 自動生成されたメソッド・スタブ
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sum);(1)

        mTextFrom = (TextView)findViewById(R.id.textViewFrom);
        mTextTo = (TextView) findViewById(R.id.textViewTo);
        mRgSum = (RadioGroup) findViewById(R.id.rgSum);
        ListView listView = (ListView) findViewById(R.id.listView1);
        adapter = new SumLogAdapter();
        listView.setAdapter(adapter);(a)

        Calendar calendar = Calendar.getInstance();(2)
        final int year = calendar.get(Calendar.YEAR);
        final int month = calendar.get(Calendar.MONTH);
        final int day = calendar.get(Calendar.DAY_OF_MONTH);

        // 開始日付を選択
        Button btnFrom = (Button) findViewById(R.id.buttonFrom);
        btnFrom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // DatePickerDialogを表示
                DatePickerDialog datePickerDialog = new DatePickerDialog(
                    SumActivity.this,
                    new DatePickerDialog.OnDateSetListener() {
                        @Override
                        public void onDateSet(DatePicker picker, int year, int month, int day) {
                            mTextFrom.setText(String.format("%04d",year) + "-" + (3)
                                    String.format("%02d",month + 1) + "-" +
                                    String.format("%02d",day));
                        }
                    },
                    year,
                    month,
                    day);
                datePickerDialog.show();

            }
        });

 SumLogAdapterクラスの処理を読んでいくと、ListViewへのdataListからの表示の仕組みがわかります。

 まず、SumLogAdapterクラスはSumActivityクラスのインナークラスなので、getCountメソッド(1)やgetItemメソッド(2)でdataListに直接アクセスできます。

 ListViewの1行の見た目を作っているのが、getViewメソッドです(3)。getViewメソッドではinflater.inflateメソッドでR.layout.rowをインフレートします。inflateは訳すると「膨らます」という意味です。アクティビティのonCreateメソッドでよく使うsetContentView(R.layout.レイアウトファイル名)と同様の効果があります。

 R.layout.rowはres/layoutに作成したrow.xmlです。

リスト18 row.xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <TextView
        android:textSize="20sp"
        android:id="@+id/textView1"
        android:layout_height="wrap_content"
        android:layout_width="240dp"/>(1)
    <TextView
        android:textSize="20sp"
        android:id="@+id/textView2"
        android:gravity="right"(2)
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>
</LinearLayout>

 row.xmlがListViewの1行のレイアウトになります。一つめのTextViewにはlayout_width="240dp"を指定しています(1)。これがtaskNameを表示する幅になります。

 集計した時間を表示するTextViewは、gravity="right"で右寄せしています(2)

 リスト17に戻りましょう。(SumLog)getItem(position)でdataListのSumLogオブジェクトを一つ取得することができます(5)。そこから、どちらも文字列であるtaskNameとsumTimeをTextViewにセットしています。

最後に

 さて、今回はLogClassからレコードを抽出してタスクごとに費やした時間を集計する処理を作ってみました。Key-Value形式のレコードをキーブレイク処理で集計してみました。NCMBに集計クエリや更新クエリがあったら便利だなという感じはしましたが、それでも短いコードで集計ができました。

 タスクタイマをアプリとして考えると、あと必要な機能は、もう使わなくなった古いタスク名の削除とそのTaskを関連オブジェクトとして持つLogClassのレコードの削除ですが、そこは各自で実装してください。次回はプッシュ通知を試してみたいと思います。



  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:MBaaSと連携するAndroidアプリを作る

著者プロフィール

  • 金宏 和實(カネヒロ カズミ)

    &nbsp;富山県高岡市出身で在住。ソフトウェア開発者兼ライター。 株式会社イーザー 関西学院大学文学部仏文科卒。第一種情報処理技術者(今で言うと、応用情報技術者。第一種&rarr;ソフ開&rarr;応用と変遷したようだ) 主な著書 『作ればわかる!Androidプログラミング第2版 -SD...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5