1

I have created a database which is displayed in a ListView using an ArrayAdapter. I want a selected ListView item to be deleted when a ContextMenu pops up with a delete option as depicted below:

enter image description here

I have a class for handling all the database functions like delete. When I use a normal onCLicklistener with a button, the delete function is performed correctly, i.e it deletes the correct database entry and reaches the if (cursor.moveToFirst()) line. When I make use of the delete menu item, it does not reach the if (cursor.moveToFirst()) line in the attached delete handler function and therefore does not delete the entry (attached after the ListView code snippet below is the delete handler).

Any help/guidance/examples will be greatly appreciated.

My ListView is populated as follows:

  public class Listview extends AppCompatActivity
  {
   private ListView users;
   FloatingActionButton fab;
   MyDBHandler dbHandler;
   ArrayAdapter<String> arrayAdapter;
   String lists;


    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
       super.onCreate(savedInstanceState);

        StrictMode.ThreadPolicy policy = new 
        StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        setContentView(R.layout.activity_listview);

       // Create back button in action bar
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);


        users = (ListView) findViewById(R.id.clientlst);

        // Floating Action bar for adding new data entries
        fab = (FloatingActionButton) findViewById(R.id.fab1);

        MyDBHandler dbHandler = new MyDBHandler(getApplicationContext());

        lists = dbHandler.loadHandler();

      //Create a list of the saved database String array items and split into 
     Strings
       ArrayList<String> list = new ArrayList<>   
       (Arrays.asList(lists.split("\n")));


        // Create the List view adapter
        arrayAdapter = new ArrayAdapter<String>(Listview.this, 
        android.R.layout.simple_list_item_1, android.R.id.text1, list)

       {
            @Override     // Edit the Text colour of the Listview items
        public View getView(int position, View convertView, ViewGroup parent) 
        {
                String Items = arrayAdapter.getItem(position);
                String[] separated = Items.split(":");
                String Name123 = separated[1];   // This will contain "Name"
                TextView textView = (TextView) super.getView(position, 
                convertView, parent);
                textView.setTextColor(Color.BLUE);
                textView.setText(Name123);
                return textView;
            }
        };

        users.setAdapter(arrayAdapter);
        registerForContextMenu(users);

    // Create an action to be performed by each click of an item in the
         users.setOnItemClickListener
               (
                     new AdapterView.OnItemClickListener()
                     {
                        @Override
                        public void onItemClick(AdapterView<?> parent, View 
                        view, int position, long id) {

                      String Items = arrayAdapter.getItem(position);
                            String[] separated = Items.split(":");
             String ip = separated[5];   // This will contain "PORT address"
             String port = separated[3]; // This will contain "IP number"
                            Toast.makeText(Listview.this, port + ip, 
                                Toast.LENGTH_LONG).show();

                        } // onItemClick

                    } // OnItemClickListener View

            ); // OnItemClickListener


    fab.setOnClickListener(new View.OnClickListener() {
                               @Override
                               public void onClick(View view)
                               {

                                   Toast.makeText(Listview.this, "Fab 
                                 Clicked", Toast.LENGTH_LONG).show();
                               }
                           }
      );
  } 

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, 
    ContextMenu.ContextMenuInfo menuInfo)
    {
      super.onCreateContextMenu(menu, v, menuInfo);

      menu.setHeaderTitle("Choose an option");
      MenuInflater inflator = getMenuInflater();
      inflator.inflate(R.menu.example_menu, menu);
  }

  @Override
  public boolean onContextItemSelected(MenuItem item)
  {

      AdapterView.AdapterContextMenuInfo info = 
     (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

      switch (item.getItemId())
      {
          case R.id.option_1:
              arrayAdapter.getItem(info.position);

            MyDBHandler dbHandler = new MyDBHandler(getApplicationContext());

            String Items= arrayAdapter.getItem(info.position);
            String[] separated = Items.split(":");
            String ip = separated[3];                          // This will 
                                    contain "IP addr"
            String names = separated[1];                       // This will 
            contain "Name"

            Log.d("LATE",names + ip);

            dbHandler.deleteHandler(names,ip);
            arrayAdapter.notifyDataSetChanged();               // Refresh the 
            listview

            Toast.makeText(this, "Deleted", Toast.LENGTH_SHORT).show();
            Intent listviews1 = new Intent(Listview.this, Listview.class);
            startActivity(listviews1);
            return true;

        case R.id.option_2:
            Intent listviews2 = new Intent(Listview.this, Listview.class);
            startActivity(listviews2);
            Toast.makeText(this, "Updated", Toast.LENGTH_SHORT).show();
            return true;

        default:
            return super.onContextItemSelected(item);
        }


    }
}

The delete handler function of the database is as follows:

 public void deleteHandler(String username, String IP)
  {
    //boolean result = false;

    String query = "Select*FROM " + TABLE_USER + " WHERE " + COLUMN_NAME + " 
    = '" +  String.valueOf(username) + "'" + " and " + COLUMN_ID + " = '" +  
    String.valueOf(IP) + "'";

    SQLiteDatabase db = this.getWritableDatabase();

    Cursor cursor = db.rawQuery(query, null);

    Log.d ("MEH", String.valueOf(cursor));

    User user = new User();

    if (cursor.moveToFirst())
    {
        user.setUserName(cursor.getString(2));
        user.setID(cursor.getString(3));

        db.delete(TABLE_USER, COLUMN_NAME + "=? and " + COLUMN_ID + "=?",

        new String[]
        {
                String.valueOf(user.getUserName()),
                String.valueOf(user.getID())
        });

        cursor.close();

        //result = true;
    }

    db.close();

    //return result;
   }
user1892364
  • 259
  • 2
  • 12
Ryno
  • 55
  • 12

2 Answers2

2
  • REMOVE this if (cursor.moveToFirst()) .
  • Make sure, COLUMN_ID is PRIMARY Key.
  • Check deleteHandler() method is invoking or not.

You should try with

  public void deleteHandler(String username, String IP)
     {
        SQLiteDatabase db = this.getWritableDatabase();
                db.delete(TABLE_USER, 
                    COLUMN_NAME  + " = ? AND " + COLUMN_ID  + " = ?", 
                    new String[] {username, IP});
                db.close(); 
     } 
IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
  • The problem is, he is not able to invoke the delete action whenever he tries taps the item on his list because there isn't any callback to it from his `onClickListener` method. – Daksh Gargas Jun 28 '18 at 12:57
  • @Dennis Valid point. By the by, I have `OPTIMISE` code. Hope my STATEMENT satisfy. – IntelliJ Amiya Jun 28 '18 at 12:59
  • 1
    Agreed, +1 for that :) – Daksh Gargas Jun 28 '18 at 13:09
  • Actually, you should also explain it to him, why `cursor.moveToFirst()` is not a good option. (Tutorials usually do that, it's not his fault) – Daksh Gargas Jun 28 '18 at 13:10
  • 1
    Nevermind, I've done the explanation part in my answer. Please review and let me know if i need to add anything else. – Daksh Gargas Jun 28 '18 at 13:14
  • 1
    Thank you for the explanation, I will give it a try and let you know how it goes. – Ryno Jun 28 '18 at 13:16
  • Was my second point valid. I mean should I add some another explanation for that? – Daksh Gargas Jun 28 '18 at 13:20
  • I have a question regarding the second point (Primary key), my promary key is just a integer which gets assigned in my create table. My COLUMN_ID is actually the String I create in one of my table's columns. Should I use the actual PRIMARY KEY (COL_ID) instead of looking for a match with the IP address (COLUMN_ID) in the delete handler? – Ryno Jun 28 '18 at 13:31
  • @Ryno You can use. Don't change now. – IntelliJ Amiya Jun 28 '18 at 13:36
  • @ IntelliJ Thank you for your explanations. – Ryno Jun 28 '18 at 13:58
2

You aren't calling any method to delete the item from the database from your users.setOnItemClickListener

As you added in your comment, all you are doing is trying to delete the item from your ActionBar's onItemClicked method.

Do the same inside your OnItemClickListener

Update2: Change in requirement

 users.setLongClickable(true);
 users.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
    //Do your tasks here


            AlertDialog.Builder alert = new AlertDialog.Builder(
                    YourActivity.this);
            alert.setTitle("Alert!!");
            alert.setMessage("Choose an option");
            alert.setPositiveButton("Edit", new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                     //do your work here                      
                    dialog.dismiss();

                }
            });
            alert.setNegativeButton("Delete", new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    //perform your delete callback here
                    dialog.dismiss();
                }
            });

            alert.show();

    return true;
  }
  });

Update1: Explanation to Amiya's answer,

  1. The reason why cursor.moveToFirst() isn't a good option is because this statement is unnecessary. The compiler knows exact spot to hit when it will enter inside your DB. One usually perform cursor.moveToFirst() when you need to iterate through all or some data elements from your database.
  2. "Make sure, COLUMN_ID is PRIMARY Key." Reason behind this is to avoid duplicity in case you ever add a functionality of adding items on the run time.
Daksh Gargas
  • 3,498
  • 2
  • 23
  • 37
  • Well elaborate. – IntelliJ Amiya Jun 28 '18 at 13:15
  • @dennis I will make these changes in the delete handler, thank you for the clarification. – Ryno Jun 28 '18 at 13:36
  • Are you gonna display a alert dialog? – Daksh Gargas Jun 28 '18 at 13:37
  • @Dennis I haven't thought about it, I am very new to Android Studio and java, would it be difficult to do so? – Ryno Jun 28 '18 at 13:43
  • Just copy and past this code. Let me know if you need any assistance. – Daksh Gargas Jun 28 '18 at 13:43
  • @ennis I get an error saying cannot resolve AlertDialog. What do I need to include to have this function? Sorry for the stupid questions – Ryno Jun 28 '18 at 13:57
  • There are no stupid questions my friend :) Anyway, you need to import AlertDialog. Hit `Crtl + Enter` and your IDE (Android Studio) will automatically import it. – Daksh Gargas Jun 28 '18 at 13:58
  • How do I perform this task (String Items = arrayAdapter.getItem(position) ) in the onClick within the setNegativeButton? – Ryno Jun 28 '18 at 14:19
  • Use the `position` variable from your parameters inside `onItemLongClick(AdapterView> parent, View v, int position, long id)` – Daksh Gargas Jun 28 '18 at 16:03
  • @Dennis, thank you for your help. I have just tested everything and it is still not deleting the database entry for some reason. It is reaching the deleteHandler function and contains the expected (username and IP address) parameters but it is not deleting that entry. I also declared the position as **final int position** in the above function as Android Studio would not compile without it. – Ryno Jul 02 '18 at 06:26
  • I'm just trying to create an account quickly – Ryno Jul 02 '18 at 08:19
  • @Dennis, is this helpful in any way [link](https://github.com/Ryno001/Databse/tree/master)? – Ryno Jul 02 '18 at 08:28
  • Yeah, but can u upload the whole application code? I would like to run it on my system. – Daksh Gargas Jul 02 '18 at 08:38
  • I added a zip folder as I didn't know how to do it any other way. Is it acceptable? – Ryno Jul 02 '18 at 08:45
  • Yeah, but you should learn how to create add your code to github. https://stackoverflow.com/questions/37093723/how-to-add-an-android-studio-project-to-github – Daksh Gargas Jul 02 '18 at 08:49
  • Anyway, I'm currently in my office, I'll get back to you in few hours. – Daksh Gargas Jul 02 '18 at 08:50
  • @Dennis, How would I find my id of the row (containing the name, port and Ip address) after creating the ListView? I assume that when the listview is created with the ArrayAdapter that the id of each entry will be re-assigned, I am really struggling to think of a way of overcoming this or extracting the **id** (`COL_ID`) from the database and using that to do all the manipulation from the selected (longclicked) listview items. – Ryno Jul 02 '18 at 14:26
  • I'll update your github code in a while. Just give me a moment. :) – Daksh Gargas Jul 02 '18 at 14:45
  • Hi, can you tell me what kind of input will you me entering. Please post it inside ListView.java file as comment at the bottom of the class. I guess I have fixed your issue. – Daksh Gargas Jul 02 '18 at 15:27
  • Sorry for the late reply, I have added the comment in the ListView class. I hope it is what you require. Thank you so much for all your help Dennis. I have been stuck with this for close to a week and a half. – Ryno Jul 03 '18 at 05:45
  • Will have a look. :) – Daksh Gargas Jul 03 '18 at 05:45
  • Hi, can you email me at dakshg18@gmail.com? – Daksh Gargas Jul 04 '18 at 05:42