かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Android WearのWearableListViewの最小の使い方

ぐぐっても、あんまりWearableListViewの使い方が出てこなくて難儀しました。NotificationsのサンプルにWearableListViewの使い方はありましたが、色々余計な処理が入ってたので、備忘録として、最小限の使い方をメモっておきます。

プロジェクトの作成とWearableListViewの追加

Android StudioでAndroid Wearのプロジェクトを作成して、activity_my.xmlをWearableListViewがあるだけの状態にします。

<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WearableListView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
</android.support.wearable.view.WearableListView>

Adapterの作成

WearableListViewもListViewと同様にAdapterを使って要素の管理をします。ふつうのとちょっと使い方が違って、WearableListView.Adapterを継承して作ります。今回はMyActivityの内部クラスとして実装しました。

class Adapter extends WearableListView.Adapter {
    private Context context;
    private LayoutInflater inflater;
    Adapter(Context context) {
        this.context = context;
        this.inflater = LayoutInflater.from(this.context);
    }
    @Override
    public WearableListView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        return new WearableListView.ViewHolder(
                this.inflater.inflate(R.layout.list_view_item, viewGroup, false)
        );
    }
    @Override
    public void onBindViewHolder(WearableListView.ViewHolder viewHolder, int i) {
        Log.d("Adapter", "index: " + i);
        TextView tv = (TextView) viewHolder.itemView.findViewById(R.id.textView);
        tv.setText("index: " + i);
    }
    @Override
    public int getItemCount() {
        return 20;
    }
}

getItemCountで要素数を返し、onCreateViewHolderで表示する要素のViewを作成します。そしてonBindViewHolderでViewとデータを結びつけます。layoutファイルから、Viewを作る場合は、上記コードのようにContextからLayoutInflaterを作っておきましょう。因みにlist_view_item.xmlは以下のようになってます。

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="New Text"
        android:id="@+id/textView"/>
</FrameLayout>

ClickListenerの実装

これ地味に必須です。これをしないと、WearableListViewの上のほうの余白タップしたらアプリが落ちてました。とりあえず、WearableListView.ClickListenerを実装したクラスを用意します。ここでは、Activityに直接実装しました。onClickが現在

public class MyActivity extends Activity implements WearableListView.ClickListener {

    // OnCreateの定義

    @Override
    public void onClick(WearableListView.ViewHolder viewHolder) {
        TextView v = (TextView) viewHolder.itemView.findViewById(R.id.textView);
        Log.d("MyActivity", "onClick " + v.getText());
    }

    @Override
    public void onTopEmptyRegionClick() {
        Log.d("MyActivity", "onTopEmptyRegionClick");
    }

    // Adapterの定義
}

最後に、ActivityのOnCreateでClickListnerとAdapterの設定をします。

public class MyActivity extends Activity implements WearableListView.ClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_my);
        WearableListView listView = (WearableListView) this.findViewById(R.id.list_view);
        listView.setAdapter(new Adapter(this));
        listView.setClickListener(this);
    }

     // その他の定義
}

コード全体

コード全体を載せておきます。

MyActivity.java

public class MyActivity extends Activity implements WearableListView.ClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_my);
        WearableListView listView = (WearableListView) this.findViewById(R.id.list_view);
        listView.setAdapter(new Adapter(this));
        listView.setClickListener(this);
    }



    @Override
    public void onClick(WearableListView.ViewHolder viewHolder) {
        TextView v = (TextView) viewHolder.itemView.findViewById(R.id.textView);
        Log.d("MyActivity", "onClick " + v.getText());
    }

    @Override
    public void onTopEmptyRegionClick() {
        Log.d("MyActivity", "onTopEmptyRegionClick");
    }

    class Adapter extends WearableListView.Adapter {

        private Context context;
        private LayoutInflater inflater;

        Adapter(Context context) {
            this.context = context;
            this.inflater = LayoutInflater.from(this.context);
        }

        @Override
        public WearableListView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            return new WearableListView.ViewHolder(
                    this.inflater.inflate(R.layout.list_view_item, viewGroup, false)
            );
        }

        @Override
        public void onBindViewHolder(WearableListView.ViewHolder viewHolder, int i) {
            Log.d("Adapter", "index: " + i);
            TextView tv = (TextView) viewHolder.itemView.findViewById(R.id.textView);
            tv.setText("index: " + i);
        }

        @Override
        public int getItemCount() {
            return 20;
        }
    }
}

activity_my.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WearableListView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
</android.support.wearable.view.WearableListView>

list_view_item.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="New Text"
        android:id="@+id/textView"/>
</FrameLayout>