I'm building an app that is supposed to take text entered from the user and place them into the textviews in a custom list item. The user enters the text into an AlertDialog but once the AlertDialog closes (hence destroyed), all the text entered is destroyed alongside with it and gives me a NullPointerException error.
This is code that handles the Dialog creation and data retrieving:
public class AssignmentActivity extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_assignment);
...
FloatingActionButton assignmentAddButton = (FloatingActionButton) findViewById(R.id.assignment_add_button);
assignmentAddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editCourseInfoDialog();
}
});
}
private void editCourseInfoDialog() {
LayoutInflater inflater = LayoutInflater.from(AssignmentActivity.this);
View dialogLayout = inflater.inflate(R.layout.assignment_edit_dialog, null);
AlertDialog.Builder dialog = new AlertDialog.Builder(AssignmentActivity.this);
dialog.setView(dialogLayout);
final TextView name = (TextView) dialogLayout.findViewById(R.id.assignmentNameView);
final TextView mark = (TextView) dialogLayout.findViewById(R.id.assignmentMarkView);
final TextView overallMark = (TextView) dialogLayout.findViewById(R.id.assignmentOverallMarkView);
final TextView weight = (TextView) dialogLayout.findViewById(R.id.assignmentWeightView);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
assignment.setName(String.valueOf(name.getText()));
assignment.setMark(Double.valueOf(mark.getText() + ""));
assignment.setMarkOutOf(Double.valueOf(overallMark.getText() + ""));
assignment.setPercentage(Double.valueOf(weight.getText() + ""));
assignmentAdapter.notifyDataSetChanged();
dialog.dismiss();
}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
}
}
The issue with your initialization.
LayoutInflater inflater = LayoutInflater.from(AssignmentActivity.this);
View dialogLayout = inflater.inflate(R.layout.assignment_edit_dialog, null);
AlertDialog.Builder dialog = new AlertDialog.Builder(AssignmentActivity.this);
dialog.setView(dialogLayout);
final TextView name = (TextView) dialogLayout .findViewById(R.id.assignmentNameView);
final TextView mark = (TextView) dialogLayout .findViewById(R.id.assignmentMarkView);
final TextView overallMark = (TextView) dialogLayout .findViewById(R.id.assignmentOverallMarkView);
final TextView weight = (TextView) dialogLayout .findViewById(R.id.assignmentWeightView);
As you said TextViews are hooked up with AlertDialog custom view then they view context should be of Dialog view.
You have a lot to learn in terms of concept. You are setting adapter before initializing your list.
assignmentAdapter = new AssignmentListAdapter(assignmentList, this); // at this line **assignmentList** is null as you initiliaze after this line
assignment = new Assignment(this);
You must initialize first like this
assignment = new Assignment(this);
assignmentAdapter = new AssignmentListAdapter(assignmentList, this);
Related
I'm having a custom layout xml file named login_form with a LinearLayout root named login_form_root. I'm trying to display this layout using dialog but can't get values from EditText as I get cannot resolve method findViewById inside onCreateDialog.
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final LayoutInflater inflater = getActivity().getLayoutInflater();
builder.setView(inflater.inflate(R.layout.login_form, null));
builder.setPositiveButton(okText, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
View myView = inflater.inflate(R.layout.login_form, (ViewGroup) findViewById(R.id.login_form_root));
EditText userEmail = (EditText) myView.findViewById(R.id.email_address);
userEmailValue = userEmail.getText().toString();
Toast.makeText(getActivity(), userEmailValue, Toast.LENGTH_SHORT).show();
}
Error is here:-
"(ViewGroup) findViewById(R.id.login_form_root)"
so how can I inflate the custom layout to get EditText values?
You should save the View when inflate it, then you can use it later
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
final View view = layoutInflater.inflate(R.layout.login_form, null);
builder.setView(view);
AlertDialog dialog = builder.create();
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
EditText userEmail = (EditText) view.findViewById(R.id.email_address);
String userEmailValue = userEmail.getText().toString();
}
});
I have a dialog Fragment containing an EditText, from which i want to retrieve the value, but when i try, i get an empty String.
Here is my Dialog code
public class PersonEditDialog extends DoubleActionDialog{
public PersonEditDialog() {
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
builder.setView(inflater.inflate(R.layout.activity_personne_edit, null))
.setPositiveButton(R.string.s_button_save, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
doAction();
}
})
.setNegativeButton(R.string.s_button_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
PersonEditDialog.this.getDialog().cancel();
}
});
builder.setTitle(getTitleId());
return builder.create();
}
#Override
public void doUpdate() {
// mise à jour de la personne
View view = getActivity().getLayoutInflater().inflate(R.layout.activity_personne_edit, null);
EditText nom = (EditText) view.findViewById(R.id.nom);
EditText prenom = (EditText) view.findViewById(R.id.prenom);
Toast.makeText(getActivity(), nom.getText() + " " + prenom.getText() + " mis à jour", Toast.LENGTH_SHORT).show();
}
#Override
public void doCreate() {
// ajout de la personne
View view = getActivity().getLayoutInflater().inflate(R.layout.activity_personne_edit, null);
EditText nom = (EditText) view.findViewById(R.id.nom);
EditText prenom = (EditText) view.findViewById(R.id.prenom);
Toast.makeText(getActivity(), nom.getText().toString() + " " + prenom.getText().toString() + " créé", Toast.LENGTH_SHORT).show();
}
#Override
protected int getUpdateLabelId() {
return R.string.s_title_edit_person;
}
#Override
protected int getCreateLabelId() {
return R.string.s_title_add_person;
}
}
the doAction() method invokes one of the two methods : doUpdate() or doCreate() depending on the value of a parameter.
The doCreate() or doUpdate() are trying to read the content o the EditText.
You are inflating a new layout and getting the contents of the edittexts in this new layout. Since the layout where the edittexts are is the dialog layout, you can use getDialog() in a DialogFragment to get a reference to the dialog and call findViewById() on it.
For example, replace the
View view = getActivity().getLayoutInflater().inflate(R.layout.activity_personne_edit, null);
with something like
Dialog dlg = getDialog();
and then call dlg.findViewById(...).
You are getting an empty String because you are trying to get it from a different EditText. In your doUpdate and doCreate methods you are creating new Views with the layout activity_personne_edit.
Instead in onCreateDialog you should inflate the layout into a global View object like
layoutView = inflater.inflate(R.layout.activity_personne_edit, null);
builder.setView(layoutView)
and then in your doUpdate and doCreate methods change
EditText nom = (EditText) layoutView.findViewById(R.id.nom);
EditText prenom = (EditText) layoutView.findViewById(R.id.prenom);
to
EditText nom = (EditText) layoutView.findViewById(R.id.nom);
EditText prenom = (EditText) layoutView.findViewById(R.id.prenom);
and no need to create the view object then.
I have the following AlertDialog and its onClick method:
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setView(View.inflate(this, R.layout.barcode_alert, null));
alertDialog.setPositiveButton("Search", new DialogInterface.OnClickListener() {
#Override
public void onClick(#NotNull DialogInterface dialog, int which) {
// how to get editTextField.getText().toString(); ??
dialog.dismiss();
}
});
The XML I inflate in the dialog (barcode_alert.xml) contains, among other things, an EditText field, and I need to get its string value after the user taps the Search button.
My question is, how do I get a reference to that field so I can get its text string?
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
final View v = View.inflate(this, R.layout.barcode_alert, null); //here
alertDialog.setView(v);
alertDialog.setPositiveButton("Search", new DialogInterface.OnClickListener() {
#Override
public void onClick(#NotNull DialogInterface dialog, int which) {
((EditText)v.findViewById(R.id.edit_text)).getText().toString(); //and here
dialog.dismiss();
}
});
Try this,
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
final View v = getLayoutInflater().inflate(this, R.layout.barcode_alert, null);
final EditText editTextField = (EditText) v.findViewById(R.id.edit_text);
editTextField.setOnClickListener(MyActivity.this);
alertDialog.setView(v);
alertDialog.setPositiveButton("Search", new DialogInterface.OnClickListener() {
#Override
public void onClick(#NotNull DialogInterface dialog, int which) {
String enteredValue = editTextField.getText().toString(); // get the text from edit text
dialog.dismiss();
}
});
You can inflate your view and get a reference to a variable:
View v = View.inflate(this, R.layout.barcode_alert, null);
you can use findViewById to get a reference to your view. Make sure that your variable is final or a member variable. Otherwise you cannot access it in the onClickListener
final EditText editText = (EditText)v.findViewById(R.id.your_edit_text
I'm trying to make an alert dialog with dynamic text. The problem is that the textview I want to edit is in an inflated Layout.
At the topmost of my code is
TextView tv;
so I can reach it from all methods in my class. Code snippet below:
public class EditNameDialog extends DialogFragment {
public EditNameDialog()
{
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater factory = LayoutInflater.from(getActivity());
View textEntryView = factory.inflate(R.layout.fragment_dialog, null);
this.setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Holo_Light_Dialog);
return new AlertDialog.Builder(getActivity())
.setTitle("Skapa profil")
.setView(textEntryView)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton)
{
}
}
).create();
}
And the layout file "fragment_dialog.xml" looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/error_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="top"
android:padding="10dp"
android:text="#string/error_connecting"
android:textSize="20sp" />
</LinearLayout>
I want to edit the TextView, which resides in the "textEntryView".
To do this i have tried
tv = (TextView) textEntryView.findViewById(R.id.error_dialog);
and then when I call my method:
public void attemptLogin(View v)
{
System.err.println(tv.getText());
}
it gives me a Nullpointer.
I don't understand why the id error_dialog cannot be found within the textEntryView View.
Thanks.
I can not see a declaration for your variable tv, like:
TextView tv = (TextView) findViewById(R.id.error_dialog);
If you have not declarate it, your framework (eclipse?) should give you a hint.
So did you declarate it in an other part of your class?
your problem is a bit more complicated than it looks. You are losing the reference to your widgets as the View-Object doesn't hold the correct View when you do it like this. I had the same issue and it took me a while figuring it.
I solved it by keeping the View-reference updated and outsourcing the retrieving of the textView-value to a later-in-lifecycle-called-method like onActivityCreated()
I posted my example that does have an editText and a Button.
My Example:
public class EnterNumberFragment extends DialogFragment implements OnClickListener{
private EditText editText = null;
private Button acceptButton = null;
private View mContentView = null;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflator= getActivity().getLayoutInflater();
mContentView = inflator.inflate(R.layout.dialog_number, null);
builder.setView(mContentView);
return builder.create();
}
#Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
acceptButton = (Button) mContentView.findViewById(R.id.accept_change);
editText = (EditText) mContentView.findViewById(R.id.et_number);
acceptButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.accept_change:
String num = editText.getText().toString();
SharedPreferences sPrefs = getActivity().getSharedPreferences("PanicPrefs",0);
SharedPreferences.Editor prefEditor = sPrefs.edit();
prefEditor.putString("NumberToCall", num).commit();
dismiss();
break;
default:
break;
}
}
The problem exist in this line:-
LayoutInflater factory = LayoutInflater.from(getActivity());
you don't have a reference of activity. What you can do is to pass an activity context and then get the activity:-
LayoutInflater factory = LayoutInflater.from(mContext.getActivity());
or you can use following code:-
LayoutInflater factory = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
I have created a screen with 5 rows of information. each row has 2 values. (value1 and value2)
At the end of each row is a button. For each row I have created a xml file that I am looping though and filling in the values from a database
what I am looking at doing is when the button is pressed a dialog is opened with two editviews filled in with the values from that row
Then when the button is pressed on the dialog the values are updated in database.
I am having problems with the createdialog / preparedialog methods and passing the values to them.
UPDATE with Code
public void createLayout(LinearLayout pMainlayout, String pMajorValue) {
DatabaseTools db = new DatabaseTools(this);
majorValue= pMajorValue;
nameInfo = db.getNames(pMajorValue);
name = returnName(pMajorValue);
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < nameInfo.size(); i++) {
// Get views
View view = (View) inflater.inflate(R.layout.mainlayout, null);
TextView nameView = (TextView) sightmarkView.findViewById(R.id.name_title);
TextView Value1View = (TextView) sightmarkView.findViewById(R.id.value1);
TextView ValueView = (TextView) sightmarkView.findViewById(R.id.value2);
Button updateButton = (Button) sightmarkView.findViewById(R.id.updatebutton);
// Get info from Database
nameValue = nameInfo.get(i).toString();
value1v = db.getMark(majorValue, nameInfo.get(i).toString());
value2v = db.getMark(majorValue, nameInfo.get(i).toString());
// populate info into fields
nameView.setText(nameValue);
Value1View.setText(String.valueOf(value1));
Value2View.setText(String.valueOf(value2));
updateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Bundle bundle = new Bundle();
//Code here to add values to a bundle
showDialog(SIGHTMARK_DIALOG_ID, bundle);
}
});
pMainlayout.addView(view);
}
}
All this work correctly. The values are displayed. I have looked into using a bundle to pass them into the dialog
#Override
protected Dialog onCreateDialog(int id, Bundle bundle) {
switch(id) {
case DIALOG_ID:
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View layout = inflater.inflate(R.layout.update, (ViewGroup) findViewById(R.id.update));
final EditText value1Edit = (EditText) layout.findViewById(R.id.value1_current);
final EditText value2Edit = (EditText) layout.findViewById(R.id.value2_current);
//next pull values from bundle to populate into fields
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout);
// Now configure the AlertDialog
builder.setTitle(R.string.sight_update_title);
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
this.removeDialog(DIALOG_ID);
}
});
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
value1New = Float.parseFloat(value1Edit.getText().toString());
value2New = Float.parseFloat(value2Edit.getText().toString());
// method run to update the database with the new values passed to it
updateMarks(value1, value2);
this.removeDialog(DIALOG_ID);
}
});
// Create the AlertDialog and return it
AlertDialog Dialog = builder.create();
return Dialog;
}
return null;
}
This part has issues and is not getting the values correctly or passing them to the update method
i think the problem is here:
If you use showDialog(int), the activity will call through to this
method the first time, and hang onto it thereafter. Any dialog that is
created by this method will automatically be saved and restored for
you, including whether it is showing.
remove references
removeDialog(SIGHTMARK_DIALOG_ID);
showDialog(SIGHTMARK_DIALOG_ID, bundle);
documentation