Android App crashes when I try to capture from EditText - android

So I am trying to make a contact form in an Alert Dialogue box which opens from a menu option. I have 3 EditText fields in my form and in my Main.java I read from those fields when the Send button in form is pressed and then I start an Email intent, or at least thats what it is supposed to do. Right now the app crashes as soon as I press the send button. Now I have troubleshooted the problem and it doesnt seem to be in the intent but it occurs when I read from the EditText fields. The code works fine when I take out the EditText reading part and just put filler information in its place, but I need this to work with the EditTexts. Thank you.
My whole code for the option in the menu:
case R.id.menu_feedback:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.menu_feedback);
LayoutInflater inflater = this.getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(inflater.inflate(R.layout.feedback, null));
// Add the buttons
builder.setNegativeButton(R.string.send, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User clicked OK button
final EditText nameField = (EditText) findViewById(R.id.EditTextName);
String name = nameField.getText().toString();
final EditText emailField = (EditText) findViewById(R.id.EditTextEmail);
String email = emailField.getText().toString();
final EditText feedbackField = (EditText) findViewById(R.id.EditTextFeedbackBody);
String feedback = feedbackField.getText().toString();
final CheckBox responseCheckbox = (CheckBox) findViewById(R.id.CheckBoxResponse);
boolean bRequiresResponse = responseCheckbox.isChecked();
/* Create the Intent */
final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
/* Fill it with Data */
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, R.string.send_email);
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, feedback);
/* Send it off to the Activity-Chooser */
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
dialog.dismiss();
}
});
builder.setPositiveButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
// create alert dialog
AlertDialog alertDialog = builder.create();
// show it
alertDialog.show();
return true;

Ok, I assume your all EditTexts are written in feedback layout file for AlertDialog,
View dialogView = inflater.inflate(R.layout.feedback, null);
builder.setView(dialogView );
And Edittext are like,
// User clicked OK button
final EditText nameField = (EditText) dialogView.findViewById(R.id.EditTextName);
String name = nameField.getText().toString();
final EditText emailField = (EditText) dialogView.findViewById(R.id.EditTextEmail);
String email = emailField.getText().toString();
final EditText feedbackField = (EditText) dialogView.findViewById(R.id.EditTextFeedbackBody);
String feedback = feedbackField.getText().toString();
Actually, when you are inflating any view and you have to use child views of that views then you have to use the reference of that view and findViewById() method. So in your case, dialogView.findViewById();

use builder or inflater instances for Accessing EditText or other views from AlertDialog as :
builder.setNegativeButton(R.string.send, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User clicked OK button
final EditText nameField = (EditText)inflater. findViewById(R.id.EditTextName);
String name = nameField.getText().toString();
final EditText emailField = (EditText)inflater.
findViewById(R.id.EditTextEmail);
String email = emailField.getText().toString();
final EditText feedbackField = (EditText)inflater.
findViewById(R.id.EditTextFeedbackBody);
String feedback = feedbackField.getText().toString();
// your code here..

Related

Android- Help fixing Custom Alert Dialog with EditText

Context: There is a custom Listview and each list item has a button in it. When you click the button an alertDialog appears with an edit text and submit button. This only happens on the first click, on subsequent clicks a Toast will simply appear with the number of times it has been clicked thus far.
When you click the submit button a toast will appear displaying the text that was entered into the editText and the number of times they have clicked on it which will presumably always be 1 since this can only happen on the first click.
Problem: The timesClicked counter is not working properly if the user so much as clicks on the editText before clicking submit. It is restting to 0 I guess. However if the user does not click on the editText then the program works normally. 0_o I'm at a loss.
Attempts at solving: I simplified the code down quite a bit to try and pinpoint the problem and this is where I am stuck. Originally I was inflating a view that only had an edit text and then I was just using builder.setPositiveButtton. I thought implementing the buttons directly in the view would fix it but that doesn't seem to be the case. I have been stuck on this for awhile. Any help would be great
Here is a video of the bug happening
private class OnSubtractClickListener implements View.OnClickListener {
final int id; //id of list item that was clicked
int timesClicked;
Toast toast;
public OnSubtractClickListener(int id, View view) {
super();
this.id = id;
timesClicked = 0;
}
#Override
public void onClick(View view) {
if (timesClicked != 0) {
toast.setText(Integer.toString(timesClicked));
toast.show();
}
else{
toast = Toast.makeText(view.getContext(), "", Toast.LENGTH_SHORT);
final View dialogView = LayoutInflater.from(view.getContext()).inflate(R.layout.dialog_add_notes, null);
AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
builder.setView(dialogView);
builder.setTitle("Subtract cigar?");
builder.setIcon(R.mipmap.monkey_launcher);
final AlertDialog dialog = builder.create();
Button yesButton = (Button)dialogView.findViewById(R.id.dialog_notes_yes_button);
yesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText editText = (EditText)dialogView.findViewById(R.id.dialog_editText);
String userInput = editText.getText().toString();
String timesClickedString = Integer.toString(++timesClicked);
toast.setText(timesClickedString + ": " + userInput);
toast.show();
dialog.dismiss();
}
});
dialog.show(); //new
}
}
}
You can make class that extend Dialog.
example:
public class CustomDialog extends Dialog {
private EditText editText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowManager.LayoutParams lpWindow = new WindowManager.LayoutParams();
lpWindow.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
lpWindow.dimAmount = 0.8f;
getWindow().setAttributes(lpWindow);
setContentView(R.layout.activity_custom_dialog);
editText = (EditText) findViewById(R.id.editText);
}
}
You can use this dialog..
mCustomDialog = new CustomDialog();
mCustomDialog.show();
You can make the layout as you wish.
======================================================================
You can use AlertDialog.Builder.setPositiveButton.
site : setPositiveButton
example...
toast = Toast.makeText(view.getContext(), "", Toast.LENGTH_SHORT);
final View dialogView = LayoutInflater.from(view.getContext()).inflate(R.layout.dialog_add_notes, null);
AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
builder.setView(dialogView);
builder.setTitle("Subtract cigar?");
builder.setIcon(R.mipmap.monkey_launcher);
builder.setPositiveButton("text", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int which) {
EditText editText = (EditText)dialogView.findViewById(R.id.dialog_editText);
String userInput = editText.getText().toString();
String timesClickedString = Integer.toString(++timesClicked);
toast.setText(timesClickedString + ": " + userInput);
toast.show();
}
});
final AlertDialog dialog = builder.create();
dialog.show(); //new
I found the solution. Basically what was happening was that when the Keyboard appeared it would cause the listview to adjust the size recreating the whole listview with recycled/old versions of the list items from before the dialog appeared -effectively undoing any changes made to the ListView items by the dialog.
In your listview XML add this:
android:descendantFocusability="beforeDescendants"
In Mainfest.xml:
<activity android:name= ".yourActivity"
android:windowSoftInputMode="adjustPan"/>

Populate List<String> with AlertDialog Input

Building my first app and can't find a solution by myself.
What my app does:
MainActivity prompts user to input player amount
presses Ok, input passed to next activity
now I want, that the user is prompted to input the player names, one by one with an AlertDialog. Those names, should be stored in an Array.
My code so far:
public class MainScreen extends AppCompatActivity {
private static final String TAG = MainScreen.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
try {
Intent intent = getIntent();
final int sumPlayers = getIntent().getIntExtra("sumPlayers", 0);
final List<String> playerNames = new ArrayList<>();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
final EditText input = new EditText(getBaseContext());
input.setTextColor(Color.BLACK);
//input.setSingleLine();
for (int c=0; c<sumPlayers; c++) {
builder.setTitle("Input Player Name");
builder.setView(input);
builder.setPositiveButton("ADD", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
playerNames.add(input.getText().toString());
}
});
builder.show();
}
ArrayAdapter<String> playerAdapter = new ArrayAdapter<String>(this, R.layout.player_list_item, R.id.editText, playerNames);
ListView listView = (ListView) findViewById(R.id.listView_main);
listView.setAdapter(playerAdapter);
} catch (Exception e) {
System.out.println("2te Act");
Log.e(TAG, "Error#: ", e);
}
}
}
I get this Exception # builder.show();
Java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
It's working without the for loop except one minor problem.
When I set the input field to setSingleLine(); the listView stays empty.
You are creating a single AlertDialog.Builder and repeatedly setting the title, view, and positive button with different values. You likely need to move this logic inside the for loop:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
final EditText input = new EditText(getBaseContext());
input.setTextColor(Color.BLACK);
//input.setSingleLine();

EditText getText() returns empty string

I have an activity with a button, when the user clicks on the button, an AlertDialog appear with 2 EditText where you put email and password to login.
When I try to get the text from the EditText i always get only empty strings.
The layout login_alert is the layout of the AlertDialog.
Here the code:
View view = getLayoutInflater().inflate(R.layout.login_alert, null, false);
String email = ((EditText) view.findViewById(R.id.emailEditText)).getText().toString();
String password = ((EditText) view.findViewById(R.id.passwordEditText)).getText().toString();
System.out.println("DEBUG: "+email+", "+password); // Empty strings
EDIT:
Activity code:
public class MainActivity extends FragmentActivity {
public static final String mAPP_ID = "...";
public static final String USER_DB_URL = "...";
AssetsExtracter mTask;
private MainFragment mainFragment;
private List<User> usersList = new ArrayList<User>();
private User currentUser = null;
private Button labLoginButton;
private EditText emailET;
private EditText passwordET;
private ProgressDialog dialog;
private View alertView; /* THIS IS THE SOLUTION */
boolean userIsLogged = false;
static {
IMetaioSDKAndroid.loadNativeLibs();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_main);
/*View view = getLayoutInflater().inflate(R.layout.login_alert, null, false); BEFORE*/
alertView = getLayoutInflater().inflate(R.layout.login_alert, null, false);
emailET = (EditText) view.findViewById(R.id.emailEditText);
passwordET = (EditText) view.findViewById(R.id.passwordEditText);
labLoginButton = (Button) findViewById(R.id.loginLabButton);
updateLoginButton();
dialog = new ProgressDialog(this);
dialog.setMessage("Signin in...");
if (savedInstanceState == null) {
// Add the fragment on initial activity setup
mainFragment = new MainFragment();
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, mainFragment).commit();
} else {
// Or set the fragment from restored state info
mainFragment = (MainFragment) getSupportFragmentManager()
.findFragmentById(android.R.id.content);
}
mTask = new AssetsExtracter();
mTask.execute(0);
}
/* THIS METHOD IS CALLED BY THE LOGIN BUTTON IN THE MAIN ACTIVITY LAYOUT */
public void onLabLoginButtonClick(View v) {
if (userIsLogged) {
currentUser = null;
userIsLogged = false;
updateLoginButton();
Toast.makeText(this, "Disconnected from Lab", Toast.LENGTH_SHORT)
.show();
} else {
/*View messageView = getLayoutInflater().inflate(
R.layout.login_alert, null, false); BEFORE */
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(R.drawable.icon_launcher);
builder.setTitle(R.string.login_string);
builder.setView(alertView); /* USING THE GLOBAL VARIABLE */
builder.setPositiveButton("Sign me", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface d, int which) {
dialog.show();
// Download user and return a List of User
DownloadFilesAsyncTask task = new DownloadFilesAsyncTask(USER_DB_URL) {
#Override
protected void onPostExecute(final List<User> result) {
usersList = result;
loginCheckRoutine(); //HERE I MANAGE THE LOGIN AND GETTING EMPTY STRING
}
};
task.execute();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
builder.create();
builder.show();
}
}
public void updateLoginButton() {
if (userIsLogged) {
labLoginButton.setText(R.string.logout_string);
} else {
labLoginButton.setText(R.string.login_string);
}
}
public void loginCheckRoutine() {
String email = emailET.getText().toString();
String password = passwordET.getText().toString();
System.out.println("DEBUG: " + email + ", " + password); // EMPTY
// controllo nella lista se c'รจ l'utente coi dati inseriti
for (int i = 0; i < usersList.size(); i++) {
if (usersList.get(i).getEmail().equals(email)
&& password.equals("admin")) {
currentUser = usersList.get(i);
userIsLogged = true;
updateLoginButton();
dialog.dismiss();
break;
}
}
if (!userIsLogged) {
userIsLogged = false;
updateLoginButton();
dialog.dismiss();
Toast.makeText(MainActivity.this, "Login Failed",
Toast.LENGTH_SHORT).show();
}
}
}
PROBLEM SOLVED, SOLUTION:
In the onCreate() I inflate the alert_dialog layout in a View variable. I made that View variable global (before onCreate()) and then in onLabLoginButtonClick() I don't inflate the view again, but I use that global instantiated in the onCreate(). hope its clear. thank you all!
You getText just after initialization. Untill you have text in xml you won't get the text. In onclick of alertdialog button get the text.
Declare
EdiText ed1,ed2; // before onCreate if in activity and onCraeteView in fragment
as a instance variable
View view = getLayoutInflater().inflate(R.layout.login_alert, null, false);
ed1= (EditText) view.findViewById(R.id.emailEditText))
ed2 = (EditText) view.findViewById(R.id.emailEditText);
then on Alert dialog Button click
String email = ed1.getText().toString();
String password= ed2.getText().toString()
you must get the text when you click on login button of alert dialog box
the above mentioned code you get text when you show alert dialog it always return always empty string you should follow the following procedure
first you make a custom alert box layout having two edit text and one button
user write text to edittext for login and give password and then click login button
when you call login button click listener you can get text of edittext easyly
You are trying to get the text immediately after you inflated the view. Try doing it when the user clicks the done button instead.
Before onCreate add:
EditText email;
EditText pass;
Add this in your onCreate
etEmail (EditText) view.findViewById(R.id.emailEditText);
etPass (EditText) view.findViewById(R.id.emailEditText);
Then add this to when your button is clicked
String email = etEmail.getText().toString();
String pass = etEmail.getText().toString();
Just ensure that the editText.getText.toString() method is inside the OnClick() method, eg:
TextView submit = enquiryFragment.findViewById(R.id.query_submit_button);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
query_type = query_type_editText.getText().toString();
query_text = query_editText.getText().toString();
if (query_text.length()!=0 && query_type.length()!=0) {
postQuery(query_type, query_text, store_id);
// Log.e("query_type ",query_type );
}else{
Toast.makeText(getContext(), "Enter something !", Toast.LENGTH_SHORT).show();
}
}
});
Alternatively add a TextChangedListener to you textview to change the change the string every time the textboxtext changes.
A textwatcher is also possible
you should get the text when you click on save or done button.
If you get this text on click of alert dialog button, you may end up taking it multiple times.

access a different layouts parameter from current activity

Suppose my current activity is Main.java and I have already declared its layout through setContentView(R.layout.layout1) from its onCreate method. Now, is it in any way possible for me to access a different layout? For e.g., assuming there is another layout - layout2 which has TextView with id tv, then I won't be able to execute the following code from Main.java :
TextView text = (TextView) findViewById(R.id.tv);
text.setText("blah blah");
Is there any way that I can set tv's value from Main.java.
My actual code is the following
setContentView(R.layout.layout);
Button button = (Button) findViewById(button);
button(buttonListener);
Dialog dialog;
Inside the listener, I have the following code:
TextView dialogTitle = (TextView) findViewById(R.id.dialog_title);
dialogTitle.setText("Email");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
View customView = getLayoutInflater().inflate(R.layout.dialog, null);
builder.setView(customView);
dialog = builder.create();
dialog.show();
The problem that I am facing is that dialog_title is in dialog.xml and not in layout.xml
You can always inflate any XML layout you want at any time:
View layout2 = LayoutInflater.from(this).inflate(R.layout.layout2, null);
You can use Bundles
In Activity 1
String your_string = "Hello, World!";
Bundle bundle = new Bundle();
bundle.putString("The key for this string", your_string );
Intent ActivityToLaunch= new Intent(this, ActivityB.class);
ActivityToLaunch.putExtras(bundle);
this.startActivity(ActivityToLaunch);
In Activity 2
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout2); //Setup some layout, set to your own
String content = getIntent().getExtras().getString("The key for this string");
TextView text = (TextView) findViewById(R.id.tv);
text.setText(content);
}
The thread starter said that he wanted to raise a custom dialog, so here goes the edit
This is my class which will generate a custom Dialog:
public class ErrorDialog {
TextView msgTextView;
Button toSettings;
final Context c;
Dialog errorDialog;
/**
* #param c The Context
* #param title Title of the Dialog
* #param msg Message og the Dialog
* #param textOnButton The text on the button
*/
public ErrorDialog(final Context c, String title, String msg, String textOnButton) {
this.c = c;
errorDialog = new Dialog(c);
errorDialog.setContentView(R.layout.error_dialog);
errorDialog.setTitle(title);
msgTextView = (TextView) errorDialog.findViewById(R.id.errorMSG);
msgTextView.setText(msg);
toSettings = (Button) errorDialog.findViewById(R.id.toSettings);
toSettings.setText(text);
toSettings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//doing operations when the user clicks my button in the dialog.
}
});
errorDialog.show();
errorDialog.setCancelable(true);
}
}
Use this class this way:
new ErrorDialog(getApplicationContext(), "My Title", "My Message to the user", "Text on the button");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
View customView = getLayoutInflater().inflate(R.layout.dialog, null);
builder.setView(customView);
TextView dialogTitle = (TextView) customView.findViewById(R.id.dialog_title);
dialogTitle.setText("Email");

Calling final Editables to use in toast

I am unsure as to how to approach this.
I have taken some guidelines given by another person on here and have now gotten to the point of it crashing when I push the button (the monitor)
http://i.stack.imgur.com/C8WgN.png
I want to be able to post a toast notification when the button is pushed, and then have it go away after a few seconds
Also, is there a way to do it to where it will still create a toast notification although some of the info (like line2) is empty?
basic.java:
public class Basic extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.basic);
Spinner spinner = (Spinner) findViewById(R.id.Spinner01);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.state_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
final Button display = (Button) findViewById(R.id.Button01);
display.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
EditText firstField = (EditText) findViewById(R.id.First);
EditText lastField = (EditText) findViewById(R.id.Last);
EditText line1Field = (EditText) findViewById(R.id.Line1);
EditText line2Field = (EditText) findViewById(R.id.Line2);
EditText cityField = (EditText) findViewById(R.id.City);
EditText stateField = (EditText) findViewById(R.id.Spinner01);
EditText zipField = (EditText) findViewById(R.id.Zip);
//EditText phoneField = (EditText) findViewById(R.id.Telephone);
final Editable firstName = firstField.getText();
final Editable lastName = lastField.getText();
final Editable lineOne = line1Field.getText();
final Editable lineTwo = line2Field.getText();
final Editable city = cityField.getText();
final Editable state = stateField.getText();
final Editable zip = zipField.getText();
//final Editable phoneNumber = phoneField.getText();
Toast toDisplay = Toast.makeText(null, firstName, 10);
toDisplay.show();
}
});
}
}
I would like the layout of the toast to be multi-lined, and looking like a postal address
First Last
Street Line 1
Line 2
City, State Zip
Toast.makeText(Change.this, "First Last \n Street Line 1 \n Line 2 \n City, State Zip", Toast.LENGTH_SHORT).show();
By using above toast we can display the output in multilines.In above statement i am using static text in that place u put required fieds like
Toast.makeText(Change.this, firstField.getText().toString()+"\n"+ lastField.getText().toString()+"\n"+ City.getText().toString(), Toast.LENGTH_SHORT).show();

Categories

Resources