1.きっかけ
斎藤新三著『Androidアプリ開発の教書(Kotlin版)初版第2刷』のp109の「アクティビティ中のリストデータを生成する、ListViewSample2]を写経していた際、ListViewに文字が表示されない(正確には、表示されているが、バックグラウンドと(ほぼ)同色で見えない)事象を発見したので報告します。この事象はリストデータをstring.xmlに持つやり方では起こりませんでした。また確認した範囲では、エミュレータがAPIレベル24以上のときにはこの事象は起こりませんでした。
どうでしょう?罫線と罫線の間にうっすらと文字が表示されているのが見えますか?(上の写真はAPIレベル19のもの)
次の写真はAPIレベル30のものです。本当ならこのように表示されるよう期待していました。
2.ソースコード
2.1 レイアウトファイル
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lvMenu"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
2.2 MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//ListViewオブジェクトを取得
val lvMenu = findViewById<ListView>(R.id.lvMenu)
// リストビューに表示するリストデータを作成
var menuList = mutableListOf("A", "B", "C")
//アダプタオブジェクトを生成する
val adapter = ArrayAdapter(
applicationContext,
android.R.layout.simple_list_item_1,
menuList)
//リストビューにアダプタオブジェクトを設定
lvMenu.adapter = adapter
}
}
3.現象
少し現象を調べたところ、OS(APIレベル)の違いで文字が(黒色で)表示できたりできなかったりするようです。
3.1 実機
名称 OSバージョン 文字可読の可否
Huawei G628-TL Android4.4.4 不可
Huawei Nova Android7.0 可
(CAZ-TL10)
3.2 エミュレータ
名称 APIレベル 文字可読の可否
Nexus4 19 不可
Nexus One 19 不可
Nexus 5X 21 不可
Nexus 5X 23 不可
Nexus 5X 24 可
Nexus 5X 27 可
Nexus 5X 28 可
Nexus 5X 29 可
Pixel3 30 可
4.原因
エンジニアならばもっと深堀して原因を探るべきでしょうが、初心者なので先を急がさせてください。
5.対策
コメント欄のgaeさんのご教示により、正しい対策方法が見つかりましたので、それを記述します。(以前記述していた対処方法はこの項の下部に見え消し状態で残しておきます。)
ArrayAdapterの第一引数をapplicationContextからthisに変更したところ、思い通りに表示するようになりました。
//アダプタオブジェクトを生成する
val adapter = ArrayAdapter(
this, // 変更点
android.R.layout.simple_list_item_1,
menuList)
また、AndroidApiのArrayAdapterのリファレンスには、次のように記述されています。
ArrayAdapter
public ArrayAdapter (Context context, int resource, T[] objects)
Constructor.
Parameters
context Context: The current context. This value cannot be null.
resource int: The resource ID for a layout file containing a TextView to use when instantiating views.
objects T: The objects to represent in the ListView. This value cannot be null.
リファレンスに第1引数がThe current context(現在のコンテキスト)と書かれているので、gaeさんが言うアクティビティーのインスタンスとは、“this”のことだと判断しました。(またAndroidアプリ開発AndroidStudio3.0対応java版を読み返したところ、第1引数はthisになっていました。それではapplicationContextとは何者ぞ?と疑問が涌いてサクッと調べたら、「ApplicationContext派とActivityContext派の主張」などと言った具合に、難しい話のようなので頭の片隅に残し、今後の課題とします。)
これで、思い通り表示されました。(実機Huawei G628-TL及びエミュレータAPIレベル19、21、23で確認済)
(以下、対策が見つかる以前に記述していた対処方法を参考と履歴のために残しておきます。)
#5.対処方法
バックグラウンドと文字の色を指定することにより表示が見えるようにしました。
本来ならば、MainActivity.ktの中に記述できると思いますが、その方法が見つからなかった(解決できなかった)ので、この方法でお茶を濁します。
ただ、ひとつ気になるのが、色の指定がうまくできないことです。backgroundで指定した#000fffは青に近い色でまあまあ正しく表示しているのですが、文字の色を指定するtextColorの#f00000は赤に近い色のはずですが、表示上”白”で表示されます(どの色を指定しても白で表示されます)。今後MainActivityの中で文字の色指定する方法が見つかれば、きっと解決できると思います。
xml
<?xml version="1.0" encoding="utf-8"?>
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lvMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:entries="@array/lv_menu"
android:background="#000fff"
android:textColor="#f00000"
/>
6.今後検討すべきこと
(1)今後MainActivityの中で文字の色指定する方法が見つける
(2)今回はArrayAdapterでこの現象が起きたが、SimpleAdapterやSimpleCursorAdapterでこの現象が起きるか
-->SimpleAdapterでも同様の現象が起きました(2020/10/15追記)。
(3)ApplicationContextとActivityContextとthisの違い
7.参考
nyan のアプリ開発 Android & Kotlin ListView と ArrayAdapter 簡単なテキストリストの表示
8.動作環境
Android Studio 4.1
Build #AI-201.8743.12.41.6858069, built on September 24, 2020
Runtime version: 1.8.0_242-release-1644-b01 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
GC: ParNew, ConcurrentMarkSweep
Memory: 1237M
Cores: 8
Registry: ide.new.welcome.screen.force=true
Non-Bundled Plugins: com.thoughtworks.gauge