2016-09-28 6 views
0

안드로이드의 ListView에서 다중 삭제 작업을하는 데 문제가 있습니다.맞춤 어댑터에서 항목 삭제 android

1) 나는 (내가) 내가 가장 중요한을 생각하는 것만 여기 놓을 게 몇 가지 버튼 및 텍스트와 각 행을 사용자 정의 할 CustomAdapter를 만들었습니다

public class PlayableCustomAdapter extends ArrayAdapter<String> { 
private final boolean[] checkedItems; 
private final LayoutInflater mInflater; 
private final ActivityCallback activityCallback; 

public PlayableCustomAdapter(Context context, ActivityCallback activityCallback, 
          List<String> files) { 
    super(context, NO_SELECTION); 

    this.activityCallback = activityCallback; 
    this.mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    this.checkedItems = new boolean[files.size()]; 

    addAll(files); 
} 

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    View row = convertView; 
    Holder holder; 

    if (row == null) { 
     row = mInflater.inflate(R.layout.list_view_row_song, null); 

     holder = new Holder(); 
     holder.text = (TextView) row.findViewById(R.id.tvFileName); 
     holder.configs = (TextView) row.findViewById(R.id.tvFileConfiguration); 
     holder.checkBox = (CheckBox) row.findViewById(R.id.cbDelete); 
     holder.playButton = (ImageButton) row.findViewById(R.id.btnPlay); 
     holder.settingsButton = (ImageButton) row.findViewById(R.id.btnSettings); 
     holder.text.setText(getItem(position)); 
     holder.configs.setText(getLyricConfiguration(getItem(position))); 
     row.setTag(holder); 

    } else { 
     holder = (Holder) convertView.getTag(); 
    } 

    holder.playButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      startPrompter(position); 
     } 
    }); 

    holder.settingsButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      startSettings(position); 
     } 
    }); 

    holder.text.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      startEditFile(position); 
     } 
    }); 
    holder.checkBox.setChecked(checkedItems[position]); 
    holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
      if (isChecked) { 
       checkedItems[position] = true; 
       activityCallback.showContent(); 
      } else { 
       verifySelectedItems(position); 
      } 
     } 
    }); 

    return row; 
} 

private void verifySelectedItems(int position) { 
    checkedItems[position] = false; 
    for (boolean checked : checkedItems) { 
     if (checked) 
      return; 
    } 
    activityCallback.hideContent(); 
} 

public boolean isChecked(int position) { 
    return checkedItems[position]; 
} 

@Override 
public void remove(String s) { 
    verifySelectedItems(getPosition(s)); 
    super.remove(s); 
    notifyDataSetChanged(); 
} 

static class Holder { 
    TextView text; 
    TextView configs; 
    ImageButton playButton; 
    CheckBox checkBox; 
    ImageButton settingsButton; 
} 

2) 내가 사용했습니다 이 어댑터는 액티비티에서 작동하며 모든 것은 여러 번의 삭제를 제외하고는 매력처럼 작동합니다. 모든 어댑터 항목을 지울 때만 listview가 올바르게 업데이트됩니다. 하나 이상의 항목을 삭제하면 어댑터가 정상적으로 작동하는 것 같습니다. 모든 위치가 올바르게 전달됩니다. 그러나 목록 끝에있는 항목 만보기에서 제거되는 방법을 모르겠습니다. 당신이 볼 수 있듯이

3), I는 삭제 후 notifyDataSetChanged();을 사용하고 있는데 문제가 계속 발생합니다. 내가 작동하게 만들 수있는 유일한 (그리고 HORRIBLE) 해결책은 삭제 후 활동을 다시 만드는 것이었다. (recreate();). 화면이 깜박이며, 끔찍하지만 완전히 기능합니다. 이제 나는 자유 시간을 갖기 때문에 너희들에게 도움을 청한다.

private void deleteFilesFromDisk(List<Integer> positionsToDelete, ArrayAdapter adapter) { 
    File[] files = getAppFiles(); 
    for (int position : positionsToDelete) { 
     if (files[position].delete()) { 
      adapter.remove(fileNames.get(position));     
     } else 
      showMessage(R.string.delete_file_error, fileNames.get(position)); 
    } 
    recreate(); // Horrible workaround, but it works! 
} 

이 방법은 단지 예를 들어 있음을 유의하시기 바랍니다 : 여기에

어댑터를 사용하는 활동에서 코드입니다. 특히 마지막 줄. 레크리에이션 명령을 사용하지 않으면 목록 맨 끝에있는 항목 만 제거됩니다 (최소한 시각적으로 말하면 UI에서 제거됩니다).

모든 요망?

+0

adapter.notifydatasetchanged()? 상속 된 메서드 대신 adapter.remove (fileNames.get (position))를 호출 할 때 – BIW

+0

어댑터에서 항목을 제거 할 필요가 없으며 목록에서 항목을 제거하고 데이터 집합이 변경된 어댑터에 알립니다. –

답변

0

귀하의 문제는, 내가 당신이라면 당신은 대신 선택한 항목을 추적하는 부울 배열을 유지의, checkedItems 에서 인덱스를 어댑터에서 항목을 제거 할 수 있지만하지

@Override 
public void remove(String s) { 
    verifySelectedItems(getPosition(s)); 
    super.remove(s); 
    notifyDataSetChanged(); 
} 

여기 있습니다 ArrayList<Integer>을 사용하고 목록의 모든 확인 된 위치를 유지합니다.

그런 다음

private void verifySelectedItems(int position) { 
    checkedItems[position] = false; 
    for (boolean checked : checkedItems) { 
     if (checked) 
      return; 
    } 
    activityCallback.hideContent(); 
} 

대신이 될 수 ...이

private void verifySelectedItems(int position) { 
    if(!checkedItems.contains(position)) { 
     activityCallback.hideContent(); 
    } 
} 

편집을 다음이이

@Override 
public void remove(String s) { 
    int pos = getPosition(s); 
    verifySelectedItems(pos); 
    remove(s); 
    checkedItems.remove(Integer.valueOf(pos)); 
    notifyDataSetChanged(); 
} 

과 같은 것을 보는 그 방법을 변경할 수 :

죄송합니다. 나는이 문제

당신은 올바른 항목을 제거하는
if (row == null) { 
     row = mInflater.inflate(R.layout.list_view_row_song, null); 

     holder = new Holder(); 
     holder.text = (TextView) row.findViewById(R.id.tvFileName); 
     holder.configs = (TextView) row.findViewById(R.id.tvFileConfiguration); 
     holder.checkBox = (CheckBox) row.findViewById(R.id.cbDelete); 
     holder.playButton = (ImageButton) row.findViewById(R.id.btnPlay); 
     holder.settingsButton = (ImageButton) row.findViewById(R.id.btnSettings); 
     holder.text.setText(getItem(position)); 
     holder.configs.setText(getLyricConfiguration(getItem(position))); 
     row.setTag(holder); 

    } else { 
     holder = (Holder) convertView.getTag(); 
    } 

생각, 제대로 질문을 읽어 보지 않았, 그러나 이것은, 어쩌면이

if(convertView == null) { 
    convertView = mInflater.inflate(R.layout.list_view_row_song, null); 
} 

Holder holder = new Holder(); 
holder.text = (TextView) convertView.findViewById(R.id.tvFileName); 
holder.configs = (TextView) convertView.findViewById(R.id.tvFileConfiguration); 
holder.checkBox = (CheckBox) convertView.findViewById(R.id.cbDelete); 
holder.playButton = (ImageButton) convertView.findViewById(R.id.btnPlay); 
holder.settingsButton = (ImageButton) convertView.findViewById(R.id.btnSettings); 

holder.text.setText(getItem(position)); 
holder.configs.setText(getLyricConfiguration(getItem(position))); 
같은 것을 시도해보세요 notifydatasetchanged 후 업데이트되는 의견을 방지
+0

남자!! 너는 생명의 은인이야 :) –