5

カスタムアダプタを備えたlistViewがあります。何かが起こったとき(子のクリック)、私はいくつかの計算を行い、子ビューを変更します。何らかの条件が満たされた場合は、クリックされた子に関係のない他の子を変更する必要があります。

これは機能することもありますが、失敗することもあり、DDMSはビューがnullであると言います...

コードをお見せしましょう:

        if(invalidaEste != -1)
        {
            try
            {
                View v = lv_data.getChildAt(invalidaEste);
                if( v== null)
                {
                    Log.e("MY_LOG", "SIZE " + lv_data.getCount());
                    Log.e("MY_LOG", "IS_NULL " + String.valueOf(invalidaEste)); 
                }

                if(invalidaEste >= lv_data.getFirstVisiblePosition() &&
                   invalidaEste <= lv_data.getLastVisiblePosition())
                {
                    RelacionFacturaPago rpf = (RelacionFacturaPago)lv_data.getAdapter().getItem(invalidaEste);
                    TextView tv = (TextView)v.findViewById(R.id.tv_pendiente);
                    tv.setText(Formato.double2Screen(rpf.getPorPagar()));
                }
            }
            catch (Exception e)
            {
                Log.e("MY_LOG", "FAIL");
                Log.e("MY_LOG", String.valueOf(invalidaEste));
            }

        }

invalidaEsteは、変更したいビューです。vがnullの場合、インデックスをログに記録して、問題がないかどうかを確認します。常にlistView.getCount()以下です

なぜこうなった?

その他のデータ:コードは、AnimationListenerリスナーのonAnimationStart(アニメーションアニメーション)内にあります。

4

4 に答える 4

9

ビューのリサイクルのため、listView.getChildAt()表示されている位置のビューのみが返され、場合によってはもう1つ返されます。たぶん、あなたがあなたのコードのより多くを共有するならば、私たちはあなたが問題に最もよく取り組む方法を理解するのを手伝うことができます。

于 2012-04-25T15:37:51.820 に答える
4

DmonとAzertitiはどちらも正しいです...リストをスクロールすると、問題が発生します。ビューが表示されていない場合、そのビューは存在しません(つまり、Androidによってリサイクルされています)。スクロールインしたら、ビューを再構築します。

このようなことを行うとうまくいくはずです:

View view;

int nFirstPos = lv_data.getFirstVisiblePosition();
int nWantedPos = invalidaEste - nFirstPos;

if ((nWantedPos >= 0) && (nWantedPos <= lv_data.getChildCount())
{
 view = lv_data.getChildAt(nWantedPos);
 if (view == null)
  return;
 // else we have the view we want
}
于 2012-04-25T18:36:27.900 に答える
1

その子が画面に表示されていない場合は、その子のビューがないことを意味します。これはあなたのうまくいかないケースだと思います。

リストアダプタの背後にあるデータを変更し、アダプタでnotifyDataSetChanged()を呼び出すことをお勧めします。これにより、アダプタが変更されたリストが通知され、ビューが再度ペイントされます。

ビューを本当に手動で更新したい場合、唯一の解決策は、新しい値をどこかに保持し、ビューが表示されるまで待つことだと思います。その時点で、有効な参照があり、更新を実行できます。

于 2012-04-25T15:38:37.007 に答える
1

リストビューの有効な位置に入る必要がある場合は、1行のコードでテストします。これが例として使用される変数です。ここで、lv_dataはListView、tvはTextViewです。

if ( lv_data.getChildAt(lv_data.getPositionForView(tv)) != null) {
    int position = lv_data.getPositionForView(tv);
}
于 2015-09-15T21:00:13.593 に答える