ArrayAdapter notifyDataSetChanged 没有响应

ArrayAdapter notifyDataSetChanged not responding

好的,我知道有很多帖子与上下文菜单和列表视图相关。我查看了 20 多页并且 none 已经能够解决我的问题。我能够从 listView 中删除一个项目,但我的应用程序跳过了 notifyDataSetChanged。 listView 的 arrayList 和 listView 本身只是静态的,因为我从一个单独的 activity 添加到它。这是我的代码...

/**
 * Activity to complete trash audits.
 * @author John D. Miller
 * @version 1.0.1
 * @since 12/06/2015
 */
package com.example.chefj.hometrashaudit;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;

public class HomeTrashAuditActivity extends AppCompatActivity {

static ListView listView;
static EditText dateText;
static ArrayList<Waste> items = new ArrayList<>();
ArrayAdapter<Waste> listAdapter;
ArrayList<Waste> wasteList = new ArrayList<>();
DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT);
File journalFile = new File("Journal.txt");
File settingsFile = new File("Settings.txt");

// Context Menu
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.listview_context_menu, menu);
}

@Override
public boolean onContextItemSelected(MenuItem item)
{
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    switch(item.getItemId())
    {
        case R.id.edit:
            // TODO launch activity to edit item...

            return true;
        case R.id.remove:
            // Remove the item
            items.remove(info.position);

这是未执行的代码行...

            listAdapter.notifyDataSetChanged();
            return true;
        default:
            return super.onContextItemSelected(item);
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home_trash_audit);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    // Context Configuration
    listView = (ListView)findViewById(R.id.listView);
    registerForContextMenu(listView);

    // Adapter Configuration
    listAdapter = new ArrayAdapter<Waste>(this, android.R.layout.simple_list_item_1, items);
    listView.setAdapter(listAdapter);

    // Setting current date
    Date date = new Date();
    String dat = df.format(date);
    dateText = (EditText) findViewById(R.id.dateText);
    dateText.setKeyListener(null);
    dateText.setText(dat);

    // Pick waste button listener
    listView = (ListView) findViewById(R.id.listView);
    Button pickWasteButton = (Button) findViewById(R.id.pickWasteButton);
    pickWasteButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent i = new Intent(getApplicationContext(), WasteSelectionActivity.class);
            startActivity(i);
        }
    });

    // Date button listener
    Button dateButton = (Button) findViewById(R.id.dateButton);
    dateButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent i = new Intent(getApplicationContext(), DateActivity.class);
            startActivity(i);
        }
    });

    // Add to journal button listener
    Button addToJournalButton = (Button) findViewById(R.id.addToJournalButton);
    addToJournalButton.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v)
        {
            // Empty Journal
            if (listView.getAdapter() == null) {
                Toast.makeText(HomeTrashAuditActivity.this, "You must first complete an audit before adding to Journal!!!", Toast.LENGTH_SHORT).show();
            }

            // Checking if audit exists for selected date
            else if (dateExists())
            {
                Toast.makeText(HomeTrashAuditActivity.this, "An audit for this date has already been completed!!!", Toast.LENGTH_SHORT).show();
            }

            // Appending Journal
            else
            {
                try
                {
                    FileOutputStream os = openFileOutput("Journal.txt", Context.MODE_APPEND);
                    PrintWriter output = new PrintWriter(os);
                    String format = "%s\t\t%-14s\t%-6s\t  %-6s";

                    // Header
                    output.println(dateText.getText().toString() + "\n");
                    output.printf(format, "Material", "Category", "Amount", "Total");
                    output.println("-----------------------------------------------------------------");

                    // Body
                    for (Waste w : items)
                    {
                        output.printf(format, w.getWasteMaterial(), w.getWasteCategory(), w.getAmount(), w.getPercentage());
                        output.println();
                    }
                    output.println("-----------------------------------------------------------------");
                    output.println();

                    // Closing PrintWriter
                    output.flush();
                    output.close();

                    // Confirmation
                    Toast.makeText(HomeTrashAuditActivity.this, "The journal was successfully updated!", Toast.LENGTH_SHORT).show();

                    // Resetting for additional audits
                    items = new ArrayList<>();
                    listAdapter.notifyDataSetChanged();
                    finish();
                }
                catch (Exception ex)
                {
                    ex.printStackTrace();
                }
            }
        }
    });
}

/**
 * Determines an audit has been created for the current audit.
 * @return true or false.
 */
private boolean dateExists()
{
    readInWasteList();
    for (Waste wa : wasteList)
    {
        System.out.println(wa.toString());
    }
    //wasteList.sort(sorter);
    for (Waste w : wasteList)
    {
        if (w.getDate().equals(dateText.getText().toString()))
        {
            return true;
        }
    }
    return false;
}

/**
 * Determines if a line is a date.
 * @param line the line to be evaluated.
 * @return true or false.
 */
private Boolean isDate(String line)
{
    try
    {
        df.parse(line);
        return true;
    }
    catch (ParseException e)
    {
        return false;
    }
}

/**
 * Reads into the wasteList from the file.
 */
private void readInWasteList()
{
    ArrayList<String> lines = new ArrayList<>();
    String date = "";
    wasteList = new ArrayList<>();

    // Reading in file
    try
    {
        File journalFile = getBaseContext().getFileStreamPath("Journal.txt");
        Scanner reader = new Scanner(journalFile);

        // Reading File
        while (reader.hasNextLine())
        {
            lines.add(reader.nextLine());
        }
    }
    catch (FileNotFoundException ex)
    {
        // Do nothing, already handled.
    }

    // Processing information to fill list
    for (String line : lines)
    {
        if (isDate(line))
        {
            date = line;
        }

        // Empty line
        else if (line.equals("")){}

        // Header
        else if (line.contains("Material")){}

        // Audit Separator
        else if (line.contains("--")){}

        // Process data
        else
        {
            Waste waste = new Waste();
            Scanner lineReader = new Scanner(line);
            waste.setDate(date);
            waste.setWasteMaterial(lineReader.next());
            waste.setWasteCategory(lineReader.next());
            waste.setAmount(lineReader.nextDouble());
            wasteList.add(waste);
            lineReader.close();
        }
    }
}

}

我不喜欢您假设 ArrayAdapter 始终保持对您传递给构造函数的同一个列表的引用。在某些情况下——例如,当您使用 getFilter() 时——ArrayAdapter 将更改其对新列表的引用。

改变

items.remove(info.position);
listAdapter.notifyDataSetChanged();

listAdapter.remove(info.position);  // automatically calls notifyDataSetChanged

如果可行,您应该在更改项目列表的所有地方检查并修改代码,并假设 ArrayAdapter 也在幕后更改。

另请记住,ArrayList.remove() 假定 equals() 方法已针对您的使用正确定义。您可能需要检查您的 equals() 实施是否导致胃灼热。