I've got a problem. Since I am a newbie to develop Android apps, I suppose that I did not get all the concepts right.
The problem is:In my dialog, after entering all the information and pushing the "Ok" button, I would like to get what I just entered into the TextEdit field. But when I try to
get that EditText on okButton.onClickListener through findViewById(R.id.myTextEditId) I got Null instead of instance.
Here is some code:
Dialog's XML (part where I define EditText) :
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp"
android:inputType="textMultiLine"
android:maxLines="3"
android:hint="#string/add_new_note_hint">
<requestFocus />
</EditText>
Here is the code, where NPE accours:
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
View dialogView = getLayoutInflater().inflate(R.layout.add_note_dialog,null);
dialogBuilder.setTitle(R.string.add_dialog_title)
.setPositiveButton(R.string.add_dialog_pos_but, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
EditText et = (EditText) findViewById(R.id.editText1); //this is where I get null instead of real instance.
}
})
Why am I getting this and what is the right way (best practice) to process widget's data in some callback method ? (how to fix)
Thank you very much, for your time on my issue!
dialogView.findViewById will solve this
The problem is that findViewById searches the current view hierarchy. If you call this from your Activity, then it searches in your current activity's view hierarchy whereas you actually want to search your dialog's:
EditText et = (EditText) dialogView.findViewById(R.id.editText1);
You'll probably need to make dialogView final as well.
Related
My normal edittext which works:
<EditText
android:id="#+id/emailEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dimen_8_dp"
android:hint="Email"
android:imeOptions="actionNext"
android:inputType="textEmailAddress"
android:text="#={viewModel.emailId}"
android:textSize="#dimen/font_size_default_input" />
Now Im using:
<myapp.app.widgets.edittext.MyCustomEditText
android:id="#+id/panEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dimen_8_dp"
android:hint="PAN number"
android:imeOptions="actionNext"
android:inputType="textCapCharacters"
android:maxLength="10"
android:text="#{viewModel.pan}"
android:textSize="#dimen/font_size_default_input" />
Now this doesnt work.
my method
!viewModel.isPanValid() -> binding.panEditText.setError(viewModel.panError.value)
doesnt work but for email it works what to do?
the
MyCustomEditText is just en extended class
public class MyCustomEditText extends LinearLayout implements View.OnFocusChangeListener, TextWatcher, TextView.OnEditorActionListener, View.OnClickListener {
It includes just a UI stuff and on focus listener etc
setError is a function of EditText. Your MyCustomEditText is not an EditText but a LinearLayout so you can't call setError on it because it simply doesn't exist for that class. I don't know the rest of MyCustomEditText but I assume it has an EditText inside it and you might have a reference to it, say editTextInThisClass. If not you will need to create one. Then you could write this in your MyCustomEditText:
public void setError(CharSequence error) {
editTextInThisClass.setError(error)
}
but I wonder if you actually intended for it to be a LinearLayout. If not you should just change LinearLayout to EditText
Surely a simple question to ask but I've tried for hours and I can't seem to get the problem !
I have a DialogFragment which contains a
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/interval_input_layout"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxStrokeWidth="0dp">
<AutoCompleteTextView
android:id="#+id/time_interval_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
tools:ignore="LabelFor" />
</com.google.android.material.textfield.TextInputLayout>
This is the listener set on this AutoCompleteView
binding.untilInput.onItemClickListener =
AdapterView.OnItemClickListener { parent, view, position, id ->
when (position) {
0 -> {
binding.numberLayout.visibility = View.GONE
}
1 -> {
binding.numberLayout.visibility = View.GONE
}
2 -> {
binding.numberLayout.visibility = View.VISIBLE
}
}
}
While number layout is just a linear layout like this
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/number_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="16dp">
<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="For number of events"
android:textColor="?android:textColorSecondary" />
</androidx.appcompat.widget.LinearLayoutCompat>
At first the listener wasn't being called so I set it like this instead of directly calling the function setOnItemClickListener (don't know why that wasn't working) , Now the listener is being called , I even put a breakpoint and debugged it and its setting visibility but its not taking any effect and it does not cause any error so I can't seem to get the problem here
Using a DialogFragment I inflated the view layout with the use of databinding in the method OnCreateView & then in OnViewCreated I worked with my view and caused changes to UI and set listeners to it and again cause changes to UI
in OnCreateDialog I called both of these methods onCreateView (to get the view and set it to dialog) and onViewCreated to setup the view
I tried to find the view using findViewById just to ensure if the databinding was working fine and it was working fine but visibility still won't change and the view won't update !
I still have't gotten to the root of the problem but it seems you have to store the view inside a variable so you don't lose a reference to it when onClickListener is called and in my opinion just when the onClickListener is called getting the view from the binding becomes invalid and it should but the small problem is that I am not calling onDestroy to make the binding null because the binding was invalid at that time !
Now I am just storing a refrence to binding like this
val myvar = binding.monthLayout
and I am capturing the value of myvar inside the onClickListener rather than using the binding
So I'm working on my first real attempt at an Android app, just a simple scorekeeper for softball games. I've got it tallying scores, outs, etc, and right now it just displays "Home" and "Away." I'd like to give users the chance to enter in actual team names. To this effect, I added a custom AlertDialog that pops up with an EditText, so when you hit "OK" it'll update the Home/Away team name.
The problem is I've been Googling this for most of the week and I've not found a single way to actually do this. I've tried tagging the fragment's layout XML so I can find the EditText, but it always gives me a null reference and crashes the app. I added a TextWatcher that presumably watched the fragment's text, but once changed and hit "OK," nothing happened. Tried adding the TextWatch to the fragment, that crashed I think, it was about two hours ago and I'm exhausted.
Really, I think I need a way to have the fragment find the TextView with the team name and change it to the value of the EditText when I positive click, but I don't know how to do that. Or maybe I've seen it and don't understand it, I've only been doing this about two months. I'd post my code, but I deleted out all the stuff that didn't work because it was taking up most of the screen real estate. Any ideas?
EDIT: So I followed advice below on defining views, that found the value of the EditText presumably, but hitting "OK" just made it set the TextView to a blank value. I think this is because the EditText's contents went away as the dialog was closed. Either that or this is all wrong. View dialogname = getActivity().getLayoutInflater().inflate(R.layout.fragment_home, null);
EditText mEtName = (EditText) dialogname.findViewById(R.id.homeName);
View mainAct = getActivity().getLayoutInflater().inflate(R.layout.activity_softball, null);
TextView oTextView = (TextView) mainAct.findViewById(R.id.teamOne);
newName = mEtName.getText().toString();
oTextView.setText(newName)
I think you are doing wrong at time of defining id for EditText. You need to give it dialog reference.
rather than doing
Edittext edittext = (EditText) findViewById(R.id.editText);
do like
Edittext edittext = (EditText) dialog.findViewById(R.id.editText);
Been through this issue a while ago. I created my own class which extended DialogFragment. When I tried to initialize EditText which was in the dialog, I got null like
mEtName = (EditText)dialog.findViewById(R.id.editText);
So, I initialized it in this way and it worked:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
...
View dialogName = getActivity().getLayoutInflater().inflate(R.layout.dialog_name, null);
mEtName = (EditText) dialogName.findViewById(R.id.dialog_etxt_name);
}
Where R.layout.dialog_name is my custom dialog layout.
actually i am displaying a pop up with ok cancel button when user clicks on edit text.
My problem is when ever user double clicks on edit text two pop up comes. so if user has selected any value from pop up its second pop up still remain there.
I don't know how to deal with it.
Any help will appreciated. thanks in advance.
This is my layout
<EditText
android:id="#+id/date_control"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/bg_edit_text"
android:focusableInTouchMode="false"
android:inputType="none"
android:editable="false"
android:clickable="true"
android:layout_marginRight="5dp" />
My java class calling the controller
datePicker = (EditText) findView(R.id.date_control);
datePicker.setOnClickListener(myControllerClass);
its controller
MyDialog myDialog = new myDialog(activity, "Select Date",
date, DateTimeDialog.DATE_PICKER);
myDialog.show();
If you keep a field reference to your dialog you could check to see if its already showing
if(myDialog == null) {
myDialog = new myDialog(activity, "Select Date",
date, DateTimeDialog.DATE_PICKER);
}
if(!myDialog.isShowing()) {
myDialog.show();
}
You just need to set your edittext clickable false after click (means your dialog gets display) then on dialog dismiss you can again make your edittext clickable true.
you have to set this property programmatically .. for EditText properties link..
Hope this explanation works for you..
hi i am new developer on android i have written code for display simple dialog,in this dialog i have taken edit text view.when i entered text on edit text then i have changed orientation of the scree then the value of edit text has not appearing!
i have written code as follows
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Title");
alert.setMessage("Message");
// Set an EditText view to get user input
final EditText input = new EditText(this);
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText();
// Do something with value!
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert.show();
please any one can resolve this?
Basically, this involves overriding the onRetainNonConfigurationInstance method.
See here:
Faster Screen Orientation Change
Excerpt:
"The Activity class has a special
method called
onRetainNonConfigurationInstance().
This method can be used to pass an
arbitrary object your future self and
Android is smart enough to call this
method only when needed. In the case
of Photostream, the application used
this method to pass the downloaded
images to the future activity on
orientation change."
prasad... The editText box does not have an ID and if the view element does not have an ID the view state is not automagically saved on a soft kill when the user changes the orientation of the phone. You might be better off creating a custom dialog using an XML layout, then the edit text box should have and ID and the view state should be automagically saved on a soft kill.
JAL
I have some code here.
Edit: Prototype code taken from the Android Docs that barely works because I do not have the time to work on this. Create an XML layout in res/layout as alert_dialog_text_entry.xml
<?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="fill_parent">
<EditText android:text="Stateful"
android:id="#+id/EditText01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
And then use this layout to create the alert:
AlertDialog.Builder builder= new AlertDialog.Builder(this);
LayoutInflater inflater= getLayoutInflater();
final View myView= inflater.inflate(R.layout.alert_dialog_text_entry, null);
builder.setTitle("About");
builder.setMessage(alertMessage+"Version: "+versionName);
builder.setView(myView);
AlertDialog alert= builder.create();
Since the editText box has an ID it appears to save state on a soft kill.
This question is old but it is still worth giving a simpler answer. JAL mentions the need to set the ID, but you can go ahead and do that directly in the Java. For example, add this new line into the original code above:
// Set an EditText view to get user input
final EditText input = new EditText(this);
// Id the EditText so the framework will save/restore it for us
input.setId(R.id.my_id_for_alert_box_inputs); // <-------- New line
alert.setView(input);
Under /res/values create a new XML file called ids.xml. In there, define this id we use in the Java:
<?xml version="1.0" encoding="utf-8"?>
<!-- Integer IDs used for tagging Views made in Java programmatically
without clashing with XML-defined views. -->
<resources>
<!-- Used to id the input box in a dialog. Reused in different dialogs. -->
<item type="id" name="my_id_for_alert_box_inputs" />
</resources>
This works because the Android application framework is supposed to save/restore views that have an ID defined. The whole XML part of the above is neat but not really needed. You could just plug a made-up integer into the Java View.setId() call to make this a one-line fix.