SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

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

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

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

  • X ポスト
  • このエントリーをはてなブックマークに追加

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のレコードの削除ですが、そこは各自で実装してください。次回はプッシュ通知を試してみたいと思います。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
MBaaSと連携するAndroidアプリを作る連載記事一覧

もっと読む

この記事の著者

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

 富山県高岡市出身で在住。ソフトウェア開発者兼ライター。株式会社イーザー関西学院大学文学部仏文科卒。第一種情報処理技術者(今で言うと、応用情報技術者。第一種→ソフ開→応用と変遷したようだ)主な著書『作ればわかる!Androidプログラミング第2版 -SDK4対応-』『VS 2010で作る Web-DB アプリ入門』『ベテランが丁寧に教えてくれるデータベースの知識と実務』『はじめてのAndroidアプリ作成 センサー活用とクラウド連携』『はじめてのAndroidアプリ作成 基本プログラミング』Web連載『VB2008で楽々Webプログラミング』『再発見!VB2005快適プログラミング』 『こうしろうのMindStroms日記』 個人的なブログはこちらです。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8217 2014/10/28 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング