かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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>