2011-10-30 51 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

相关问题