2011-10-30 21 views
2

これは何らかのレンダリングの最適化などによるものだと感じていますが、わかりません。リストビューに複数の選択されたアイテムが表示される

私はリストビューを持っていて、アイテムが選択されたときに、その背景色を変更して視覚的に選択したままにします。

問題は、リストの上から項目を選択してスクロールすると、一度表示されていた別の選択項目が表示された場合に表示されます。同じ時間に画面上の選択された項目)。これは反対の方法でも機能します。下の項目を選択して上にスクロールすると、選択されている別の項目が表示されます。

また、選択したアイテム間の距離が均一ではないため、デバイスをランドスケープに回転すると、選択したアイテム間の距離が小さくなります。

問題が何であるかわからない場合は、私も写真を添付し​​ました。

これは最小限のリストであり、選択された1つのアイテムのみを表示します。 enter image description here

ここでは、上部付近のアイテムを選択しました。下にスクロールした後 enter image description here

(スクロールバーを参照)が選択されているように別のアイテムを表示します。 enter image description here

コードのためです。

リストの一部です。

public class ResultListFragment extends ListFragment { 

BookListAdapter mBooksArray; 
BookData api; 
View footer; 
ListView list; 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Activity parent = getActivity();  
     BookSearch app = (BookSearch) parent.getApplicationContext(); 

    api = app.bookAPI; 

    mBooksArray = new BookListAdapter(/*some params*/); 
    mBooksArray.currentActivity = parent; 


} 

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

     list = (ListView) inflater.inflate(R.layout.search_results, null); 

    footer = inflater.inflate(R.layout.load_more, null); 

    return list; 
} 

public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    list.addFooterView(footer); 

    list.setAdapter(mBooksArray); 
} 

} 

また、ArrayAdapterでは、色はonClickメソッドで変更されます。

public class BookListAdapter extends ArrayAdapter<Book> { 

ArrayList<Book> books; 
private BookData bookData; 
Activity currentActivity; 
final BookListAdapter self = this; 
private View selected = null; 



public void update() { 
    currentActivity.runOnUiThread(new Runnable() { 
     public void run() {  
      self.notifyDataSetChanged(); 
     } 
    }); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    if (v == null) { 

     LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
       Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.search_list_view_item, null); 
    } 
    /*some code to set the image and text */ 
    v.setOnClickListener(new OnItemClickListener(position)); 
    return v; 
} 

public void onClick(int position, View view) { 
      // this log always reports the correct position when i select a list item 
    Log.i(new Integer(position).toString(), books.get(position).title); 
    if(selected != null) { 
     selected.setBackgroundResource(R.drawable.list_view_bg); 
    } 
    selected = view; 
    selected.setBackgroundResource(R.color.listSelected); 

} 

private class OnItemClickListener implements OnClickListener{   
     private int mPosition; 

     OnItemClickListener(int position){ 
      mPosition = position; 
     } 
     @Override 
     public void onClick(View view) { 
     BookListAdapter.this.onClick(mPosition, view); 
     }    
    } 
} 

答えて

2

リストビューは、ビュー(View v = convertView; if (v == null) { } ...との一部)を再利用するので、あなたは何度も何度も使用されるビューの背景を設定しています。代わりに、モデルに "selected"フラグを設定する必要があります(Bookオブジェクト自体)。コメントアウトされて、あなたのgetViewの一部では、あなたがして言う:

if (book.isSelected()) { 
    v.setBackgroundResource(R.color.listSelected) 
} 
+0

は、だから私は、私は、リストをスクロールダウンして、その彼らのように、リスト内の他の項目を生成するために、GetViewメソッドを呼び出すことを考えに修正しています見通しに近づく? –

+0

ええ、 'getView()'が各行に対して呼び出されます。それは、キャッシュ内の可視ビューの数を多かれ少なかれ保持し、その後、それらを再利用します。したがって、下にスクロールすると、最初のアイテムに使用されたのと同じビューがn + 1アイテム(またはそれ以降)に使用されます。だからこそ、背景を含めて毎回ビュー上で気になるすべてのプロパティを設定する必要があります。 – dmon

関連する問題