Search code examples
javaandroidinner-classeslistactivityanonymous-class

Why aren't my results being added the first time?


I am trying to make an app that must use a ListActivity and populate the list with bookmarks that a user may add.

A "Add Bookmark" option is listed in the app menu, and when selected it calls 3 "show dialog" functions which prompt the user to fill 3 string variables (title, url, and note).

After receiving input I want it to call addBookmark() which will add the strings to a Bookmark class object and then add the object to the list via an ArrayAdapter.

As of now, when I compile and click the Add Bookmark button under menu, the app seems to run out of order and immediatly populates the list with the text I used to initialize the strings, and doesn't add the users input until the button is clicked a second time. My expected output is to not display anything the first time the Add Bookmark button is clicked, and to output the users input as soon as they finish typing and adding it themselves. My code is below

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.InputType;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.EditText;

import java.util.ArrayList;


public class BookNote extends ListActivity{

private ArrayAdapter<Bookmark> adapter;
private String title = "Example Title",url = "www.ExampleURL.com",note = "Example Note about Website";

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

    ArrayList<Bookmark> bookmarkList = new ArrayList<>();
    adapter = new ArrayAdapter<Bookmark>(this,android.R.layout.simple_list_item_1,bookmarkList);
    setListAdapter(adapter);
}

//Show dialog and editText for user to assign title to bookmark.
public void showTitleDialog(){
    AlertDialog.Builder titleBuilder = new AlertDialog.Builder(this);
    titleBuilder.setTitle("Enter Title");

    final EditText titleET = new EditText(this);
    titleET.setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
    titleBuilder.setView(titleET);
    titleBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int i) {
             title = titleET.getText().toString();
        }
    });
    titleBuilder.show();
}

//Show dialog and editText for user to assign url to bookmark.
public void showURLDialog(){
    AlertDialog.Builder urlBuilder = new AlertDialog.Builder(this);
    urlBuilder.setTitle("Enter URL");

    final EditText urlET = new EditText(this);
    urlET.setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
    urlBuilder.setView(urlET);

    urlBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int i) {
            url = urlET.getText().toString();
        }
    });
    urlBuilder.show();
}

//Show dialog and editText for user to assign note to bookmark.
public void showNoteDialog(){
    AlertDialog.Builder noteBuilder = new AlertDialog.Builder(this);
    noteBuilder.setTitle("Enter Note");

    final EditText noteET = new EditText(this);
    noteET.setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
    noteBuilder.setView(noteET);

    noteBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            note = noteET.getText().toString();
        }
    });

    noteBuilder.show();
}

//Create new bookmark object filled with user entries and add to ArrayAdapter.
private void addBookmark(){
    Bookmark bookmark = new Bookmark(title,url,note);
    adapter.add(bookmark);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_book_note, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_add) {
        showTitleDialog();
        showURLDialog();
        showNoteDialog();
        addBookmark();
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

Solution

  • I believe that what is happening is that your opOptionsItemSelected() method is executing these lines of code:

        //noinspection SimplifiableIfStatement
    if (id == R.id.action_add) {
        showTitleDialog();
        showURLDialog();
        showNoteDialog();
        addBookmark();
        return true;
    }
    

    You seem to expect that the app will wait until after the dialogs are dismissed before moving onto the addBookmark() method. It won't. The app will show each dialog, and then execute addBookmark() immediately.

    You have onClick listeners defined in each of your dialogs. You should place your addBookmark() method in one of those so that it executes after the user has entered their information.

    I would also suggest making it one dialog. Three dialogs can be annoying. What happens if the user cancels during the first or second dialog?