ListViewの使用
値の一覧を表示したり、一覧から選択するのに使用する。
予め ScrollViewインタフェースが実装してあり、スクロールを利用して擬似的に Spinnerのような使い方もできる。
予め ScrollViewインタフェースが実装してあり、スクロールを利用して擬似的に Spinnerのような使い方もできる。
使い方
ListViewクラスと ListAdapterインターフェースの実装を組み合わせて使用する。
ちょっと面倒だけど、上手いこと使うとSpinnerよりも快適な使用感を演出してくれる。
ListViewクラスの高さをリストの1アイテム分程度に絞り、スクロールされるたびに表示されているアイテムの選択とみなし、スクロール位置を微調整してやればよい。
必要な処理はこんな感じ
ListViewクラスの高さをリストの1アイテム分程度に絞り、スクロールされるたびに表示されているアイテムの選択とみなし、スクロール位置を微調整してやればよい。
必要な処理はこんな感じ
- 1アイテムの高さを取得
- ListViewクラスの高さを設定
- スクロールの停止を検知し表示されているアイテムを選択する
- 選択したアイテムにあわせてスクロール位置を微調整する
サンプルコード
- 配列から Adapterを作成し、ListViewにセットする
ListView hoursList = (ListView) findViewById(R.id.HoursListView); Integer[] hours = new Integer[24]; for (int i = 0 ; i < 24 ; i++) hours[i] = Integer.valueOf(i); ArrayAdapter<Integer> hoursAdapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_list_item_1, hours); hoursList.setAdapter(hoursAdapter);
- 画面サイズを取得し、そのサイズを使ってリストアイテムの高さを測定
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); display.getMetrics(metrics); View tempView = hoursAdapter.getView(0, null, null); tempView.measure(metrics.widthPixels, metrics.heightPixels); int itemHeight = tempView.getMeasuredHeight();
- ListViewの高さをアイテムの高さに合わせる
LayoutParams tempLayout = hoursList.getLayoutParams(); tempLayout.height = itemHeight; hoursList.setLayoutParams(tempLayout);
- ListViewのデフォルト位置を設定し、リスナーをセットする
hoursList.setSelection(5); hoursList.setOnScrollListener(this);
- リスナーを作成。アクティビティを使っている
public class MainActivity extends Activity implements OnScrollListener {
- リスナーのメソッドを実装する
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //nothing todo }
- スクロール位置を微調整するよう小細工する
public void onScrollStateChanged(AbsListView view, int scrollState) { // TODO 自動生成されたメソッド・スタブ Log.v(TAG, "Scroll State:" + scrollState); if (scrollState == SCROLL_STATE_IDLE ) { ListView listView = (ListView)view; View firstShownChilndView = listView.getChildAt(0); int targetPos = listView.getFirstVisiblePosition(); if( itemHeight + firstShownChilndView.getTop() < itemHeight / 2) targetPos += 1; if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { listView.smoothScrollToPosition(targetPos); } else { listView.setSelection(targetPos); } } }
この例でアプリをエミュレータ上で実行すると、ホイールマウスによるスクロールが onScrollでは検知されるものの、onScrollStateChagedでは検知されず微調整されない。実機では問題ないが、少し気になる。