I've search over the threads but so far I have not found what I'm looking for. I created a custom Alert Dialog that show up and I can do almost anything with it. It custom dialog is made of 3 TextViews and 3 EditText but whenever I need to get the EditText I get a null component.
From my xml file
<TextView android:layout_alignParentTop="true"
android:id="@+id/txtAccName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Name"
android:textSize="23dp"
>
</TextView>
<EditText android:id="@+id/txtEditName"
android:layout_below="@+id/txtAccName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
android:maxLength="20"
>
I'm trying to get the EditText field with:
EditText txtAccName = (EditText) findViewById(R.id.txtEditName);
Log.d("#############################", "txtAccName="+txtAccName.getText().toString());
But when doing this, the first line works well, the second home causes a crash and the control is null. This is the Overwrite method that I use to create the custom AlertDialog that I need.
@Override
protected Dialog onCreateDialog(int id) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View layout = inflater.inflate(R.layout.accountdialog, (ViewGroup) findViewById(R.id.accDialog));
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
});
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
EditText txtAccName = (EditText) findViewById(R.id.txtEditName);
//EditText txtAccCur = (EditText) findViewById(R.id.txtEditCur);
//EditText txtAccCountry = (EditText) findViewById(R.id.txtEditCountry);
//DBConn db = new DBConn(Accounts.this.getApplicationContext(), "msaverdb", null, 0);
Log.d("#############################", "CALLING db.insertAccount");
Log.d("#############################", "txtAccName="+txtAccName.getText().toString());
//db.insertAccount(txtAccName.getText().toString(), txtAccCountry.getText().toString(),
// txtAccCur.getText().toString());
Accounts.this.removeDialog(ACC_DIALOG);
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Accounts.this.removeDialog(ACC_DIALOG);
}
});
builder.setView(layout);
AlertDialog ad = builder.create();
return ad;
}
Any help is most appreciated.
Take note of how all of your method calls are being resolved within your anonymous inner classes.
findViewById
is a method that exists on views and on your activity. The version of this method on your activity searches for a view within the activity window's view hierarchy. The version on views searches that view instance and all attached children.Your call on the problematic line of code:
is resolving to
Activity#findViewById
. But your dialog's layout is not attached to your activity window, it's attached to the dialog. You can find the correct view reference in several ways but the simplest in your case is probably to search from the root of the layout that you inflated:The explanation by adamp is great. But that method didn't work for me. The simplest way for me is like this:
Hope this helps somebody.
When you use
findViewById
you implicitly refer to the current activity. The part you have to change isinstead of
when you attempt to resolve it. You'll also have to change the scope of the
AlertDialog
objectad
to class-wide and make sure that it's not null, before you search for views in it. That's pretty much it.