列表项已从 ListView 中删除,但未从数据库中删除
Posted
技术标签:
【中文标题】列表项已从 ListView 中删除,但未从数据库中删除【英文标题】:List item is deleted from ListView, but not from the database 【发布时间】:2018-09-10 17:44:48 【问题描述】:我有一个自定义 ListView 适配器。在 ListView 中我设置了一个删除按钮。
现在我想通过单击该列表的按钮来删除固定列表项。我已经能够从 ListView 中删除它。但是当我刷新我的布局活动时,列表显示在同一个地方。
也许它没有从数据库中删除。我在主要活动中创建了数据库。但是我从 ListView 适配器活动中删除了列表项。
这是我的 ListView 适配器:
import static com.example.shubho.digitalattendancesheet.Constant.FIRST_COLUMN;
import static com.example.shubho.digitalattendancesheet.Constant.SECOND_COLUMN;
public class ListViewAdapter extends BaseAdapter
public ArrayList<HashMap> list;
Activity activity;
public ListViewAdapter(Activity activity, ArrayList<HashMap> list)
super();
this.activity = activity;
this.list = list;
@Override
public int getCount()
// TODO Auto-generated method stub
return list.size();
@Override
public Object getItem(int position)
// TODO Auto-generated method stub
return list.get(position);
@Override
public long getItemId(int position)
// TODO Auto-generated method stub
return 0;
private class ViewHolder
TextView txtFirst;
TextView txtSecond;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
// TODO Auto-generated method stub
// TODO Auto-generated method stub
final ViewHolder holder;
LayoutInflater inflater = activity.getLayoutInflater();
if (convertView == null)
convertView = inflater.inflate(R.layout.course_display_row, null);
holder = new ViewHolder();
holder.txtFirst = (TextView) convertView.findViewById(R.id.t_code);
holder.txtSecond = (TextView) convertView.findViewById(R.id.t_title);
ImageButton delete = (ImageButton) convertView.findViewById(R.id.t_delete);
convertView.setTag(holder);
delete.setOnClickListener( new View.OnClickListener()
@Override
public void onClick(View v)
list.remove(position);
notifyDataSetChanged();
);
else
holder = (ViewHolder) convertView.getTag();
HashMap map = list.get(position);
holder.txtFirst.setText((CharSequence) map.get(FIRST_COLUMN));
holder.txtSecond.setText((CharSequence) map.get(SECOND_COLUMN));
return convertView;
在我的 AddCourseActivity(主要活动)中,我使用了:
public class AddCourseActivity extends AppCompatActivity implements View.OnClickListener
EditText editCourseCode,editCourseTitle;
Button btnAdd,btnEdit,btnSearch,btnShowAll;
ImageButton btnDelete;
SQLiteDatabase db;
ListView listview;
int i;
ArrayList<String> ar =null;
ArrayList<String> ar1 =null;
ArrayList<String> SampleArrayList = new ArrayList<>();
private ArrayList<HashMap> list;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_course);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
editCourseCode = (EditText)findViewById(R.id.courseCode);
editCourseTitle = (EditText)findViewById(R.id.courseTitle);
btnAdd = (Button)findViewById(R.id.add);
btnShowAll = (Button)findViewById(R.id.show);
btnEdit = (Button)findViewById(R.id.update);
db = openOrCreateDatabase("CourseDB", Context.MODE_PRIVATE,null);
db.execSQL("CREATE TABLE IF NOT EXISTS course(courseCode VARCHAR, courseTitle VARCHAR)");
btnAdd.setOnClickListener(this);
btnEdit.setOnClickListener(this);
btnShowAll.setOnClickListener(this);
public void onClick(View view)
if (view == btnAdd)
String str = editCourseCode.getText().toString().trim();
String str1 = editCourseTitle.getText().toString().trim();
if(str.length()>0 && str1.length()>0)
db.execSQL("insert into course values('" + str + "','" + str1 + "')");
Snackbar.make(view, "Inserted", Snackbar.LENGTH_SHORT).show();
editCourseCode.setText("");
editCourseTitle.setText("");
else
Snackbar.make(view, "Not Inserted", Snackbar.LENGTH_SHORT).show();
else if(view == btnShowAll)
try
final ListView lview = (ListView) findViewById(R.id.list);
populateList();
final ListViewAdapter adapter = new ListViewAdapter(this, list);
lview.setAdapter(adapter);
catch (Exception e)
Snackbar.make(view, "No record found", Snackbar.LENGTH_SHORT).show();
else if(view==btnEdit)
if(editCourseCode.getText().toString().trim().length()==0 && editCourseTitle.getText().toString().trim().length()==0)
Snackbar.make(view, "Not Updated", Snackbar.LENGTH_SHORT).show();
return;
else
if (editCourseCode.getText().toString().trim().length() != 0)
db.execSQL("UPDATE course set courseTitle='"+editCourseTitle.getText()+"' WHERE " + " courseCode ='"+editCourseCode.getText()+"'");
else if (editCourseTitle.getText().toString().trim().length() != 0)
db.execSQL("UPDATE course set courseCode='"+editCourseCode.getText()+"' WHERE " + " courseTitle ='"+editCourseTitle.getText()+"'");
Snackbar.make(view, "Updated", Snackbar.LENGTH_SHORT).show();
private void populateList()
// TODO Auto-generated method stub
ar = new ArrayList();
ar1 = new ArrayList();
Cursor c = db.rawQuery("Select * from course", null);
c.moveToFirst();
do
ar.add(c.getString(c.getColumnIndex("courseCode")));
ar1.add(c.getString(c.getColumnIndex("courseTitle")));
while (c.moveToNext());
list = new ArrayList<HashMap>();
for ( i = 0; i < ar.size(); i++)
HashMap temp = new HashMap();
temp.put(FIRST_COLUMN, ar.get(i));
temp.put(SECOND_COLUMN, ar1.get(i));
list.add(temp);
@Override
public boolean onCreateOptionsMenu(Menu menu)
getMenuInflater().inflate(R.menu.menu_add_course, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
// Handle item selection
switch (item.getItemId())
case R.id.action_profile:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
如何从数据库中删除固定列表项?
【问题讨论】:
【参考方案1】:当您从列表中删除时,您只需在数据库表中运行删除查询即可。所以onClickListener
应该是这样的。
ImageButton delete = (ImageButton) convertView.findViewById(R.id.t_delete);
convertView.setTag(holder);
delete.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// Delete from database as well
db.rawQuery("delete from course where courseCode = '" + list.get(position).get(FIRST_COLUMN) + "'", null);
// Now delete from list and update your ListView
list.remove(position);
notifyDataSetChanged();
);
更新
基于问题的更新。我已经修改了您的适配器并在其中引入了一些新变量。请检查适配器并导入此适配器中所需的包。然后修改启动适配器的位置。
public class ListViewAdapter extends BaseAdapter
private ArrayList<HashMap> list;
private Context context;
private SQLiteDatabase db;
public ListViewAdapter(Context context, ArrayList<HashMap> list)
super();
this.context = context;
this.list = list;
@Override
public int getCount()
return list.size();
@Override
public Object getItem(int position)
return list.get(position);
@Override
public long getItemId(int position)
return 0;
private class ViewHolder
TextView txtFirst;
TextView txtSecond;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
final ViewHolder holder;
if (convertView == null)
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.course_display_row, null);
holder = new ViewHolder();
holder.txtFirst = (TextView) convertView.findViewById(R.id.t_code);
holder.txtSecond = (TextView) convertView.findViewById(R.id.t_title);
ImageButton delete = (ImageButton) convertView.findViewById(R.id.t_delete);
convertView.setTag(holder);
delete.setOnClickListener
(new View.OnClickListener()
@Override
public void onClick(View v)
db = context.openOrCreateDatabase("CourseDB", Activity.MODE_PRIVATE, null);
db.execSQL("DELETE from course where courseCode = '" + list.get(position).get(FIRST_COLUMN) + "'");
db.close();
list.remove(position);
notifyDataSetChanged();
);
else
holder = (ViewHolder) convertView.getTag();
HashMap map = list.get(position);
holder.txtFirst.setText((CharSequence) map.get(FIRST_COLUMN));
holder.txtSecond.setText((CharSequence) map.get(SECOND_COLUMN));
return convertView;
希望有帮助!
【讨论】:
db.rawQuery 无法解决。如何在 listview 适配器活动中获取主要活动的数据库?? 与您在主活动中打开数据库的方式相同。初始化适配器时,只需从主要活动传递上下文。 会不会.. final ListViewAdapter 适配器 = new ListViewAdapter(this, list, SQLiteDatabase.db); ??? 没有。我猜你已经在传递上下文了。只需使用上下文在适配器中打开数据库。然后在您的数据库中执行查询。ListViewAdapter adapter = new ListViewAdapter(this, list);
- 很好。
谢谢您,先生。在专家的帮助下,我找到了解决该问题的方法。我已经编辑了代码行,db.execSQL("DELETE from course where courseCode = '" + list.get(position).get(FIRST_COLUMN) + "'");
,它工作正常。【参考方案2】:
在OnClick
中为删除按钮创建一个工作线程并执行数据库查询以删除该项目。
您需要唯一标识列表中的项目,因此基本上您需要在项目上添加某种 id(我认为您已经拥有)
您可以使用AsyncTask
、Handlers
或Threads
来执行此操作。不要在主线程上执行数据库查询,否则您的应用程序会滞后。
附带说明。停止使用notifyDataSetChanged
,而改用notifyItemRemoved
。
【讨论】:
【参考方案3】:在适配器类中创建一个Interface
interface OnDeleteListener
onDeleteCourse(String code, int position)
将此构造函数添加到 Adapter 类
private OnDeleteListenre mListener;
public ListViewAdapter(List<HashMap> items, OnDeleteListener listener)
mListener = listener
...
在 Adapter 类中添加此方法
public void refresh(int position)
// remove the item from the list
list.remove(position)
// refresh listview
notifyDataSetChanged();
如下更改delete
按钮实现
delete.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
// get the course code from the list according to position
...
...
// pass this code and item position here
mListener.onDelete(## PASS COURSE CODE HERE ##, position);
);
让Activity
类implement OnDeleteListener
和
@Override
public void onDeleteCourse(String code, int postion)
// Delete the course from the database here
...
...
// notify the adapter
adapter.refresh(position)
初始化适配器
adapter = ListViewAdapter(list, this)
【讨论】:
以上是关于列表项已从 ListView 中删除,但未从数据库中删除的主要内容,如果未能解决你的问题,请参考以下文章
Ajax / PHP:调用正常,但未从 PHP 发出警报结果
Xamarin MVVM 从另一个页面删除 Listview 项目