4

いくつかのビューが定義された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になります)、この拡張クラスではまだ間違っていると思います。

4

4 に答える 4

5

convertViewが常に既存のインスタンスになるというのは真実ではありません。nullかどうかを確認してから、インスタンス化する必要があります。そうでない場合は、変更することができます。

これは次のようになります。

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);
}
于 2011-03-14T20:38:58.677 に答える
1

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;
}
于 2011-03-14T21:28:29.833 に答える
0

テキストビューとイメージビューが存在しないビューで作成しようとしているため、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);

そして、アダプターが指すlistIconとlistTextを使用してentry.xmlを定義します。私の例では、連絡先リストから名前と番号を照会しています。

カスタムアダプタでは、getViewまたはbindView内のtextviewおよびimageviewに問題なくアクセスできるはずです。

ここで は、連絡先リスト内のすべての連絡先をその写真、名前、番号とともに取得する例を示しますが、アクティビティの代わりにListActivityを使用し、2つのテキストビューと1つの画像ビューを持つ1つのxmlのみを使用します。ListActivityを使用する場合、ListViewを使用する必要はなく、アクティビティでコンテンツビューを設定する必要もありません。

お役に立てば幸いです。

于 2011-03-14T21:31:18.767 に答える
-2

ビューごとに:layout_widthとlayout_heigthを入力することを忘れないでください。

于 2011-03-14T20:25:23.040 に答える