如何向列表视图中的每个按钮添加一个点击,填充自定义数组适配器,从数组中删除该项目并更新它?

How to add an onclick to every button in a listview, populated with a custom arrayadapter, that deletes that item from the array and updates it?

我才刚刚开始学习Android,所以如果我没有很好地解释我正在努力做的事情,我深表歉意。

所以在我的 presetList activity 中,我有一个 Preset 对象的数组列表,我用来自 sqlite 数据库的值填充该数组列表,该数据库是在其相应的 DBHelper 中创建和定义的。我有一个使用自定义视图(textView 和 imageButton)的 presetAdapter。我将 imageButtons 设置为删除图标,当点击时,从数据库中删除相应的文本视图,用更新的值重新填充 arraylist,然后更新自身,以显示值的删除。

我能够从数据库中正确删除该值,并且为了重新填充和刷新数组列表和 presetAdapter,我在 presetList 中创建了一个名为 refreshList() 的方法。此方法应处理该功能,但当我调用它时,它会抛出 NullPointerException。更具体地说,当我尝试打开游标以从我的数据库中读取值时它崩溃了:

错误:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.dmapp, PID: 5697
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDatabasePath(java.lang.String)' on a null object reference
        at android.content.ContextWrapper.getDatabasePath(ContextWrapper.java:327)
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:352)
        at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:322)
        at com.example.dmapp.presetsDBHelper.getSpecificPresets(presetsDBHelper.java:93)
        at com.example.dmapp.PresetList.refreshList(PresetList.java:77)
        at com.example.dmapp.PresetAdapter.onClick(PresetAdapter.java:72)

这是预设列表:

public class PresetList extends AppCompatActivity {

    MyRecyclerViewAdapter adapter;
    private PresetAdapter presetAdapter;
    private ArrayList<Preset> presetList = new ArrayList<>();
    String TAG = "PresetList";
    private String passedPresetVariable;
    private presetsDBHelper mPresetsDBHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.preset_list);
        setPassedPresetVariable(this.getIntent().getStringExtra("presetVariable"));
        Log.d(TAG, "onCreate: Passed Preset variable is " + getPassedPresetVariable());


        // data to populate the RecyclerView with

        mPresetsDBHelper = new presetsDBHelper(this);
        DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
        int deviceHeight = (displayMetrics.heightPixels);

        Button addEntry = findViewById(R.id.addEntry);
        ListView presetListView = findViewById(R.id.presetListView);

        ViewGroup.LayoutParams params = presetListView.getLayoutParams();
        params.height = (int)(deviceHeight * .80);
        presetListView.setLayoutParams(params);

        // set up the RecyclerView with data from the database
        //Log.d(TAG, "onCreate: Preset variable is " + getIntent().getStringExtra("presetVariable"));
        Cursor presets = mPresetsDBHelper.getSpecificPresets(getIntent().getStringExtra("presetVariable"));
        try {
            if (presets.moveToNext()) {
                do {
                    presetList.add(new Preset(presets.getString(2)));
                } while (presets.moveToNext());
            }
        } finally {
            presets.close();
        }

        presetAdapter = new PresetAdapter(this, presetList);
        presetListView.setAdapter(presetAdapter);

        /*
        addEntry.setOnClickListener(new View.OnClickListener() {
            // The code in this method will be executed when the numbers View is clicked on.
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(view.getContext(), CityInfo.class);
                startActivity(intent);
            }
        });
        */
    }

    public void refreshList(){
        mPresetsDBHelper = new presetsDBHelper(this);
        Log.d(TAG, "refreshList: Preset variable is " + getPassedPresetVariable());
        presetList.clear();
        Cursor presets = mPresetsDBHelper.getSpecificPresets("Environment"); //Didn't work with getPassedPresetVariable, attempted hardcoded value to test. Still not functional
        try {
            if (presets.moveToNext()) {
                do {
                    presetList.add(new Preset(presets.getString(2)));
                } while (presets.moveToNext());
            }
        } finally {
            presets.close();
        }
        presetAdapter.notifyDataSetChanged();
    }

    public void setPassedPresetVariable(String passedPresetVariable) {
        this.passedPresetVariable = passedPresetVariable;
    }

    public String getPassedPresetVariable() {
        return passedPresetVariable;
    }
}

这是我的适配器:

public class PresetAdapter extends ArrayAdapter<Preset> {

    private Context mContext;
    private List<Preset> presetList = new ArrayList<>();
    private PresetList presetListClass;
    String TAG = "PresetAdapter";

    public PresetAdapter(Context context, ArrayList<Preset> list) {
        super(context, 0 , list);
        mContext = context;
        presetList = list;
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View listItem = convertView;
        if(listItem == null) {
            listItem = LayoutInflater.from(mContext).inflate(R.layout.preset_item, parent, false);
        }

        Preset currentPreset = presetList.get(position);
        final TextView name = listItem.findViewById(R.id.presetValue);
        ImageButton delete = listItem.findViewById(R.id.deleteIcon);

        name.setText(currentPreset.getValue());
        name.setTag(position);
        name.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                int position = (Integer) view.getTag();
                // Access the row position here to get the correct data item
                Preset preset = getItem(position);
                // Do what you want here...
                String presetValue = preset.getValue();
                Intent intent = new Intent(name.getContext(), CityInfo.class);
                intent.putExtra("presetValue", presetValue);
                mContext.startActivity(intent);
            }
        });

        delete.setTag(position);
        delete.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                int position = (Integer) view.getTag();
                // Access the row position here to get the correct data item
                Preset preset = getItem(position);
                // Do what you want here...
                String presetValue = preset.getValue();
                presetsDBHelper mPresetsDBHelper = new presetsDBHelper(name.getContext());
                mPresetsDBHelper.removeSpecificPreset(presetValue);
                presetListClass = new PresetList();
                presetListClass.refreshList();
            }
        });

        return listItem;
    }
}

我假设有一种更简单的方法可以解决我所缺少的问题,或者有一些更简单的解决方案。如果有人能给我一些见解,将不胜感激!

抱歉,如果我的问题看起来很愚蠢,但这是我 class 刚开始时的一个常见错误,所以我问: 你知道你的光标从 0 开始吗​​?那么 2 实际上是第 3 个字段? 游标就像数组索引一样工作。也许这对你来说很明显,然后我 apologize.but 我 class 一半的伙伴因此而面临这个问题。

而且我不确定 extends ArrayAdapter<> 是否应该指定类型?我也是新手,所以我不知道,但是当我使用我没有指定的适配器时它正在工作

所以这比我想象的要容易得多。我已经将 arrayList 传递到 arrayAdapter,我在其中定义了 onClick 方法。我需要做的就是将代码从 refreshList() 函数迁移到 arrayAdapter 和 notifyDataSetChanged();

中的 onClick 内部

我的 arrayAdapter 中的 onClick 方法现在看起来像这样:

delete.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                int position = (Integer) view.getTag();
                // Access the row position here to get the correct data item
                Preset preset = getItem(position);
                // Do what you want here...
                String presetValue = preset.getValue();
                presetsDBHelper mPresetsDBHelper = new presetsDBHelper(name.getContext());
                mPresetsDBHelper.removeSpecificPreset(presetValue);

                presetList.clear();
                Cursor presets = mPresetsDBHelper.getSpecificPresets("Environment"); //Didn't work with getPassedPresetVariable, attempted hardcoded value to test. Still not functional
                try {
                    if (presets.moveToNext()) {
                        do {
                            presetList.add(new Preset(presets.getString(2)));
                        } while (presets.moveToNext());
                    }
                } finally {
                    presets.close();
                }
                notifyDataSetChanged();

            }
        });