2011-10-30 53 views
2

我有一種感覺,這是由於某種渲染優化或某種東西,但我不知道是什麼。列表視圖顯示多個選定項目

我有一個列表視圖,當一個項目被選中時,我改變它的背景顏色,使它在視覺上保持被選中。

當列表超出屏幕(它滾動),如果我選擇頂部附近的項目,然後向下滾動它也會顯示另一個選擇的項目,曾經不在視圖(我永遠不會看到2同時在屏幕上選擇的項目)。如果我選擇靠近底部的一個項目,然後滾動到頂部,它也會以相反的方式起作用,它將顯示另一個項目作爲被選中的項目。

另外還有一個說明,所選項目之間的距離不統一,如果我將設備旋轉到橫向,所選項目之間的距離較小。

如果不清楚是什麼問題,我還附上圖片。

這是一個最小的列表,它只顯示一個選定的項目。 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

ListView控件回收的意見(與View v = convertView; if (v == null) { } ...的部分),所以你設置上,將被反覆使用的視圖的背景。相反,您還需要在模型上設置「選定」標誌(Book對象本身)。在被註釋掉你getView的一部分,你然後說:

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

所以我在想,當我向下滾動列表,它調用getView方法生成的列表作爲其他項目糾正他們接近進入視野? –

+0

是的,'getView()'被調用每一行。它或多或少地保留了緩存中的可見視圖的數量,並在那之後重用它們。因此,當您向下滾動時,用於第一個項目的相同視圖將用於n + 1項目(左右)。這就是爲什麼你必須每次都在視圖上設置你關心的每個屬性,包括背景。 – dmon

相關問題