如何向列表视图中的每个按钮添加一个点击,填充自定义数组适配器,从数组中删除该项目并更新它?
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();
}
});
我才刚刚开始学习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();
我的 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();
}
});