Hatena::ブログ(Diary)

iAndrolog

2010-07-08

ListActivityでスクロール位置を取得する方法

ListActivityから他のアクティビティに移動して戻ってきた場合、スクロールの位置は強制的に一番上に戻ってしまいます。

前回のスクロール位置を復元したいときは、あらかじめ取得した位置を保存→Resume時に移動、といった処理を行うことになりますが、取得する良い方法が無いためなかなか厄介です。

Activityに関連付けられたListViewクラスにもそのような関数はありませんし、スーパークラスのView.getScrollY()も必ず0が返ってくるようです。

一つの解決策として、ArrayAdapterクラスのgetViewからスクロール位置を引っ張ってくる、という方法があります。

以下、サンプルコードです。

public class MenuListAdapter extends ArrayAdapter<MenuListItem> {

	@Override
	public View getView(int position, View convertView, ViewGroup parent){

		//スクロール位置を保存する
		if (position >= MenuActivity.m_nListPosition){
			MenuActivity.m_nListPositionTop = false;
		}
		else{
			MenuActivity.m_nListPositionTop = true;
		}
		MenuActivity.m_nListPosition = position;

		//各アイテムのセット処理など
		// :
		// :
		
		return convertView;
	}
}

public class MenuActivity extends ListActivity {

	public static int m_nListPosition;
	public static boolean m_nListPositionTop;
	public static final int HEIGHT = 30;	//リスト1行分の縦幅


	@Override
	public void onResume(){
		super.onResume();

		//リスト作成処理
		// :
		// :

		MenuListAdapter adapter = new MenuListAdapter(this, m_clList);
		setListAdapter(adapter);

		//スクロール位置変更
		int nPosition;
 		if (m_nListPositionTop){
			nPosition = m_nListPosition
 		}
 		else{
 			int nList = (int)(getListView().getHeight() / HEIGHT));	//1画面のリスト数
			nPosition = m_nListPosition - nList;
 		}
		getListView().setSelection(nPosition);
	}
}

ArrayAdapter.getView関数は、スクロールによって新しいリストを表示する必要があるタイミングで呼ばれます。

(「Adapter#getViewの挙動について - hyoromoの日記」に詳しく載っています)

このときpositionにリスト番号が入りますので、現在のおおよそのスクロール位置を知ることができます。

ただしスクロール方向(上向き、下向き)に関係なく、新しく表示されたリスト番号が取得されますので、サンプルコードでは前回のposition値との比較によって、スクロール方向を把握するようになっています。

あとは、ListActivity.onResume()で保存されたスクロール位置に移動させる処理を追加します。

こちらも、スクロール方向によって描画位置を変える必要があります。

きりんきりん 2010/10/29 11:57 参考にさせていただきました!
スクロール位置の保存がどうもうまくできなくて困ってました。
感謝です。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/t_kaido/20100708/1278602028