Furudateのブログ

プログラミングやネットワーク系の知識・技術がメインのブログ。技術メモ帳的な感じになるかと。岩手から発信していきます。

【Android】ListFragmentとListViewの使い方

こんにちは。

今回はListViewを使ってデータを表示する方法を書きたいと思います。
タブなどを使った際に使えるListFragmentと、ListViewの両方について書きたいと思います。

ListFragmentについて

FragmentはAndroid3.0から導入された新しいクラスです。
FragmentはActivityの内部に配置可能で、タブレットなどに左右に画面を出したい時などに使います(Activityは同一画面に並べることはできない)。
基本的にはタブで画面を分ける際に使われると思います。
また、FragmentはActibityでホスト(呼び出す)必要があります。

ListFragmentはそんなFragmentをリスト表示してくれるものです。割と簡単に実装できます。
今回はタブをタッチする以外にも、ViewPagerを使ってスワイプでも切り替えられるようにしたいと思います。

以下ソースコードです。

なお、Activityを作る際に、Navigation Type をTabs + Swipe にしておいてください。

MainActivity(ListFragmentを呼び出すActivity)

protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);

	// Action barのモードをタブモードに切り替え
	final ActionBar actionBar = getActionBar();
	actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

	// FragmentPagerAdapterを継承したクラスのアダプターを作成
	mSectionsPagerAdapter = new SectionsPagerAdapter(
			getSupportFragmentManager());

	// ViewPagerにSectionPagerAdapterをセット
	mViewPager = (ViewPager) findViewById(R.id.pager);
	mViewPager.setAdapter(mSectionsPagerAdapter);

/**
 * スワイプしたときにもActionbarのタブ(NavigationItem)を常に表示させる処理
 */
mViewPager
		.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
			@Override
			public void onPageSelected(int position) {
				actionBar.setSelectedNavigationItem(position);
			}
		});

// getCountでタブの数を指定。
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
	// Actionbarにタブを追加。
	// getPageTitleでタブのタイトルを表示
	actionBar.addTab(actionBar.newTab()
			.setText(mSectionsPagerAdapter.getPageTitle(i))
			.setTabListener(this));
}
});

/**
 * タブを選択した時の処理
 */
@Override
public void onTabSelected(ActionBar.Tab tab,
		FragmentTransaction fragmentTransaction) {
	// ここで表示するフラグメントを決定する(SectionsPagerAdapter.getItemが呼び出される)
	mViewPager.setCurrentItem(tab.getPosition());
}

/**
 * タブの選択が外れた場合の処理
 */
@Override
public void onTabUnselected(ActionBar.Tab tab,
		FragmentTransaction fragmentTransaction) {
}

/**
 * タブが2度目以降に選択された場合の処理
 */
@Override
public void onTabReselected(ActionBar.Tab tab,
		FragmentTransaction fragmentTransaction) {
}

/**
 * ViewPagerの動作を作成
 */
public class SectionsPagerAdapter extends FragmentPagerAdapter {

	public SectionsPagerAdapter(FragmentManager fm) {
		super(fm);
	}

	/**
	 * 各ページに設定するFragmentを指定
	 * @params タブの位置。左から0,1,2..となる
	 */
	@Override
	public Fragment getItem(int position) {
		if (position == 0){
			FragmentAnswer fragment = new FragmentAnswer();
			return fragment;
		} else {
			FragmentTest fragment = new FragmentTest();
			return fragment;
		}
	}

	/**
	 * タブの数を決定
	 */
	@Override
	public int getCount() {
		return 2;
	}

	/**
	 * タブのタイトルを決定
	 */
	@Override
	public CharSequence getPageTitle(int position) {
		switch (position) {
		case 0:
			return getString(R.string.title_section1).toUpperCase();
		case 1:
			return getString(R.string.title_section2).toUpperCase();
		}
		return null;
	}
}

なお、デフォルトでは DummySectionFragment というFragmentのひな形(サンプル)となるような画面を生成するクラスが作成されますが、いらないので削除しています。

呼び出す側のFragment(今回の場合はFragmentAnswerとかになります)

public class FragmentAnswer extends ListFragment {
	/**
	 * ListFragmentにどのようなアイテムを入れるかを実装
	 */
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		
		// 実際のリストアイテム代入
		String[] category = {"test", "tes1", "test2", "test3"};
		ArrayAdapter<String> adapter = (new ArrayAdapter<String>(getActivity(), R.layout.row, category){
			/**
			 * GetViewをオーバーライドして背景色を交互に変える
			 */
			@Override
			public View getView(int position, View convertView, ViewGroup parent){
				View view = super.getView(position, convertView, parent);
				if (position % 2 == 0){
					view.setBackgroundColor(Color.GRAY);
				}else{
					//view.setBackgroundColor();
				}
				
				return view;
			}
		});
		
		setListAdapter(adapter);
		
		ListView lv = getListView();
		
		/**
		 * リストの項目をクリックしたときの処理(今回は違うActivityにタッチした場所ごとの値を渡して呼び出します)
		 * @params position:タッチした場所(一番上は0)
		 */
		lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id){
				Intent intent = new Intent(getActivity(), SubActivity.class);
				// Intentに値をセット
				intent.putExtra("id", position);
				startActivity(intent);
			}
		});
	}

}

Adapterでレイアウトファイルを設定していますが、今回は自作したものにしています(矢印アイコンとか表示したかったので)。
しかし、レイアウトファイルはシステム側で用意されているものもあり、以下のようにしてそちらを使ったほうが楽な場合もあります。
今回のも用意されているのをオーバーライドして作成しています。
なお、システム側で用意されているレイアウト一覧はこちらです。

ArrayAdapter<String> adapter = (new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, category)

Adapterで設定したレイアウトファイル(今回の場合はrow.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:textColor="@color/white"
    android:paddingLeft="15dp"
    android:layout_marginLeft="15dp"
/>


以上でListFragmentを使うことができます。結構楽ですね。


ListViewについて

今回はActivity(Class)内にView作成のメソッドを作成し、on create の中で呼び出すようにしました。

private void populateContentsListView(){
	ListView lv = (ListView)findViewById(R.id.list_view1);
	
	String value[] = {"test", "test2", "test3", "test4"};
	ArrayAdapter<String> adapter = (new ArrayAdapter<String>(this, R.layout.row2, value){
		/**
		 * GetViewをオーバーライドして背景色を交互に変える
		 */
		@Override
		public View getView(int position, View convertView, ViewGroup parent){
			View view = super.getView(position, convertView, parent);
			if (position % 2 == 0){
				view.setBackgroundColor(Color.WHITE);
			}else{
				view.setBackgroundColor(Color.GRAY);
			}
			
			return view;
		}
	});
	
	lv.setAdapter(adapter);
}


以上です。これでListを扱えるようになりました。
基本的にはFragmentを用いて、特定のActivityでしか使わない場合はListViewを使うと良いと思います。

また、ListViewにアイコンを付けたい時などはレイアウトファイルをカスタマイズする必要があるのですが、こちらではカスタマイズしたのを配布しています。

簡単に使えるのでおすすめです。

それでは。