I have a very strange situation. I am using Contextual Action Mode for selecting multiple items of the ListView. The flow goes as follows:
User selects the list items using long press on them --> Uses the action item "Operations" to choose what he wants to do --> This action item creates a AlertDialog with 4 list items (call it dialog1) where the 3rd item calls another AlertDialog (call it dialog2) which includes an EditText for some data input and later calls a method to perform it.
Later the user hits Back button or Home button to exit the Action Mode.
The problem is that dialog2 shows up alternatively like first time user selects the list items, Chooses "Operations" action item and chooses the 3rd item which calls dialog2. Now dialog2 will appear as it is supposed to. Later the user hits the Back button to quit the Action Mode.
The SECOND TIME user performs the same steps dialog2 doesn't appear.
The logcat shows this error in both the cases:
09-04 10:53:12.096 6299-6299/com.project.pcmanager
W/InputEventReceiver: Attempted to finish an input event but the input
event receiver has already been disposed.
Some code:
public void sendAction(final Context context, final EventModel model, int position) {
JSONObject object = new JSONObject();
String[] operations = getResources().getStringArray(R.array.operations);
// null set before is modified here
model.setEventTitle(operations[position]);
final String ip = model.getEventIP();
switch (position) {
case 0:
try {
object.put("command", "power_off");
notifyUser();
LogUtils.addEntry(model.toString());
execCommand(ip,object);
} catch (JSONException e) {
e.printStackTrace();
}
break;
case 1:
try {
object.put("command", "reboot");
notifyUser();
LogUtils.addEntry(model.toString());
execCommand(ip,object);
} catch (JSONException e) {
e.printStackTrace();
}
break;
case 2:
//Show AlertDialog with EditText on it for command input
final EditText txtCommand = new EditText(context);
// Set some properties to EditText
txtCommand.setPadding(16, 16, 16, 16);
txtCommand.setMinHeight(150);
txtCommand.setHint("Ex: ping google.com");
txtCommand.setSingleLine();
new AlertDialog.Builder(context)
.setTitle("Run a task")
.setView(txtCommand)
.setCancelable(false)
.setPositiveButton("Run",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String command = txtCommand.getText().toString();
if (command.length() > 0) {
JSONObject object = new JSONObject();
try {
object.put("run", command);
object.put("ip", ip);
notifyUser();
LogUtils.addEntry(model.toString());
performRemoteExec(object);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(context, "Please provide a command first!", Toast.LENGTH_SHORT).show();
}
}
}).setNeutralButton("Cancel", null).show();
break;
case 3:
notifyUser();
LogUtils.addEntry(model.toString());
getScreenshot(ip);
break;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
listView.setAdapter(adapter);
listView.setEmptyView(emptyView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
//Change the title bar with the items selected
mode.setTitle(listView.getCheckedItemCount() + " selected");
//select the clicked item
adapter.toggleSelection(position);
}
/**
* Called when action mode is first created.
* The menu supplied will be used to generate action buttons for the action mode.
* #param mode ActionMode being created
* #param menu Menu used to populate action buttons
* #return true if the action mode should be created,
* false if entering this mode should be aborted.
*/
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
onContextMode = true;
mode.getMenuInflater().inflate(R.menu.menu_client_select_main, menu);
return true;
}
/**
* Called to refresh an action mode's action menu whenever it is invalidated.
* #return true if the menu or action mode was updated, false otherwise.
*/
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
/**
* Called to report a user click on an action button.
* #return true if this callback handled the event,
* false if the standard MenuItem invocation should continue.
*/
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_operations) {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setItems(R.array.operations, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
SparseBooleanArray selectedIds = adapter.getSelectedIds();
// traverse the array to find chosen clients
for (int i = 0; i < selectedIds.size(); i++) {
if (selectedIds.get(i)) {
ClientModel item = adapter.getItem(i);
String ip = item.getClientIP();
String os = item.getOSType();
// null will be treated soon
EventModel model = new EventModel(ip, null, os);
sendAction(builder.getContext(),model, which);
}
}
}
});
builder.show();
}
return true;
}
/**
* Called when an action mode is about to be exited and destroyed.
*/
#Override
public void onDestroyActionMode(ActionMode mode) {
onContextMode = false;
}
});
}
Ok so I figured the problem myself. It turns out the culprit was me using SparseBooleanArray to get selected clients and I was wrong.
In my code it was:
SparseBooleanArray selectedIds = adapter.getSelectedIds();
So, I removed this SparseBooleanArray with a new implementation technique. I used ArrayList<ClientMode> selectedItems to store all the selected models in my Adapter class.
Also, I created a simple method called clearSelections that calls selectedItems.clear() method in it. I call this method at on onDestroyActionMode as per my app requirement.
HOW I FOUND THIS?
I simply placed a bunch of System.out.println statements all around onCreate and sendAction to find out the culprit.
Related
I am using SingleChoiceItems in ActionBar using DialogBuilder. I need to save the item selected even after exiting the application then restore the saved setting when accessing the application again.
I saw many examples of shared preferences and onRestoreInstanceState() and onSaveInstanceState() but I am quite confused. Below is the code with explanations of what I did.
Dialog Builder
I saved the present state of the selected option in - > selectPosition .. Then saving the selectedPosition in the global variable isChecked and setting it to the SelectSingleChoice arguments.
public void displaySortDialog(final Context context) {
int selection = context.getSharedPreferences(PREF_NAME,
Context.MODE_MULTI_PROCESS).getInt("Selection_key", 0);
Toast.makeText(getApplicationContext(), "Start Sel :"+selection , Toast.LENGTH_SHORT).show();
CharSequence[] sort_options = { "Z-A", "A-Z", "Size" };
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.sort_apps));
builder.setSingleChoiceItems(sort_options, selection,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int selected_sort) {
/*
* Toast.makeText(getApplicationContext(),
* sort_options[selected_sort], Toast.LENGTH_SHORT)
* .show(); // isChecked = restoredChecked;
*/
}
});
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// saving
context.getSharedPreferences(PREF_NAME,
Context.MODE_MULTI_PROCESS).edit()
.putInt("Selection_key", id ).commit();
Toast.makeText(getApplicationContext(), "Choosen :"+id, Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.create().show();
}
Declaring and using the displaySortDialog funtion
public boolean onOptionsItemSelected(MenuItem item) {
boolean result = true;
result = menuChoice(item);
switch (item.getItemId()) {
case R.id.menu_Sort_By_Size: {
displaySortDialog(getBaseContext());
break;
}
case R.id.menu_Action_Search: {
// openSearch();
break;
}
default: {
result = super.onOptionsItemSelected(item);
break;
}
}
return result;
}
Using the below code when I long press the home button or press the home button from the application the selected setting seems OK. They are selected and saved as I toast the message to make sure they are selected which means onSaveInstanceState is working because the toast message in onSaveInstanceState is displayed. But when I try to restore the settings saved through onRestoreInstanceState() then it doesn't work. After exiting the application the settings go back to default.
public void onRestoreInstanceState(Bundle savedInstanceState) {
if(savedInstanceState != null){
isChecked = savedInstanceState.getInt("SELECTED_SORT_ITEM");
Toast.makeText(getApplicationContext(), "RESTORED: "+isChecked, Toast.LENGTH_SHORT).show();
}
}
public void onSaveInstanceState(Bundle savedInstanceState) {
//outState.putInt(SELECTED_SORT_ITEM, getActionBar().getSelectedNavigationIndex());
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt(SELECTED_SORT_ITEM, isChecked);
Toast.makeText(getApplicationContext(), SELECTED_SORT_ITEM+isChecked, Toast.LENGTH_SHORT).show();
}
The toast OnSaveInstanceRestore is shown when I press the home button from the app or long press the home button and again select the app. But after exiting the app I am unable to restore the selected settings.
If you can help me with these methods or know some other method it would be appreciated.
Use shared preference,
like:
// For saving
context.getSharedPreferences(PREF_NAME,Context.MODE_MULTI_PROCESS)
.edit()
.put("Selection_key",selectedPosition)
.commit();
//For retrieve
int selection = context.getSharedPreferences(PREF_NAME,Context.MODE_MULTI_PROCESS)
.getInt("Selection_key",0); // 0 being default selection value, put whatever u want
// int selection, Use this Selection for your UI
i know this question has been asked a couple of times before and i tried all of the suggestions there and i still cant refresh my list view after i add a new item to the list
can anyone please try to explain how can i do it?
thnaks
this is the code of the adding:
public class MainActivity extends ListActivity {
private DBHandler dataBase;
private ArrayList<Movies> list;
private ArrayAdapter<Movies> adapter;
private ListView lv;
private ImageButton addMovie;
private Intent intent;
final static int FLAG_FOR_ADDING=1;
final static int FLAG_FOR_EDITING=2;
final static int FLAG_FROM_MENU=3;
private int selected_movie;
private String the_movie;
private String movie_title;
private String movie_description;
private String movie_url;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
dataBase = new DBHandler(MainActivity.this);
// by pressing this button the user will get instructions about how to use this application
Button start = (Button)findViewById(R.id.how_to_start);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(MainActivity.this, "Press the plus button for adding a movie or the menu button for the menu", Toast.LENGTH_LONG).show();
}
});
// by pressing this button, the menu of this application will open
ImageButton menu = (ImageButton)findViewById(R.id.menu_context);
menu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openOptionsMenu();
}
});
addMovie = (ImageButton)findViewById(R.id.add_movie);
addMovie.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
registerForContextMenu(addMovie);
openContextMenu(addMovie);
}
});
// the array list is getting the movies from the database
list = dataBase.getAllMovies();
// here i am setting the adapter that will handle the list
adapter = new ArrayAdapter<Movies>(MainActivity.this, R.layout.row,list);
// i am getting a default xml
lv=getListView();
// i am connecting between the list and the adapter
lv.setAdapter(adapter);
// by short pressing an item on the list the user will move to the edit_a_movie page
// in order to edit the movie
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
intent = new Intent(MainActivity.this,Edit_A_Movie.class);
// i am sending the information of the item that been pressed to the edit_a_movie page
// the id, title,description and the url_photo
intent.putExtra("item_id", list.get(position).getId());
intent.putExtra("item_title", list.get(position).getTitle().toString());
intent.putExtra("item_description", list.get(position).getDescription().toString());
intent.putExtra("item_url", list.get(position).getPhoto_url().toString());
startActivityForResult(intent, FLAG_FOR_EDITING);
}
});
// a long press on a movie in the list will open a context menu for deleting or editing the item
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
// i am getting the information of the movie that was pressed
selected_movie = list.get(position).getId();
the_movie = String.valueOf(selected_movie);
movie_title = list.get(position).getTitle().toString();
movie_description = list.get(position).getDescription().toString();
movie_url = list.get(position).getPhoto_url().toString();
// i register to a context menu
registerForContextMenu(lv);
openContextMenu(lv);
return true;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
// by pressing the exit option, the user will exit the application
case R.id.menu_exit:
finish();
android.os.Process.killProcess(android.os.Process.myPid());
super.onDestroy();
break;
// this option will delete all the movies from the list
case R.id.menu_delete:
dataBase.deleteAllMovies();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// if the user will press the menu button he will get the menu and if he will press
// the plus button he will get 2 options: 1. move to the edit a movie page
// 2. move to the search a movie from the Internet page
// if the user will press a long press on a movie he will get 2 options:
//1. update the movie
//2. delete the movie
if(v.getId() == R.id.menu_context){
getMenuInflater().inflate(R.menu.main, menu);
}
else if (v.getId() == R.id.add_movie){
getMenuInflater().inflate(R.menu.aad_menu, menu);
}
else {
getMenuInflater().inflate(R.menu.edit_or_delete, menu);
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()){
// selecting this option will exit the application
case R.id.menu_exit:
finish();
android.os.Process.killProcess(android.os.Process.myPid());
super.onDestroy();
break;
// this option will delete all the movies from the list
case R.id.menu_delete:
dataBase.deleteAllMovies();
break;
// this option will move the user to the edit a movie page
case R.id.move_to_edit:
intent = new Intent(MainActivity.this,Edit_A_Movie.class);
startActivityForResult(intent, FLAG_FOR_ADDING);
break;
// this option will get the user move to the add a movie from the Internet page
case R.id.move_to_search:
break;
// if the user will press on a movie he will be able to update the movie or delete it
//this option will delete the movie
case R.id.delete_menu_movie:
dataBase.deleteMovie(the_movie);
break;
// this option will move the user to the edit_a_movie page
case R.id.edit_menu_movie:
intent = new Intent(MainActivity.this,Edit_A_Movie.class);
// i am sending the information of the pressed movie
intent.putExtra("item_id",selected_movie);
intent.putExtra("item_title", movie_title);
intent.putExtra("item_description", movie_description);
intent.putExtra("item_url", movie_url);
startActivityForResult(intent, FLAG_FROM_MENU);
break;
default:
break;
}
return super.onContextItemSelected(item);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
// this is the info i am getting from the edit_a_movie page in order to put it in the database
// i am using it to add a new movie to the list
if(requestCode==FLAG_FOR_ADDING && resultCode==RESULT_OK){
// this is the info i received
String title_from_adding = data.getStringExtra("user_title");
String description_from_adding = data.getStringExtra("user_desciption");
String url_from_adding = data.getStringExtra("user_url");
// here i am putting the info in the database
dataBase.addMovie(title_from_adding, description_from_adding, url_from_adding);
// in case that the user pressed the cancel button he will get a massage
} else if
(requestCode==FLAG_FOR_ADDING && resultCode==RESULT_CANCELED){
Toast.makeText(MainActivity.this, "No movie has been added", Toast.LENGTH_LONG).show();
}
// i am using the info from the edit_a_movie page in order to update a movie
else if
(requestCode==FLAG_FOR_EDITING && resultCode==RESULT_OK ){
String position_from_editing = data.getStringExtra("position");
String title_from_editing = data.getStringExtra("user_title");
String description_from_editing = data.getStringExtra("user_desciption");
String url_from_editing = data.getStringExtra("user_url");
// the database is being updating
dataBase.updateMovie(position_from_editing, title_from_editing, description_from_editing, url_from_editing);
}
// this case is for editing the movie that was long pressed
else if
(requestCode==FLAG_FROM_MENU && resultCode==RESULT_OK){
// i am receiving the updated information from the edit_a_movie page
String position_from_menu = data.getStringExtra("position");
String title_from_menu = data.getStringExtra("user_title");
String description_from_menu = data.getStringExtra("user_desciption");
String url_from_menu = data.getStringExtra("user_url");
//the database is being updating with the new information
dataBase.updateMovie(position_from_menu, title_from_menu, description_from_menu, url_from_menu);
}
}
}
You should call notifyDataSetChanged on the adapter.
After dataBase.addMovie(..)
adapter.notifyDataSetChanged();
I am using StandOutWindow library.
In my Setting screen,I have a switch (turn on/off). If I turn on switch, a popup and a notification are displayed.
When I turn off switch, popup isn't display.
I wanna, when I click on notification, popup is hidden and switch has "OFF" status. Now,I only do popup is hidden. Switch also has "ON" status. How to I can turn off switch.
I tried write code in getPersistentNotificationIntent but can not.
Here is my code:
public class TogglePopup extends StandOutWindow {
public View view;
#Override
public String getAppName() {
return "JSDict";
}
#Override
public int getAppIcon() {
return android.R.drawable.ic_menu_close_clear_cancel;
}
#SuppressLint("NewApi")
#Override
public void createAndAttachView(int id, final FrameLayout frame) {
// create a new layout from body.xml
final LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.popup_toggle, frame, true);
ToggleButton toggle = (ToggleButton) view
.findViewById(R.id.toggle_popup);
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
LinearLayout viewLinear = (LinearLayout) view
.findViewById(R.id.toggle_popup_background);
if (isChecked) {
// The toggle is enabled
viewLinear
.setBackgroundResource(R.drawable.popup_toggle_on);
ComponentName service = getApplicationContext()
.startService(
new Intent(getApplicationContext(),
ClipboardMonitor.class));
StandOutWindow.closeAll(getApplicationContext(),
ClipboardMonitor.class);
StandOutWindow.show(getApplicationContext(),
ClipboardMonitor.class, StandOutWindow.DEFAULT_ID);
} else {
// The toggle is disabled
viewLinear
.setBackgroundResource(R.drawable.popup_toggle_off);
getApplicationContext().stopService(
new Intent(getApplicationContext(),
ClipboardMonitor.class));
StandOutWindow.closeAll(getApplicationContext(),
ClipboardMonitor.class);
}
}
});
}
// the window will be centered
#Override
public StandOutLayoutParams getParams(int id, Window window) {
return new StandOutLayoutParams(id, 250, 300,
StandOutLayoutParams.CENTER, StandOutLayoutParams.CENTER);
}
// move the window by dragging the view
#Override
public int getFlags(int id) {
return super.getFlags(id) | StandOutFlags.FLAG_BODY_MOVE_ENABLE
| StandOutFlags.FLAG_WINDOW_FOCUSABLE_DISABLE;
}
#Override
public String getPersistentNotificationMessage(int id) {
return "Click to close the JSDict";
}
#Override
public Intent getPersistentNotificationIntent(int id) {
return StandOutWindow.getCloseIntent(this, TogglePopup.class, id);
/*
* StandOutWindow.show(this, WidgetsWindow.class,
* StandOutWindow.DEFAULT_ID);
*/
}
}
There needs to be a single persistent notification for the StandOut service, or else android will kill your service on low memory (which happens every 5 seconds). You are mistaken about the fact that there is a new persistent notification for each new window. Unless you have multiple types, you will only have one persistent notification no matter how many windows the user opens. If multiple types are an issue, look at FloatingFolders for how to implement multiple types in a single service.
When implementing setMultiChoiceItems with a cursor, you have to specify an isCheckedColumn.
The problem, as articulated on other sites, is that when users select an item from the list the checkbox does not update. Some have suggested updating the SqLite table each time a user selects an item, but this did not work in my application. Here is the solution I came up with.
This is what I came up with:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int myDialogChoice = getArguments().getInt("whichDialog");
mSelectedItems = new ArrayList(); // Where we track the selected items
mCurrentFavoritesSelection = new ArrayList();
myDataBaseAdapter = new AthleteDbAdapter(getActivity());
// int myAthleteId;
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
switch(myDialogChoice) {
case Select_From_Favorites:
myCursorFromSqLite = myDataBaseAdapter.fetchAllFavorites(getActivity());
// You need a Primative Boolean Array to specify which items were selected last time.
boolean[] booleanPrimativeArray = new boolean[myCursorFromSqLite.getCount()];
final ArrayList mArrayListOfIDs = new ArrayList();
ArrayList<Boolean> myBooleanList = new ArrayList<Boolean>();
// This array will be the choices that appear in the Dialog.
ArrayList<String> mArrayListOfNames = new ArrayList<String>();
myCursorFromSqLite.moveToFirst();
/* Populate Arrays
*
*/
int iCount = 0;
while(!myCursorFromSqLite.isAfterLast()) {
// put _id's from SqLite data into an array.
mArrayListOfIDs.add(Integer.valueOf(
myCursorFromSqLite.getString(myCursorFromSqLite.getColumnIndex(KEY_ROWID))));
// put series of booleans into Primative Array depending upon whether user selected them last time.
if(Integer.valueOf(myCursorFromSqLite.getString(myCursorFromSqLite.getColumnIndex("checked"))) == 1){
booleanPrimativeArray[iCount] = true;
mSelectedItems.add(
Integer.valueOf(myCursorFromSqLite.getString(myCursorFromSqLite.getColumnIndex(KEY_ROWID)))
);
// I kept track of what selections from last time were.
mCurrentFavoritesSelection.add(
Integer.valueOf(myCursorFromSqLite.getString(myCursorFromSqLite.getColumnIndex(KEY_ROWID)))
);
} else booleanPrimativeArray[iCount] = false;
iCount++;
mArrayListOfNames.add(myCursorFromSqLite.getString(myCursorFromSqLite.getColumnIndex("fullName")));
myCursorFromSqLite.moveToNext();
}
// Change the ArrayList of names to a Char Sequence
CharSequence[] charSeqOfNames = mArrayListOfNames.toArray(new CharSequence[mArrayListOfNames.size()]);
try{
myCursorFromSqLite.close();
} catch (Throwable t) {
Log.e(APP_TAG,"Error closing myCursorFromSqLite Cursor " + t);
}
builder.setTitle(R.string.pick_athletes)
.setMultiChoiceItems(charSeqOfNames, booleanPrimativeArray,
new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
if (isChecked) {
// If the user checked the item, build an array containing the selected items _id's.
mSelectedItems.add((Integer) mArrayListOfIDs.get(which));
} else if (mSelectedItems.contains((Integer) mArrayListOfIDs.get(which))) {
// Else, if the user changes his mind and de-selects an item, remove it
mSelectedItems.remove((Integer) mArrayListOfIDs.get(which));
}
}
})
// Set the action buttons
.setPositiveButton(R.string.pullathletesbutton, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// User clicked OK, so save the mSelectedItems results somewhere
// or return them to the component that opened the dialog
Log.d(APP_TAG,"Call something");
mListener.onDialogPositiveClick(PickListDialog.this, mSelectedItems, mCurrentFavoritesSelection);
}
})
.setNegativeButton(R.string.cancelbutton, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
}
});
This worked well. The user can change his mind without affecting the underlying database and the checkmarks update properly. Once the user has finalized his choices, he hits the "positive" button and the database is updated.
When selected, a context menu option brings up an AlertDialog. I want the user to enter text into an EditText in the AlertDialog, and when the user presses PositiveButton, the value of EditText is able to be "returned" to the main method. Here is the relevant code from my class:
public class PassPlay extends ListActivity {
public static final int PENALTY_ID = Menu.FIRST+1;
public static final int FUMBLE_ID = Menu.FIRST+2;
public static final int ADDLYDS_ID = Menu.FIRST+3;
public static final int SAFETY_ID = Menu.FIRST+4;
EditText ydsFromAlertDialog;
String penYdsStr;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.passplay);
ydsFromAlertDialog=(EditText)findViewById(R.id.passYdsLabel);
registerForContextMenu(getListView());
}
public boolean onCreateOptionsMenu(Menu menu) {
populateMenu(menu);
return(super.onCreateOptionsMenu(menu));
}
public boolean onOptionsItemSelected(MenuItem item) {
return(applyMenuChoice(item) || super.onOptionsItemSelected(item));
}
public boolean onContextItemSelected(MenuItem item) {
return(applyMenuChoice(item) || super.onContextItemSelected(item));
}
private void populateMenu(Menu menu) {
menu.add(Menu.NONE, PENALTY_ID, Menu.NONE, "Penalty");
menu.add(Menu.NONE, FUMBLE_ID, Menu.NONE, "Fumble");
menu.add(Menu.NONE, ADDLYDS_ID, Menu.NONE, "Additional Yards");
menu.add(Menu.NONE, SAFETY_ID, Menu.NONE, "Safety");
}
private boolean applyMenuChoice(MenuItem item) {
LayoutInflater factory = LayoutInflater.from(this);
final View textEntryView;
switch (item.getItemId()) {
case PENALTY_ID:
textEntryView = factory.inflate(R.layout.textdialog, null);
new AlertDialog.Builder(this)
.setView(textEntryView)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.timeout)
.setPositiveButton(R.string.offense, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Actions for offensive timeout
EditText penaltyYds=(EditText)findViewById(R.id.ydsAssessedLabel);
penYdsStr = penaltyYds.getText().toString();
ydsFromAlertDialog.setText(penYdsStr);
}
})
.setNeutralButton(R.string.defense, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Actions for defensive timeout
}
})
.setNegativeButton(R.string.cancel, null)
.show();
return true;
case FUMBLE_ID:
//Fumble window
return true;
case ADDLYDS_ID:
//Additional Yards window
return true;
case SAFETY_ID:
//Safety window
return true;
}
return(false);
}
}
The main XML layout (passplay.xml) has your normal TextViews, EditTexts, CheckBoxes, etc. I want to set one of those EditTexts (ydsFromAlertDialog) to be assigned the value entered in the AlertDialog (EditText penaltyYds). The AlertDialog's XML layout (textdialog.xml) is very simple with one TextView and one EditText.
When I run the program, the following line errors out with "The application has stopped unexpectedly."
penYdsStr = penaltyYds.getText().toString();
So in summary, I want to press the menu option "Penalty", have an AlertDialog with an EditText where I enter a number, and when I press PositiveButton, the EditText ydsFromAlertDialog's value is changed to what was entered in the Dialog.
In reality, I have a database table with 5 columns, 4 of which will be populated by normal fields, but the 5th will be populated by the value entered in the Dialog. I figured if I can "return" it to "be with" the rest of the values, I'll be able to save it to same table record as the others, too.
Let me know if you need any more information. Thank you!
You have to get the ydsAssessedLabel from the view you inflated
EditText penaltyYds=(EditText)textEntryView.findViewById(R.id.ydsAssessedLabel);