I am creating a demo Android app which has a ListView displaying in a fragment. Each List item has a text and a delete button, and the items are stored in SQLite database. I am having trouble understanding how to delete the corresponding item from the database when the delete button is clicked. I searched for various ways online, and could not figure out how to get the _ID value (set to autoincrement) of the row item in the DB, so that the item could be deleted.
The custom Adapter class
public class CustomListAdapter extends ArrayAdapter<DataModel> implements View.OnClickListener{
private ArrayList<DataModel> dataSet;
Context mContext;
private TaskHelper_tab1 mHelper;
public CustomListAdapter(@NonNull Context context, int resource, @NonNull ArrayList<DataModel> data) {
super(context, resource, data);
this.dataSet = data;
this.mContext=context;
}
private static class ViewHolder {
TextView txtName;
Button btn;
}
@Override
public void onClick(View v) {
int position=(Integer) v.getTag();
Object object= getItem(position);
DataModel dataModel=(DataModel)object;
switch (v.getId())
{
case R.id.task_delete:
Snackbar.make(v, "Release date " +dataModel.getName(), Snackbar.LENGTH_LONG)
.setAction("No action", null).show();
break;
}
}
private int lastPosition = -1;
@SuppressLint("NewApi")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// Get the data item for this position
final DataModel dataModel = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
final ViewHolder viewHolder; // view lookup cache stored in tag
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.task_list_long_term_item, parent, false);
viewHolder.txtName = (TextView) convertView.findViewById(R.id.task_title);
viewHolder.btn = (Button) convertView.findViewById(R.id.task_delete);
result=convertView;
convertView.setTag(viewHolder);
viewHolder.btn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
int id2 = (int) getItemId(position);
Toast.makeText(mContext,id2 + " Button clicked" + position,Toast.LENGTH_SHORT).show();
deleteTask(id2);
notifyDataSetChanged();
}
});
} else {
viewHolder = (ViewHolder) convertView.getTag();
result=convertView;
}
lastPosition = position;
viewHolder.txtName.setText(dataModel.getName());
return convertView;
}
public void deleteTask(int position){
mHelper = new TaskHelper_tab1(getContext());
SQLiteDatabase db = mHelper.getWritableDatabase();
db.execSQL("DELETE FROM " + Task_tab1.TaskEntry.TABLE + " WHERE " + Task_tab1.TaskEntry._ID + "= '" + position + "'");
db.close();
}
}
The fragment code
public class fragment_tab1 extends Fragment{
//for db tasks
EditText editText = null;
private TaskHelper_tab1 mHelper;
FloatingActionButton fab_tab1;
private PopDialog.PopDialogListener listener; //listener to pass the text to parent activity
private TextView textViewDescr;
private CustomListAdapter mAdapter;
private View view;
private ListView list_calllog;
private ArrayList<DataModel> callLog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mHelper = new TaskHelper_tab1(getContext());
list_calllog = (ListView) getActivity().findViewById(R.id.list);
updateUI(); //this works -- keep this to initially populate the UI on opening app
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if(view==null)
{
view=inflater.inflate(R.layout.fragment_tab1, container,false);
}
else
{
ViewGroup parent = (ViewGroup) view.getParent();
parent.removeView(view);
}
callLog= new ArrayList<>();
callLog.add(new DataModel("Apple Pie", null)); //maybe add button here
callLog.add(new DataModel("Banana Bread",null ));
CustomListAdapter adapter=new CustomListAdapter(getActivity(),R.layout.task_list_long_term_item,callLog);
list_calllog=(ListView)view.findViewById(R.id.list);
list_calllog.setAdapter(adapter);
fab_tab1 = (FloatingActionButton) view.findViewById(R.id.fab_tab1);
fab_tab1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View tab1) {
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.pop_dialog_layout, null);
alert.setTitle("info")
.setMessage("dialog box message")
.setView(view)
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String edittext_descr = editText.getText().toString();
applyTexts(edittext_descr);
Toast toast = Toast.makeText(getContext(), "adadadaa", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
}
);
alert.show();
editText = view.findViewById(R.id.edit_text);
}
});
return view;
}
@Override
public void applyTexts(String edittext_descr) {
String task = String.valueOf(edittext_descr);
SQLiteDatabase db = mHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Task_tab1.TaskEntry.COL_TASK_TITLE, task);
db.insertWithOnConflict(Task_tab1.TaskEntry.TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
updateUI();
}
private void updateUI() {
ArrayList<DataModel> taskList = new ArrayList<>();
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cursor = db.query(Task_tab1.TaskEntry.TABLE,
new String[] {Task_tab1.TaskEntry._ID, Task_tab1.TaskEntry.COL_TASK_TITLE}, null, null, null, null, null);
while(cursor.moveToNext()){
int index = cursor.getColumnIndex(Task_tab1.TaskEntry.COL_TASK_TITLE);
//add new task
String str = cursor.getString(index);
DataModel dm = new DataModel(str,null );
taskList.add(dm);
}
if(mAdapter == null){
mAdapter = new CustomListAdapter(getActivity(), R.layout.task_list_long_term_item, taskList );
list_calllog.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(taskList);
mAdapter.notifyDataSetChanged();
}
cursor.close();
db.close();
}
}
I searched for various ways online, and could not figure out how to get the _ID value (set to autoincrement) of the row item in the DB, so that the item could be deleted.
Aren't you querying the ID attribute for the object when you read the data from the database? If not, do that and store in the DataModel
. Then when you get the object that was clicked, you have the ID:
DataModel dataModel=(DataModel)object;
// TODO: Use dataModel.getId()
Hope that helps!