2012-06-28 113 views
0
ListView listView; 
Activity activity; 
public ArrayList<Tasks> tasks; 
View v; 

public TaskAdapter(Activity activity, ArrayList<Tasks> tasks) 
{ 
    super(activity, R.layout.presenterlayout, tasks); 
    this.activity = activity; 
    this.tasks = tasks; 
} 

static class ViewHolder { 
    public TextView taskTitleTextView; 
    public TextView taskDescriptionTextView; 
    public TextView taskDueTimeTextView; 
    public CheckBox checkBox; 
} 

public View getView(final int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 
    v = convertView; 
    if (v == null) { 
     LayoutInflater inflator = activity.getLayoutInflater(); 
     v = inflator.inflate(R.layout.presenterlayout, null, false); 
     listView = (ListView) v.findViewById(R.id.listView); 
     holder = new ViewHolder(); 
     holder.taskTitleTextView = (TextView)  v.findViewById(R.id.taskTitleTextView); 
     holder.taskDescriptionTextView = (TextView) v.findViewById(R.id.taskDescriptionTextView); 
     holder.taskDueTimeTextView = (TextView) v.findViewById(R.id.taskDueTimeTextView); 
     holder.checkBox = (CheckBox) v.findViewById(R.id.checkBox); 
     holder.taskTitleTextView.setText(tasks.get(position).getTasksTitleString()); 
     holder.taskDescriptionTextView.setText(tasks.get(position).getTasksDescriptionString()); 
     holder.taskDueTimeTextView.setText(tasks.get(position).getTasksDueTimeString()); 
     holder.checkBox.setId(position); 
     holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

      @Override 
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
       if(holder.checkBox.isChecked()) 
       { 
        System.out.println("postion: " + position); 
        if(tasks.get(position).isTasksCompleted().equals("true")) 
        { 
         tasks.get(position).setTasksCompleted("false");       
        } 
        else if(tasks.get(position).isTasksCompleted().equals("false")) 
        { 
         tasks.get(position).setTasksCompleted("true");       
        } 
        updateThisTask(tasks.get(position)); 
        tasks.remove(position); 
        notifyDataSetChanged(); 
       } 
      } 
     }); 
    } 
    else { 
     v = convertView; 
    } 
    return v; 
} 

private void updateThisTask(Tasks tasks) { 
    DBAdapter dbAdapter = new DBAdapter(getContext()); 
    int id = dbAdapter.getID(tasks); 
    dbAdapter.updateTask(tasks, id); 
} 

} 

我想從數組列表中刪除項目。正如你所看到的,我正在使用複選框。我第一次點擊複選框時,正確的項目被刪除。第二次,如果我點擊複選框,由於索引超出範圍,應用程序崩潰。我如何從數組列表中刪除一個稱爲任務的項目並更新列表視圖?如何刪除ArrayList項目,然後更新列表視圖

+0

您的適配器是baseAdapter/ArrayAdapter? – rajpara

+0

向我們展示您的LogCat請 –

回答

4

一旦你從tasks數組中刪除一個項目,畢竟該項目得到一個新的指數,因此所有你已經保存在持有人,並傳遞到OnCheckedChangeListener是錯誤的position值。我想你這樣做,你不能依賴數組中的位置作爲查找條目的方式。您需要使用對象本身並搜索數組以查找匹配的對象。使用類似

int arrayIndexOfThisTask = tasks.indexOf(objectThatIsInTheArray); 

編輯:添加代碼示例:

試試這個:

public View getView(int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 
    v = convertView; 
    if (v == null) { 
     LayoutInflater inflator = activity.getLayoutInflater(); 
     v = inflator.inflate(R.layout.presenterlayout, null, false); 
     listView = (ListView) v.findViewById(R.id.listView); 
     holder = new ViewHolder(); 
     v.setTag(holder); // Attach the holder to the view so we can find it again 
     holder.taskTitleTextView = (TextView)  v.findViewById(R.id.taskTitleTextView); 
     holder.taskDescriptionTextView = (TextView) v.findViewById(R.id.taskDescriptionTextView); 
     holder.taskDueTimeTextView = (TextView) v.findViewById(R.id.taskDueTimeTextView); 
     holder.checkBox = (CheckBox) v.findViewById(R.id.checkBox); 
    } else { 
     // Get the ViewHolder from the recycled view 
     holder = (ViewHolder)v.getTag(); 
    } 
    // Get the task at this position in the array 
    final Task task = tasks.get(position); 

    holder.taskTitleTextView.setText(task.getTasksTitleString()); 
    holder.taskDescriptionTextView.setText(task.getTasksDescriptionString()); 
    holder.taskDueTimeTextView.setText(task.getTasksDueTimeString()); 
    holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
      if(holder.checkBox.isChecked()) 
      { 
       // Try to find the position in the array for this object (it may already have been removed) 
       int position = tasks.indexOf(task); 
       System.out.println("postion: " + position); 
       // If this object is no longer in the array, just ignore this action 
       if (position >= 0) { 
        if(tasks.get(position).isTasksCompleted().equals("true")) 
        { 
         tasks.get(position).setTasksCompleted("false");       
        } 
        else if(tasks.get(position).isTasksCompleted().equals("false")) 
        { 
         tasks.get(position).setTasksCompleted("true");       
        } 
        updateThisTask(tasks.get(position)); 
        tasks.remove(position); 
        notifyDataSetChanged(); 
       } 
      } 
     } 
    }); 
    return v; 
} 

我可能沒有一切完全正確,但你應該明白我的意思。

實際上有很多事情你的代碼錯誤:

  1. 你沒有正確使用ViewHolder模式。您從未使用setTag()ViewHolder附加到View本身,並且在convertView中給出再循環視圖時,您從未從中檢索到ViewHolder
  2. 如果convertView非空,您只是將它返回而不做任何事情。這是錯誤的,因爲適配器以任何想要的方式回收視圖,並且它可能會從位置6向您傳遞View,並要求位置1請求View。在這種情況下,您將剛剛返回位置6的View(這不是正確)。
  3. 我已將實際的Task對象傳遞給onCheckChanged()方法,而不是傳遞位置,我使用indexOf()來獲取該對象的數組中的當前位置。

我希望這會有幫助。

+0

這不可能,因爲我需要某種索引才能從數組列表中獲取項目。 –

+0

增加了代碼示例和其他一些觀察。玩的開心。 –

+0

非常感謝,這些肯定是好的一點。 –

相關問題