読者です 読者をやめる 読者になる 読者になる

techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

FAB x Realm add x ListView Reload

Android Realm

FAB x Realm add x ListView Reload

やりたいこと

  1. Floating Action Button 押す
  2. Realm にデータ追加
  3. ListView を更新して追加したデータを表示する

Floating Action Button

説明不要と思われるが、下記がそれ。

Buttons/ Floating Action Button - Components - Google design guidelines

表示させる

Android Support Library に含まれているのでそれを使用する。

Support Library | Android Developers

こちら の通り、build.gradle に下記を追記する。

dependencies {
    ...
    compile "com.android.support:appcompat-v7:18.0.+"
}

layout に以下を追記すると Floating Action Button が表示される。

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="16dp"
    android:src="@android:drawable/ic_input_add"
    app:backgroundTint="@color/colorPrimary"/>

プッシュイベントをハンドリングする

Activity 側で以下を実装する。

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
      // 押下時の処理を記述
          addTask();

      }
    });

Realm にデータ追加

とりあえずテスト用に、押下した時間情報を登録していく。

先述の addTask() の中身を下記のように実装してみる。

  private void addTask() {
    Task myModel = new MyModel();
    Integer identifier;
    if (taskRealmResults.max("id") != null) {
      identifier = taskRealmResults.max("id").intValue() + 1;
    } else {
      identifier = 1;
    }
    task.setId(identifier);
    Date date = new Date(System.currentTimeMillis());
    task.setDate(date);
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.JAPANESE);
    Log.v("Test", simpleDateFormat.format(date));

    realm.beginTransaction();
    realm.copyToRealmOrUpdate(task);
    realm.commitTransaction();
  }

List View の更新

下記のように Realm に listner 登録しておくと、データ変更時の処理をハンドリングできる。

    private Realm realm;
    private RealmResults<MyModel> myModels;

    private RealmChangeListener realmListener = new RealmChangeListener() {
        @Override
        public void onChange() {
            // ここでは既にmyModelsの中身は変更後の内容に書き換わっている
            reloadListView();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        realm = Realm.getDefaultInstance();
        realm.addRealmChangeListener(listener);
        allPerson = realm.where(Person.class).findAll(); // Create the "live" query result
        setupViews(); // Initial setup of views
        reloadListView(); // Redraw views with data
    }

reloadListView を下記のように実装してみたところ、ボタン押下の度にリストに項目追加されていく動作を確認できた。

  private void reloadListView() {

    ArrayList<Task> taskArrayList = new ArrayList<>();

    for(int i = 0; i < taskRealmResults.size(); i++){
      Task task = new Task();

      task.setId(taskRealmResults.get(i).getId());
      task.setTitle(taskRealmResults.get(i).getTitle());
      task.setContents(taskRealmResults.get(i).getContents());
      task.setDate(taskRealmResults.get(i).getDate());

      taskArrayList.add(task);
    }

    ListView listView = (ListView)findViewById(R.id.listView1);
    taskAdapter = new TaskAdapter(MainActivity.this);
    taskAdapter.setTaskArrayList(taskArrayList);
    listView.setAdapter(taskAdapter);

    taskAdapter.notifyDataSetChanged();
  }

その他

RealmResultsArrayList に置き換えるところが冗長に感じられる。

そもそも組み方がおかしいのかもしれないし、この辺りも RealmRecyclerView を使えば解消されるのかも知れない?(まだ調べてない)