在Listview onItemClick上选择了错误的项目

时间:2014-09-29 05:16:55

标签: android listview simplecursoradapter onitemclick

面对一个非常奇怪的问题。我在每个项目上都有listview checkbox,当我点击正在选中的listview的第一项时,与此项目一起,最后一项列表视图也正在被选中!当我滚动列表视图时。没有滚动它是完美的。

此外,当我选择最后一项时,滚动后会同时选择第一项。提醒,这些第一个和最后一个之间的所有其他项目都正常工作。选择第一个或最后一个项目后,有趣的部分是如果我不滚动listview 2-3秒,它就能完美运行。所以我希望这可能是视图渲染或某种程度上的问题。有人能指出我到底发生了什么......

Cursor cursor = queryDatabase();

    // The desired columns to be bound
      String[] columns = new String[] {               
        DataBaseHelper.ROW_PROFILE_NAME,
        DataBaseHelper.ROW_PROFILE_TYPE,
        DataBaseHelper.ROW_ID
      };

      // the XML defined views which the data will be bound to
      int[] to = new int[] { 
        R.id.profileName,
        R.id.profileStatus
      };

      // create the adapter using the cursor pointing to the desired data 
      //as well as the layout information
      mAdapter = new SimpleCursorAdapter(
        this, R.layout.profile_listview_delete_item, 
        cursor, 
        columns, 
        to,
        0);

      listView = (ListView) findViewById(R.id.profile_listview_delete_main);
      // Assign adapter to ListView
      listView.setAdapter(mAdapter);

      listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
            // TODO Auto-generated method stub

            CheckBox cb;                

            Cursor c = mAdapter.getCursor();
            String prodile_id = c.getString(c.getColumnIndex(DataBaseHelper.ROW_ID));

            cb = (CheckBox)arg1.findViewById(R.id.checkbox);
            cb.toggle();

            if(cb.isChecked())
            {                   
                profileStack.add(prodile_id);                   
                //Toast.makeText(getApplicationContext(), String.valueOf(profileStack), Toast.LENGTH_LONG).show();                  
                counter++;              
            }
            else if(!cb.isChecked())
            {
                profileStack.remove(prodile_id);                    
                //Toast.makeText(getApplicationContext(), String.valueOf(profileStack), Toast.LENGTH_LONG).show();                  
                counter--;                  
            }               
            countSelectedItem.setText(String.valueOf(counter)+" items selected");

            mAdapter.notifyDataSetChanged();                                
        }
    });

3 个答案:

答案 0 :(得分:1)

您应该使用自定义Adapter(以及模型类optional。此处TemaRescatado是片段中的模型类)。在getView(...)中,您必须使用CompoundButton.OnCheckedChangeListener尝试使用ViewHolder pattern

代码段

viewHolder.checkbox = (CheckBox) view.findViewById(R.id.checkBox1);
viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

      @Override
      public void onCheckedChanged(CompoundButton buttonView,
         boolean isChecked) {
         TemaRescatado element = (TemaRescatado) viewHolder.checkbox
                  .getTag();
         element.setSelected(buttonView.isChecked());

         }
      });

答案 1 :(得分:1)

您应该从AdapterView获取光标,该光标作为参数传递给onItemClick方法。

更改代码。

Cursor c = mAdapter.getCursor();

Cursor c = (Cursor) arg0.getItemAtPosition(position);

答案 2 :(得分:0)

发生此问题是因为ListView的回收。只要显示适配器的下一个数据,它就会立即使用第一个可见的View。因此,当您检查List&#39}中的数据并选中复选框时位置。它会保持不变你离开它。所以我对这个问题的解决方案是:

在您的适配器getView()

添加一个简单的if-else语句来检查是否应该选中复选框,如下所示:

// note that this is a pseudo code
if(ID exist in profileStack){
//set checkBox
}
else{
//set checkBox
}