リスト表示の見た目を変えるために、LayoutInflaterを利用します。
http://developer.android.com/intl/ja/reference/android/view/LayoutInflater.html
とくになにもせずAndroidのListViewを表示したときは、単一のテキストまたはボタンなどが行になって表示されます。
色々な要素をリスト表示したいときには、たとえば、Webサイトの場合だとループの中にHTMLを書くだけで済むのですが、Androidの場合は、LayoutInflaterを利用してListViewの中に動的にxmlを差し込んで表示したりする必要があります。
また、リストをスクロールしたとき、リストの要素が再利用されるので、リスト番号が単純に上から順にインクリメントされているわけではなく、クリックでリスト番号を取得するための挙動を制御する必要がありました。
このように、Androidでのリストの扱いは、ひとくせある感じになっています。
目的を実現するにあたって、以下の資料を参考にしました。
androidでRSSを取得して一覧表示 - m_shige1979のささやかな抵抗と欲望の日々
http://m-shige1979.hatenablog.com/entry/2015/07/15/080000
Adapter#getViewの挙動について - hyoromoのブログ
http://hyoromo.hatenablog.com/entry/20090912/1252777077
Android -ListView(イベント処理)- <MitoRoid>
http://mitoroid.com/category/android/android_listview3.php
LayoutInflater - Androyer in Japan
https://sites.google.com/site/androyerjapan/home/layoutinflater
ListView で onItemClick() と onItemLongClick() を両立 - Unmotivated
http://blog.lciel.jp/blog/2013/11/22/onitemclick-vs-onitemlongclick/
以下、コードの解説です。
MainActivity.java
リストの要素を作ります。ArrayAdapterを継承したrowAdapaterをリストビューに渡しています。
クリック・長押しされたときにトーストを表示するようにします。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package monst.post.nine.listview1; | |
import android.support.v7.app.ActionBarActivity; | |
import android.os.Bundle; | |
import android.view.Menu; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.widget.AdapterView; | |
import android.widget.ListView; | |
import android.widget.Toast; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class MainActivity extends ActionBarActivity { | |
private ListView listview; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
// 表示用のリストを用意 | |
List<RowDetail> objects = new ArrayList<RowDetail>(); | |
for (int i = 0; i < 100; i++) { | |
RowDetail item = new RowDetail(); | |
StringBuilder title = new StringBuilder(); | |
title.append("テスト"); | |
title.append(i); | |
String title_message = new String(title); | |
StringBuilder detail = new StringBuilder(); | |
detail.append(title_message); | |
detail.append("の詳細データです。"); | |
String detail_message = new String(detail); | |
item.setTitle(title_message); | |
item.setDetail(detail_message); | |
// リストにアイテムを追加 | |
objects.add(item); | |
} | |
// リストビューへ紐付け | |
listview = (ListView)findViewById(R.id.listView); | |
// ArrayAdapterを設定 | |
RowDetailAdapter rowAdapater = new RowDetailAdapter(this, 0, objects); | |
// リストビューへリストを登録 | |
listview.setAdapter(rowAdapater); | |
// リストビューがクリックされたときのコールバックリスナーを登録 | |
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { | |
// リストのアイテムをクリックした時の挙動 | |
@Override | |
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | |
// リストビューの項目を取得 | |
ListView listview = (ListView) parent; | |
RowDetail item = (RowDetail) listview.getItemAtPosition(position); | |
String text = "クリックしました:" + item.getTitle() + ":" + item.getDetail(); | |
// トースト表示 | |
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
// リストビューの項目が長押しされたときのコールバックリスナーを登録 | |
listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { | |
@Override | |
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { | |
// リストビューの項目を取得 | |
ListView listview = (ListView) parent; | |
RowDetail item = (RowDetail) listview.getItemAtPosition(position); | |
String text = "長押ししました:" + item.getTitle() + ":" + item.getDetail(); | |
// トースト表示 | |
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show(); | |
// onItemClickを実行しない | |
return true; | |
} | |
}); | |
} | |
} |
RowDetail.java
リストの要素を保存する際に使用するクラスです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package monst.post.nine.listview1; | |
public class RowDetail { | |
private String title; | |
private String detail; | |
public void setTitle(String title){ | |
this.title = title; | |
} | |
public String getTitle(){ | |
return this.title; | |
} | |
public void setDetail(String detail){ | |
this.detail = detail; | |
} | |
public String getDetail(){ | |
return this.detail; | |
} | |
} |
RowDetailAdapter.java
リストビュー用のアダプターです。
リストをスクロールして、新しい行が表示されるタイミングでgetViewが実行されます。
レイアウトが初めて作成される場合のみLayoutInflaterを実行します。それ以外は、表示されなくなったViewが引数に渡されてくるので再利用します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package monst.post.nine.listview1; | |
import android.content.Context; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.ArrayAdapter; | |
import android.widget.TextView; | |
import java.util.List; | |
public class RowDetailAdapter extends ArrayAdapter<RowDetail> { | |
private LayoutInflater layoutinflater; | |
// コンストラクタ | |
public RowDetailAdapter(Context context, int textViewResourceId, List<RowDetail> objects){ | |
super(context, textViewResourceId, objects); | |
// xmlで定義したレイアウトを取得 | |
layoutinflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); | |
} | |
@Override | |
public View getView(int position, View convertView, ViewGroup parent) { | |
// 指定行のデータを取得 | |
RowDetail detail = (RowDetail)getItem(position); | |
// レイアウトが初めて作成される場合のみ作成 | |
if(null == convertView){ | |
convertView = layoutinflater.inflate(R.layout.row, null); | |
} | |
// 行のデータを項目へ設定 | |
TextView text1 = (TextView)convertView.findViewById(R.id.textView); | |
text1.setText(detail.getTitle()); | |
TextView text2 = (TextView)convertView.findViewById(R.id.textView2); | |
text2.setText(detail.getDetail()); | |
// 返却 | |
return convertView; | |
} | |
} |
activity_main.xml
ListViewを表示します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" | |
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" | |
android:paddingRight="@dimen/activity_horizontal_margin" | |
android:paddingTop="@dimen/activity_vertical_margin" | |
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> | |
<ListView | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:id="@+id/listView" | |
android:layout_alignParentTop="true" | |
android:layout_alignParentLeft="true" | |
android:layout_alignParentStart="true" /> | |
</RelativeLayout> |
row.xml
ListViewの中身になります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:orientation="vertical" | |
android:layout_width="wrap_content" | |
android:layout_height="50dp" | |
android:weightSum="1"> | |
<TextView | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:textAppearance="?android:attr/textAppearanceLarge" | |
android:text="Large Text" | |
android:id="@+id/textView" /> | |
<TextView | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:textAppearance="?android:attr/textAppearanceMedium" | |
android:text="Medium Text" | |
android:id="@+id/textView2" | |
android:layout_weight="0.08" /> | |
</LinearLayout> |