simplecursoradapterのfindViewByID()の場合、nullpointer
-
24-10-2019 - |
質問
XMLファイルを備えたSimpleCursoradapterを使用していました。
<LinearLayout ...>
<ImageView android:id="@+id/listIcon" />
<TextView android:id="@+id/listText" />
</LinearLayout>
私の目的は、TextViewのテキスト色とLinearLayoutの背景色(つまり、ListViewの各行)をプログラムで設定することでした。色はデータベースから返されます。
たとえば、TextViewを操作しようとしたときにNPEを取得していました。
TextView tv = (TextView) findViewById(R.id.listText);
tv.setTextColor(color); // NPE on this line
これは公平です。リストに複数のエントリがある場合、それを想定するのは合理的です」r.id.listtext「機能しません。したがって、SimpleCursorアダプターを拡張しました。
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のラインが登録されていない場合、私は「ClassCastException:Android.Widget.TextView「私が呼んでいる場所」row.findviewbyid(r.id.listicon)"
参照のために、私は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を取得します(リスト項目のクリック)。次のアクティビティでは何も変更されていません。エントリ(クリックするとActivity2につながる)を備えたリストにSimpleListAdapterを使用するときに機能したため、この拡張クラスで間違っていることだと思います。
解決
それは本当ではありません ConvertView 常に既存のインスタンスになります。それが無効かどうかを確認してから、インスタンス化する必要があります。そうでない場合は、あなたがしたように変更することができます。
これは次のようなものでなければなりません:
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
convertView = //inflate your row here
View row = convertView;
//Manipulate the row here
return(row);
}
他のヒント
GetViewメソッドを変更します:
public View getView(int position, View convertView, ViewGroup parent) {
convertView = View.inflate(getContext(), R.layout.myLayout, null);
TextView text = (TextView) convertView.findViewById(R.id.listText);
ImageView icon = (ImageView) convertView.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) {
convertView.setBackgroundColor(mBackgroundColor);
}
return convertView;
}
TextViewとImageViewを作成しようとしているため、NPEを取得していると思います。
データベースからのエントリを使用してListViewを膨らませたい場合、アクティビティでは、listViewでmain.xmlを定義します。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/listView1">
</ListView>
そして、oncreateメソッドでは、このXMLのビューを設定します setContentView(R.layout.main);
. 。次に、データベースとカスタムアダプターにカーソルを作成します。
MySimpleCursorAdapter adapter = new MySimpleCursorAdapter(this, R.layout.entry,
names, new String[] {Phones.NAME, Phones.NUMBER}, new int[] {
R.id.listIcon, R.id.listText});
startManagingCursor(cursor);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(adapter);
また、AdapterがポイントするListIconとListTextでEntry.xmlを定義します。私の例では、連絡先リストから名前と数字をクエリしています。
カスタムアダプターでは、問題なくgetViewまたはbindView内のTextViewとImageViewにアクセスする必要があります。
ここ 連絡先リストのすべての連絡先をその写真、名前、番号で取得するが、アクティビティの代わりにListActivityを使用し、2つのテキストビューとImageViewを持つ1つのXMLのみを使用する例があります。 ListActivityを使用する場合、ListViewを使用する必要はなく、アクティビティでコンテンツビューを設定する必要はありません。
私はそれが役立つことを願っています!
それぞれのビューについて、layout_widthとlayout_heigthを置くことを忘れないでください。