アンドロイドでリスト表示を使うケースはたくさんあります。例えば、サムネイルの風景写真と場所の名前のリスト、タップしてその詳細を説明するアプリは多いですね。これらはListViewとBaseAdapterを使うと簡単にできます。
2021.2.1
ListView
画像とテキストのListViewを作りましたが
アイテムのクリックと画面遷移の追加変更を考えてみます。
![[Android] ListView リストをタップして画面遷移させてみる 1x1.trans - [Android] ListView リストをタップして画面遷移させてみる](https://akira-watson.com/wp-content/themes/simplicity2/images/1x1.trans.gif)
画像とテキストのListViewの作成
画像を res/drawable 以下に置きますが、ここに置ける画像には限界があり、メモリを圧迫させない工夫が必要になります。
ここでは簡単な例として 540×300 pixel 程度の画像をリストと、タップして画面遷移した先でも同じ画像を使っています。
 
本来ならばリスト表示ではサムネイル化してもっと小さい画像を使った方がいいでしょう。タップして画面遷移した先では別のサイズの大きな画像をassetsから呼び出した方が画像がきれいになります。
 
これについてはdrawable VS assetsを参照ください。
 
![[Android] ListView リストをタップして画面遷移させてみる 1x1.trans - [Android] ListView リストをタップして画面遷移させてみる](https://akira-watson.com/wp-content/themes/simplicity2/images/1x1.trans.gif)
BaseAdapterで画像とテキストをリスト表示 を元に画像をdrawableから読み出してリスト表示させるところは、
 
MainActivity.java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | ... public class MainActivity extends AppCompatActivity {     private static final String[] scenes = {             "Ventnor",             "Wroxall",             "Whitewell",             "Ryde",             "StLawrence",             "Lake",             "Sandown",             "Shanklin"     };     // ちょっと冗長的ですが分かり易くするために     private static final int[] photos = {             R.drawable.ventnor,             R.drawable.wroxall,             R.drawable.whitewell,             R.drawable.ryde,             R.drawable.stlawrence,             R.drawable.lake,             R.drawable.sandown,             R.drawable.shanklin     };     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         // ListViewのインスタンスを生成         ListView listView = findViewById(R.id.list_view);         // BaseAdapter を継承したadapterのインスタンスを生成         // レイアウトファイル list.xml を activity_main.xml に         // inflate するためにadapterに引数として渡す         BaseAdapter adapter = new ListViewAdapter(this.getApplicationContext(),                 R.layout.list, scenes, photos);         // ListViewにadapterをセット         listView.setAdapter(adapter);     } } | 
 
BaseAdapterを継承したadapter class
ListViewAdapter.java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | ... public class ListViewAdapter extends BaseAdapter {     static class ViewHolder {         TextView textView;         ImageView imageView;     }     private LayoutInflater inflater;     private int itemLayoutId;     private String[] titles;     private int[] ids;     ListViewAdapter(Context context, int itemLayoutId,                            String[] scenes, int[] photos) {         super();         this.inflater = (LayoutInflater)                 context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);         this.itemLayoutId = itemLayoutId;         this.titles = scenes;         this.ids = photos;     }     @Override     public View getView(int position, View convertView, ViewGroup parent) {         ViewHolder holder;         // 最初だけ View を inflate して、それを再利用する         if (convertView == null) {             // activity_main.xml に list.xml を inflate して convertView とする             convertView = inflater.inflate(itemLayoutId, parent, false);             // ViewHolder を生成             holder = new ViewHolder();             holder.textView = convertView.findViewById(R.id.textView);             holder.imageView = convertView.findViewById(R.id.imageView);             convertView.setTag(holder);         }         // holder を使って再利用         else {             holder = (ViewHolder) convertView.getTag();         }         // holder の imageView にセット         holder.imageView.setImageResource(ids[position]);         // 現在の position にあるファイル名リストを holder の textView にセット         holder.textView.setText(titles[position]);         return convertView;     }     @Override     public int getCount() {         // texts 配列の要素数         return titles.length;     }     @Override     public Object getItem(int position) {         return null;     }     @Override     public long getItemId(int position) {         return 0;     } } | 
アイテムをクリックした時の挙動をコーディング
各要素がタップされ、その画像が一面表示される挙動を考えてみます
- タップされた時に、その要素の position を取得
- 遷移先の SubActivity.java にタップされた情報を渡し遷移する
- SubActivity からその position にある画像とテキストを表示
タップされた事を認識するために、リスナーを設定します。
implements OnItemClickListener
の設定と onCreate() に
listView.setOnItemClickListener(this);
を設定します
 
MainActivity.java
| 1 2 3 4 5 6 7 8 | public class MainActivity extends Activity implements OnItemClickListener{ 	... 	protected void onCreate(Bundle savedInstanceState) { 		... 		listView.setOnItemClickListener(this); 	} 	... | 
 
itemがタップされ時に onItemClick() が呼ばれ、itemの position から配列のindexを取得して putExtra() で intent にセットします。そして遷移先の Activity に渡す。
 
MainActivity.java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | ...      @Override     public void onItemClick(AdapterView<?> parent, View v, int position, long id) {         Intent intent = new Intent(this.getApplicationContext(), SubActivity.class);         // clickされたpositionのtextとphotoのID         String selectedText = scenes[position];         int selectedPhoto = photos[position];         // インテントにセット         intent.putExtra("Text", selectedText);         intent.putExtra("Photo", selectedPhoto);         // Activity をスイッチする         startActivity(intent);     } | 
 
SubActivity.java にて getStringExtra() から
配列のindexを取り出し
画面に表示します
 
SubActivity.java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | ... public class SubActivity extends AppCompatActivity {     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_sub);         Intent intent = getIntent();         String selectedText = intent.getStringExtra("Text");         int selectedPhoto = intent.getIntExtra("Photo", 0);         TextView textView = findViewById(R.id.selected_text);         textView.setText(selectedText);         ImageView  imageView = findViewById(R.id.selected_photo);         imageView.setImageResource(selectedPhoto);     } } | 
サンプルコード
まとめてみましょう。
新規に作成するファイル、取り込む画像などが多いのでプロジェクトとしてはこのような配置になります。
![[Android] ListView リストをタップして画面遷移させてみる 1x1.trans - [Android] ListView リストをタップして画面遷移させてみる](https://akira-watson.com/wp-content/themes/simplicity2/images/1x1.trans.gif)
MainActivity.java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | //package com.example.testlistviewitemclick; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ListView; public class MainActivity extends AppCompatActivity         implements AdapterView.OnItemClickListener {     private static final String[] scenes = {             "Ventnor",             "Wroxall",             "Whitewell",             "Ryde",             "StLawrence",             "Lake",             "Sandown",             "Shanklin"     };     // ちょっと冗長的ですが分かり易くするために     private static final int[] photos = {             R.drawable.ventnor,             R.drawable.wroxall,             R.drawable.whitewell,             R.drawable.ryde,             R.drawable.stlawrence,             R.drawable.lake,             R.drawable.sandown,             R.drawable.shanklin     };     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         // ListViewのインスタンスを生成         ListView listView = findViewById(R.id.list_view);         // BaseAdapter を継承したadapterのインスタンスを生成         // レイアウトファイル list.xml を activity_main.xml に         // inflate するためにadapterに引数として渡す         BaseAdapter adapter = new ListViewAdapter(this.getApplicationContext(),                 R.layout.list, scenes, photos);         // ListViewにadapterをセット         listView.setAdapter(adapter);         // クリックリスナーをセット         listView.setOnItemClickListener(this);     }     @Override     public void onItemClick(AdapterView<?> parent, View v,                             int position, long id) {         Intent intent = new Intent(                 this.getApplicationContext(), SubActivity.class);         // clickされたpositionのtextとphotoのID         String selectedText = scenes[position];         int selectedPhoto = photos[position];         // インテントにセット         intent.putExtra("Text", selectedText);         intent.putExtra("Photo", selectedPhoto);         // SubActivityへ遷移         startActivity(intent);     } } | 
 
ListViewAdapter.java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | //package com.example.testlistviewitemclick; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class ListViewAdapter extends BaseAdapter {     static class ViewHolder {         TextView textView;         ImageView imageView;     }     private final LayoutInflater inflater;     private final int itemLayoutId;     private final String[] titles;     private final int[] ids;     ListViewAdapter(Context context, int itemLayoutId,                     String[] scenes, int[] photos) {         super();         this.inflater = (LayoutInflater)                 context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);         this.itemLayoutId = itemLayoutId;         this.titles = scenes;         this.ids = photos;     }     @Override     public View getView(int position, View convertView, ViewGroup parent) {         ViewHolder holder;         // 最初だけ View を inflate して、それを再利用する         if (convertView == null) {             // activity_main.xml に list.xml を inflate して convertView とする             convertView = inflater.inflate(itemLayoutId, parent, false);             // ViewHolder を生成             holder = new ViewHolder();             holder.textView = convertView.findViewById(R.id.textView);             holder.imageView = convertView.findViewById(R.id.imageView);             convertView.setTag(holder);         }         // holder を使って再利用         else {             holder = (ViewHolder) convertView.getTag();         }         // holder の imageView にセット         holder.imageView.setImageResource(ids[position]);         // 現在の position にあるファイル名リストを holder の textView にセット         holder.textView.setText(titles[position]);         return convertView;     }     @Override     public int getCount() {         // texts 配列の要素数         return titles.length;     }     @Override     public Object getItem(int position) {         return null;     }     @Override     public long getItemId(int position) {         return 0;     } } | 
 
遷移先のActivityです。
SubActivity.java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //package com.example.testlistviewitemclick; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.widget.ImageView; import android.widget.TextView; public class SubActivity extends AppCompatActivity {     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_sub);         Intent intent = getIntent();         // MainActivityからintentで受け取ったものを取り出す         String selectedText = intent.getStringExtra("Text");         int selectedPhoto = intent.getIntExtra("Photo", 0);         TextView textView = findViewById(R.id.selected_text);         textView.setText(selectedText);         ImageView  imageView = findViewById(R.id.selected_photo);         imageView.setImageResource(selectedPhoto);     } } | 
 
ManifestにSubActivityを登録します。
AndroidManifest.xml
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"     ...     <application        ...         <activity android:name=".MainActivity">             ...         </activity>         <activity             android:name=".SubActivity"             android:label="@string/app_name" >         </activity>     </application> </manifest> | 
 
MainActivityのレイアウト
activity_main.xml
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context=".MainActivity">     <ListView         android:id="@+id/list_view"         android:layout_width="match_parent"         android:layout_height="wrap_content"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintLeft_toLeftOf="parent"         app:layout_constraintRight_toRightOf="parent"         app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> | 
 
ListViewのinflater
list.xml
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="horizontal"     android:layout_width="match_parent"     android:layout_height="match_parent">     <ImageView         android:id="@+id/imageView"         android:scaleType="centerCrop"         android:contentDescription="@string/description"         android:layout_margin="5dp"         android:layout_width="120dp"         android:layout_height="80dp" />     <TextView         android:id="@+id/textView"         android:layout_margin="29dp"         android:layout_gravity="center_vertical"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:textSize="20sp"         android:textColor="#000" /> </LinearLayout> | 
 
SubActivityのレイアウト
activity_sub.xml
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context=".MainActivity">     <TextView         android:id="@+id/selected_text"         android:textSize="20sp"         android:textColor="#000"         android:layout_margin="10dp"         android:layout_width="match_parent"         android:layout_height="wrap_content"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintLeft_toLeftOf="parent"         app:layout_constraintRight_toRightOf="parent"         app:layout_constraintTop_toTopOf="parent"         app:layout_constraintVertical_bias="0.15"/>     <ImageView         android:id="@+id/selected_photo"         android:layout_margin="10dp"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:contentDescription="@string/description"         android:scaleType="fitCenter"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintLeft_toLeftOf="parent"         app:layout_constraintRight_toRightOf="parent"         app:layout_constraintTop_toTopOf="parent"         app:layout_constraintVertical_bias="0.5"/> </androidx.constraintlayout.widget.ConstraintLayout> | 
 
リソース
strings.xml
| 1 2 3 4 | <resources>     <string name="app_name">Your App Name</string>     <string name="description">picture</string> </resources> | 
サンプル動画
このまま同じように GridView に変える事も可能です。
 
関連ページ:
- ArrayAdapter
- ListView と ArrayAdapter 簡単なテキストリストの表示
- ArrayAdapterを使ってレイアウトをアレンジ
- ListActivity と ArrayAdapterで画像とテキストをリスト表示
- Basedapter
- BaseAdapterで画像とテキストをリスト表示
- ListViewリストをタップして画面遷移
- ListViewアイテムの移動、削除
- ListView アイテム個々の背景、高さなどを変える
References:
ListView | Android Developers
リストビュー | Android Developers
BaseAdapter | Android Developers
![[Android] ListView リストをタップして画面遷移させてみる base adapter 00 100x100 - [Android] ListView リストをタップして画面遷移させてみる](https://akira-watson.com/wp-content/uploads/2013/12/base-adapter_00-100x100.jpg)
