1

ListActivity に問題があります。ArrayAdapter と Overridden getView を拡張して、各行のデータを入力しました。Adapter の ArrayList から TextView にいくつかのデータをスローします。

私の問題は、スクロールすると、各行の TextView に、ArrayList の対応するデータにないテキストが入力されることです。つまり、リストの一番上に、空の文字列が入力された TextView を含む行があるとします。リストの一番下にいて、TextView に "bob" が入力された行が表示されている場合、フリックして一番上までスクロールすると、一番上の行の TextView に "bob" が含まれている可能性がありますが、私のArrayListのそのインデックスには「bob」が含まれていません。空の文字列 (実際には null) が含まれています。上下にスクロールし続けると、アダプターの ArrayList の内容に対応しないデータが他の行に入力 (または消去) されます。

これを実現するために、ListView を高速にスクロールする必要はありません。ただし、スクロールが速いほど、行がめちゃくちゃになるようです。

これが私のコードです。getView が呼び出されるたびに findViewById を使用していることに気付きましたが、それは問題ではありません。convertView に対して呼び出しています。各行で正しい TextView を取得する必要がありますね。

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    // get the View for this list item
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.layout_mylistlist_item, null);
    }

    // get the next object
    MyListItem myItem = m_items.get(position);

    // set up the list item
    if (myItem != null) {
        TextView txtName = (TextView) v.findViewById(R.id.mylist_name);

        // set text
        if (txtName != null && myItem.getName() != null) {
            txtName.setText(myItem.getName());
        }
    }

   // return the created view
    return v;
}
4

2 に答える 2

2

問題は、一番下の if(myItem != null) チェックだと思います。

テキストビューを空の文字列に設定するelseステートメントをそのブロックに追加してみてください。

そのようです:

// set up the list item 
TextView txtName = (TextView) v.findViewById(R.id.mylist_name); 
if (myItem != null) {  
    // set text 
    if (txtName != null && myItem.getName() != null) { 
        txtName.setText(myItem.getName()); 
    } else
    {
        txtName.setText("");
    }
} 
else
{
    txtName.setText("");
}

convertview には、渡されたときにまだ古いデータが含まれています。データが無効な場合でも、意図的に上書きする必要があります。そうしないと、古いデータが保持されます。

于 2010-08-18T18:41:31.390 に答える
1

これを交換

if (v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.layout_mylistlist_item, null);
    }

これとともに

if (v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.layout_mylistlist_item, parent, false);
    }

inflate(...) メソッドに「false」を渡す必要があります。

時間があれば、Android ListView に関する今年の I/O セッションをご覧ください: http://code.google.com/events/io/2010/sessions/world-of-listview-android.html

それを見るか、少なくともスライドをスクロールすることは本当に価値があります。彼らもオンラインです。

あなたのフィードバックに基づいて、データを ArrayAdapter にバインドする方法を提案させてください。多分それはあなたの問題を解決します。

public class MyTestArrayAdapter extends ArrayAdapter<MyDataModel>{
   private final int resourceId;

   public MyTestArrayAdapter(Context context, int resourceId, List<MyDataModel> myDataModelList) {
      super(context, resourceId, myDataModelList);
      this.resourceId = resourceId;
   }

   @Override
   public View getView(int position, View convertView, ViewGroup parent) {
      if(convertView == null){
         LayoutInflater inflater = (LayoutInflater)getContext().getSystemService....
         convertView = inflater.inflate(resourceId, parent, false);
      }

      MyDataModel modelObj = getItem(position);

      TextView someDataView = convertView.findViewById(....);
      someDataView.setText(modelObj.getDataText());
      ...

      return convertView;
   }

}

データを ArrayAdapter のメンバーとして渡す必要はないと思います。(これをコンパイルまたは実行しようとしなかったため、調整が必要になる場合があります)

于 2010-08-18T15:16:58.330 に答える