Realmの検索UIチュートリアル(Android編)

このチュートリアルで、Thorbenはインクリメンタルサーチ可能なユーザインタフェースを実現するために、RealmSearchViewをどのように使えば良いかを50に満たないコードで説明しています。RealmSearchViewはEditTextやRecyclerViewを拡張したものです。その実装には、RealmRecyclerViewやRealmBasedRecyclerViewAdapterを使っています。

想定作業時間: 20分


RealmSearchView は検索ボックスと検索結果の一覧を提供するライブラリです。RealmSearchAdapterを用いて特定のクラスのRealmオブジェクトに対してテキスト検索を行い、その結果を表示します。このライブラリは、高速なインクリメンタルサーチのユーザインタフェースを50行に満たないコードで実現します。

このチュートリアルではRealmSearchViewのv0.9.1を使用します。

このチュートリアルを通して、あなたは次のような検索インターフェイスを作成できるようになります。

search.xml

概要

モバイルアプリでは、ユーザーは欲しい情報へ素早くアクセスしたいと考えています。しかし多くの場合、検索機能は実装工数の都合から省略されてしまいます。今回紹介するadd-onを使うことで、Realmオブジェクトに対する検索機能を簡単に実装することができます。

とても高速なので、検索文字列を入力した瞬間に、リアルタイムに検索結果を表示することができます。

アプリケーションの作成を始めましょう!これから作成するアプリケーションでは、以下のようなBlogRealmObjectを使ってブログデータを扱います。

public class Blog extends RealmObject {

   private String title;
   private String url;
   private String content;
   private String date;
   private String image;
   private String emoji;

   public Blog() {
   }

   // getters/setters/etc

}       

記事の更新情報を受け取る

Blogオブジェクトのタイトルに対して検索を行う機能を実装していきます。

完成版のコードは、GitHubで見るkとおができます

はじめに

Android Studioを起動し新しいプロジェクトをEmpty Activityを選択して作成します。

RealmSearchViewjitpack.ioで提供されていて、Gradleの依存ライブラリとして利用可能です。依存ライブラリに追加するために、以下のコードをあなたのプロジェクトのトップディレクトリにあるbuild.gradleファイルに追加してください。

maven { url "https://jitpack.io" }

追加すると以下のようになります。

allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

次に、appモジュールのbuild.gradleファイルのdependenciesに、以下のコードを追加して下さい。

compile 'com.github.thorbenprimke:realm-searchview:0.9.1'

“Sync project with Gradle files”を実行したら準備は完了です。

統合

まず、MainActivityのレイアウトファイルを開いて、以下の内容で上書きしてください。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <co.moonmonkeylabs.realmsearchview.RealmSearchView
        android:id="@+id/search_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:rsvHint="@string/search_hint"
        />

</FrameLayout>

app:rsvHintは検索条件に対するヒントテキストです。

次に、以下のようにRealmSearchAdapterを継承したBlogSearchAdapterを作成してください。

public class BlogRecyclerViewAdapter
            extends RealmSearchAdapter<Blog, BlogRecyclerViewAdapter.ViewHolder> {

        public BlogRecyclerViewAdapter(
                Context context,
                Realm realm,
                String filterColumnName) {
            super(context, realm, filterColumnName);
        }

        public class ViewHolder extends RealmViewHolder {

            private final BlogItemView blogItemView;

            public ViewHolder(BlogItemView blogItemView) {
                super(blogItemView);
                this.blogItemView = blogItemView;
            }
        }

        @Override
        public ViewHolder onCreateRealmViewHolder(ViewGroup viewGroup, int viewType) {
            ViewHolder vh = new ViewHolder(new BlogItemView(viewGroup.getContext()));
            return vh;
        }

        @Override
        public void onBindRealmViewHolder(ViewHolder viewHolder, int position) {
            final Blog blog = realmResults.get(position);
            viewHolder.blogItemView.bind(blog);
        }

        @Override
        public ViewHolder convertViewHolder(RealmViewHolder viewHolder) {
            return ViewHolder.class.cast(viewHolder);
        }
    }

RealmSearchAdapterはRealm上のデータに対する検索とフィルタリングを行う機能を提供するベースアダプタです。

RealmSearchAdapterは、Context、Realmインスタンス、フィルタ対象のプロパティ名を受け取ります。

その他の注目すべきメソッドは以下の通りです。

  • onCreateRealmViewHolder: viewのためのviewHolderを作成します。BlogItemViewのソースコードは以下の通りです。

  • onBindRealmViewHolder: Blogインスタンスの情報をviewに渡して表示します。

public class BlogItemView extends RelativeLayout {

    @Bind(R.id.emoji)
    TextView emoji;

    @Bind(R.id.title)
    TextView title;

    @Bind(R.id.date)
    TextView date;

    @Bind(R.id.description)
    TextView description;

    public BlogItemView(Context context) {
        super(context);
        init(context);
    }

    private void init(Context context) {
        inflate(context, R.layout.blog_item_view, this);
        ButterKnife.bind(this);
    }

    public void bind(Blog blog) {
        emoji.setText(blog.getEmoji());
        title.setText(blog.getTitle());
        date.setText(blog.getDate());
        description.setText(blog.getContent());
    }
}

BlogItemViewButterKnifeBindアノテーション使用して初期化を行います。

部品の結合

後は、RealmSearchViewBlogSearchAdapterを接続すれば完成です。

onCreateonDestroyメソッドを以下のように実装してください。

```java @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search);

RealmSearchView realmSearchView = (RealmSearchView) findViewById(R.id.search_view);

realm = Realm.getInstance(this);
BlogRecyclerViewAdapter adapter = new BlogRecyclerViewAdapter(this, realm, "title");
realmSearchView.setAdapter(adapter); }

@Override protected void onDestroy() { super.onDestroy(); if (realm != null) { realm.close(); realm = null; } } ```}

ActivityのフィールドRealmインスタンス保持した上でアダプタに渡します。フィールドに保持しておくことで、Activityの終了時に呼ばれるonDestroyメソッドがrealmインスタンスをcloseできるようにしています。

上記のコードはRealm上のBlogオブジェクトをtitleでフィルタリングするように指示しています。

最後に、adapterRealmSearchViewsetAdapter()に渡されます。

実行

これで完成です。アプリケーションを起動してください。

Realmにデータを投入すると、以下のように表示されます。

search.xml

実際に動作するサンプルデータつきのプロジェクトをGitHubで参照可能です。

https://github.com/thorbenprimke/realm-searchview

About the content

This content has been published here with the express permission of the author.


Thorben Primke

Thorben is a Software Engineer at Pinterest working towards making all product pins buyable. Prior to Pinterest he worked on Android at Jelly, Facebook, and Gowalla.

4 design patterns for a RESTless mobile integration »

close