いくつかのビューが定義されたxmlファイルでSimpleCursorAdapterを使用していました。
<LinearLayout ...>
<ImageView android:id="@+id/listIcon" />
<TextView android:id="@+id/listText" />
</LinearLayout>
私の目的は、TextViewのテキストの色とLinearLayoutの背景色(つまり、ListViewの各行)をプログラムで設定することでした。色はデータベースから返されます。
たとえば、TextViewを操作しようとしたときに、文句なしにNPEが検出された後、NPEを取得していました。
TextView tv = (TextView) findViewById(R.id.listText);
tv.setTextColor(color); // NPE on this line
これは公正です。リストに複数のエントリがある場合は、「R.id.listText」は機能しないと考えるのが妥当です。そこで、SimpleCursorAdapterを拡張しました。
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
TextView text = (TextView) row.findViewById(R.id.listText);
// ImageView icon = (ImageView) row.findViewById(R.id.listIcon);
// If there's an icon defined
if (mIcon_id != 0) {
// icon.setImageResource(mIcon_id);
}
// If text color defined
if (mTextColor != 0) {
text.setTextColor(mTextColor);
}
// If background color set
if (mBackgroundColor != 0) {
row.setBackgroundColor(mBackgroundColor);
}
return(row);
}
そして、2つの異なるエラーが発生します。
- 同様のNPEが「text.setTextColor(mTextColor)」でスローされます
- ImageViewの行にコメントがない場合、 「 Row.findViewById(R.id.listIcon)」を呼び出している「 ClassCastException:android.widget.TextView 」が表示されます。
参考までに、Commonswareのサンプルコードを自分の状況に適用しようとしていました。リンク(pdf)
これに変更されました:
public View getView(int position, View convertView, ViewGroup parent) {
convertView = super.getView(position, convertView, parent);
if (convertView == null) convertView = View.inflate(mContext, R.layout.theme_item, null);
TextView text = (TextView) convertView.findViewById(R.id.listText_tv);
ImageView icon = (ImageView) convertView.findViewById(R.id.listIcon_iv);
// If there's an icon defined
if (mIcon_id != 0) {
icon.setImageResource(mIcon_id);
}
// If text color defined
if (mTextColor != 0) {
text.setTextColor(mTextColor);
}
// If background color set
if (mBackgroundColor != 0) {
convertView.setBackgroundColor(mBackgroundColor);
}
bindView(convertView, mContext, mCursor);
return(convertView);
}
次のアクティビティでClassCastExceptionが発生します(リストアイテムをクリック)。次のアクティビティでは何も変更されていません。エントリのあるリストにSimpleListAdapterを使用すると機能したので(クリックするとActivity2になります)、この拡張クラスではまだ間違っていると思います。