Android notifyDataSetChanged не обновляет элементы после удаления

Итак, я пытаюсь удалить элемент в ожидании, однако он не удаляет его из списка сразу после щелчка. Я должен вернуться и вернуться к этому экрану, и он будет удален. Однако мой другой список на том же экране был немедленно обновлен (метод отправленного профиля). Я попытался создать метод, который выполняет ту же функцию, которая мне нужна, и вызываю ее до notifyDataSetChanged, но ничего не работает. Спасибо за любые советы о том, почему мой notifyDataSetChanged не работает.

ArrayAdapter<String> adapterSubmit, adapterPending;
    ArrayList<String> itemsSubmit, itemsPending;
    ListView lstSubmitPro, lstPendingPro;
    String path = Environment.getExternalStorageDirectory().getAbsolutePath() +  "/CaptureLogs";
    Button btnSubmit;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_pro_list);
        btnSubmit = (Button) findViewById(R.id.btnTest);
        lstSubmitPro = (ListView) findViewById(R.id.lstSubmitPro);
        lstPendingPro = (ListView) findViewById(R.id.lstPendingPro);
        itemsSubmit = new ArrayList<String>();
        adapterSubmit = new ArrayAdapter(this, R.layout.prolist, R.id.tvRows, itemsSubmit);
        lstSubmitPro.setAdapter(adapterSubmit);
        itemsPending = new ArrayList<String>();
        adapterPending = new ArrayAdapter(this, android.R.layout.simple_list_item_multiple_choice, itemsPending);
        lstPendingPro.setAdapter(adapterPending);
        lstPendingPro.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        pendingSubmitProfile();
        SubmittedProfile();
        btnSubmit.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            SparseBooleanArray sp = lstPendingPro.getCheckedItemPositions();
            if (sp!= null) {
                for (int i = 0; i < sp.size(); i++) {
                    if (sp.valueAt(i) == true) {

                        SubmittedProfile();
                        adapterSubmit.notifyDataSetChanged();

                        itemsPending.remove(sp.get(i));
                        adapterPending.notifyDataSetChanged();
                        Toast.makeText(ProList.this, "Your profiles have been submitted successfully.", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(ProList.this, "Please choose a profile to be submitted.", Toast.LENGTH_LONG).show();
                    }
                }
            }
            }

        });

  public void pendingSubmitProfile()
    {
        File dir = new File(path);
        File[] files = dir.listFiles();
        for (File f : files) {
            if (f.isFile()) {
                BufferedReader inputStream = null;
                try {
                    inputStream = new BufferedReader(new FileReader(f));
                    String lineToRead = "--PENDING SUBMIT--";
                    String CurrentLine;
                    while ((CurrentLine = inputStream.readLine()) != null) {
                        if (CurrentLine.equals(lineToRead)) {
                            String filen = f.getName().substring(0, f.getName().lastIndexOf("."));
                            itemsPending.add(filen);

                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }




public void SubmittedProfile()
{
    File dir = new File(path);
    File[] files = dir.listFiles();
    for (File f : files) {
        if (f.isFile()) {
            BufferedReader inputStream = null;
            try {
                inputStream = new BufferedReader(new FileReader(f));
                String lineToRead = "--SUBMITTED--";
                String CurrentLine;
                while ((CurrentLine = inputStream.readLine()) != null) {
                    if (CurrentLine.equals(lineToRead)) {
                        String filen = f.getName().substring(0, f.getName().lastIndexOf("."));
                        itemsSubmit.add(filen);

                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

ЖУРНАЛ

Ранее было 2 элемента, но отмечен 1

05-02 08:00:02.409 4293-4293/com.example.irambi.irmobilewizard D/returned value:: 2 1 2

После 2 элемента, но 1 отмечен

05-02 08:00:03.726 4293-4293/com.example.irambi.irmobilewizard D/returned value:: 0 1 0

Это для 1 элемента и 1 проверенного. Я не могу сказать, было ли это до или после, так как на logcat напечатано только 1. Это приведет к сбою и следующей ошибке

05-02 08:03:35.345 4293-4293/com.example.irambi.irmobilewizard D/returned value:: 1 1 1

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0

Ранее было 2 элемента, но 2 проверено

05-02 08:07:56.378 4596-4596/com.example.irambi.irmobilewizard D/returned value:: 2 2 2

После 2 элемента, но 2 проверены — произойдет сбой.

05-02 08:07:57.671 4596-4596/com.example.irambi.irmobilewizard D/returned value:: 0 2 0
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0

Все испытания проводятся с использованием

itemsPending.remove(sp.keyAt(i));
                      adapterPending.remove(adapterPending.getItem(sp.keyAt(i)));

Лог на основе:

Log.d("returned value:", itemsPending.size() + " " + sp.size()  + " " + adapterPending.getCount());

person Kelvin JigSawing    schedule 02.05.2018    source источник


Ответы (4)


Попробуй это

itemsPending.remove(sp.keyAt(i));
adapterPending.remove(adapterPending.getItem(sp.keyAt(i)));
adapterPending.notifyDataSetChanged();

ИЗМЕНИТЬ:

Так что в основном переключение данных списка работает нормально. Что портит код, так это то, что он пишет файл. Я решаю это так.

Во-первых, создайте функцию, которая обновит мои ожидающие файлы до отправленных.

public void submitPendingProfile(String filename){
    try {
        BufferedReader file = new BufferedReader(new FileReader(path + "/" + filename+".txt"));
        String line;
        StringBuffer inputBuffer = new StringBuffer();

        while ((line = file.readLine()) != null) {
            inputBuffer.append(line);
            inputBuffer.append('\n');
        }
        String inputStr = inputBuffer.toString();

        file.close();


        inputStr = inputStr.replace("--PENDING SUBMIT--", "--SUBMITTED--");

        FileOutputStream fileOut = new FileOutputStream(path + "/" + filename+".txt");
        fileOut.write(inputStr.getBytes());
        fileOut.close();

    } catch (Exception e) {
        System.out.println("Problem reading file.");
    }
}

Затем я рефакторинг цикла для более простого процесса. Например, удалить строку SubmittedProfile();, которая продолжает читать все текстовые файлы, если условия верны. Это большой процесс. Вот как вместо этого.

for(int i = lstPendingPro.getAdapter().getCount() - 1 ; i >= 0; i--) {
    if (sp.get(i)) {
       //So when file is submitted, i update the files status using the above function.
       submitPendingProfile(itemsPending.get(i));

       //To avoid rereading of files, just add the item before removing it to the pending list
       itemsSubmit.add(itemsPending.get(i));
       adapterSubmit.notifyDataSetChanged();

       itemsPending.remove(sp.keyAt(i));
       adapterPending.notifyDataSetChanged();
       Toast.makeText(ProList.this, "Your profiles have been submitted successfully.", Toast.LENGTH_LONG).show();
   }
}
person Android_K.Doe    schedule 02.05.2018
comment
Комментарии не для расширенного обсуждения; этот разговор был перемещен в чат< /а>. - person Samuel Liew♦; 03.05.2018

Вы пытались изменить свой код в этом порядке?

    btnSubmit.setOnClickListener(new View.OnClickListener()

{

    @Override
    public void onClick (View v){
    SparseBooleanArray sp = lstPendingPro.getCheckedItemPositions();
    if (sp != null) {
        for (int i = 0; i < sp.size(); i++) {
            if (sp.valueAt(i) == true) {

                SubmittedProfile();
                itemsPending.remove(sp.get(i));

                Toast.makeText(ProList.this, "Your profiles have been submitted successfully.", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(ProList.this, "Please choose a profile to be submitted.", Toast.LENGTH_LONG).show();
            }
        }
    }
    adapterSubmit.notifyDataSetChanged();
    adapterPending.notifyDataSetChanged();
}

});
person AFLAH ALI    schedule 02.05.2018
comment
Пробовал, но нет, он все еще не обновляет этот список мгновенно - person Kelvin JigSawing; 02.05.2018
comment
Попробуйте переместить строки 'adapterSubmit.notifyDataSetChanged(); itemsPending.remove(sp.get(i)); адаптерPending.notifyDataSetChanged(); Toast.makeText(ProList.this, Ваши профили успешно отправлены., Toast.LENGTH_LONG).show();' внутрь метода SubmittedProfile() - person AFLAH ALI; 02.05.2018
comment
тогда, если я это сделаю, мне не нужно будет снова объявлять sp? - person Kelvin JigSawing; 02.05.2018
comment
Вы можете передать sp в качестве аргумента SubmittedProfile(); изменив метод на public void SubmittedProfile(SparseBooleanArray sp){...} - person AFLAH ALI; 02.05.2018
comment
Просто для того, чтобы понять, где проблема - person AFLAH ALI; 02.05.2018

Попробуйте этот код..

    itemsPending.remove(itemsPending.indexOf(sp.get(i)));
    adapterPending.notifyDataSetChanged();
person Android Team    schedule 02.05.2018
comment
Оно сломалось. Я получил исключение ArrayOutOfBoundsException. - person Kelvin JigSawing; 02.05.2018

itemsPending.remove(sp.get(i));
adapterPending.notifyDataSetChanged();
listview.invalidate();

Попробуйте приведенный выше код, возможно, он вам поможет.

person Riddhi Shah    schedule 02.05.2018
comment
Пробовал, но нет, он все еще не обновляет этот список мгновенно - person Kelvin JigSawing; 02.05.2018
comment
Затем используйте recylerview - person Riddhi Shah; 02.05.2018