Trouble with my custom layout for an Alert Dialog - java

Making a to-do list. Having 2 issues, The not so important issue is that for some reason I can't see the TextView's that I set up as "labels". The more important thing is that when I click the create new task button, my alert pops up, I can put values in my EditText boxes, but when I hit create, it crashes and I get a NullPointer exception saying I'm trying to call getText() on a null object reference. I can't figure out if I'm inflating incorrectly or if I'm not linking the EditTexts to the alert properly. The annoying thing is that my edittext alert box works just fine editing existing list items(that I hardcoded for testing). Here's my layout and activity, I commented the line in which it breaks. Sorry about all the Log.d's I'm really trying to visualize how all this works.
The Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<EditText
android:layout_width="55dp"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:id="#+id/txtCreatePriority"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="25dp"
android:hint="1"
android:textAlignment="center" />
<EditText
android:layout_width="235dp"
android:layout_height="wrap_content"
android:id="#+id/txtCreateItemContent"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/txtCreatePriority"
android:layout_toEndOf="#+id/txtCreatePriority"
android:layout_marginLeft="15dp"
android:hint="Do Laundry"
android:textAlignment="center" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Priority"
android:id="#+id/lblPriority"
android:layout_above="#+id/txtCreatePriority"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="17dp"
android:textStyle="bold"
android:textSize="23dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Task to-do"
android:id="#+id/lblItemContent"
android:layout_above="#+id/txtCreateItemContent"
android:layout_toRightOf="#+id/lblPriority"
android:layout_toEndOf="#+id/lblPriority"
android:layout_marginLeft="65dp"
android:textStyle="bold"
android:textSize="23dp" />
</RelativeLayout>
The Activity
public class MainActivity extends AppCompatActivity {
private ListDataSource ds;
private ListView listViewToDo;
private Button btnAddNew;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Context context = this;
Log.d("MainActivity","Attempting to create data source");
try {
ds = new ListDataSource();
}
catch(Exception e)
{
e.printStackTrace();
Log.d("MainActivity","Failed to create data source");
}
btnAddNew = (Button)findViewById(R.id.btnAddNew);
Log.d("Main Activity","Attempting to link empty list view to on screen view");
listViewToDo = (ListView)findViewById(R.id.listOfLists);
Log.d("Main Activity", "Views linked, Attempting to set adapter to listView");
listViewToDo.setAdapter(new ListDataSourceAdapter(this, ds));
Log.d("Main Activity", "Successfully set Adapter");
btnAddNew.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("addItem", "Entered onclick, Attempting to create AlertDialog");
AlertDialog.Builder addItem = new AlertDialog.Builder(context);
Log.d("addItem", "AlertDialog Built, attempting to create inflater");
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
addItem.setView(inflater.inflate(R.layout.create_item_layout, null));
Log.d("addItem", "inflater built linking text boxes");
final TextView txtCreatePriority = (TextView)findViewById(R.id.txtCreatePriority);
final TextView txtCreateCellContent = (TextView)findViewById(R.id.txtCreateItemContent);
final TextView lblPriority = (TextView)findViewById(R.id.lblPriority);
final TextView lblItemContent = (TextView)findViewById(R.id.lblItemContent);
addItem.setTitle("Create new item");
addItem
.setCancelable(false)
.setPositiveButton("Create", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.d("editText onClick", "in onClick method, preparing to add entry");
// This is where the code breaks
ds.getList().add(Integer.valueOf(txtCreatePriority.getText().toString()), new CellContent(Integer.valueOf(txtCreatePriority.getText().toString()) + 1, txtCreateCellContent.getText().toString().trim()));
Log.d("editText onClick", "added new entry");
ListDataSourceAdapter adapter = new ListDataSourceAdapter(context, ds);
Log.d("editText onClick", "reestablished link to adapter");
listViewToDo.setAdapter(adapter);
Log.d("editText onClick", "adapter set");
adapter.notifyDataSetChanged();
Log.d("editText onClick", "DataSetChanged");
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertDialog = addItem.create();
alertDialog.show();
}
});
// add button listener
listViewToDo.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id)
{
AlertDialog.Builder editItem = new AlertDialog.Builder(context);
final EditText edittext = new EditText(context);
editItem.setTitle("Change item");
editItem
.setMessage("Set new todo item")
.setView(edittext)
.setCancelable(false)
.setPositiveButton("Submit", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
Log.d("editText onClick","in onClick method, preparing to remove previous entry");
ds.getList().remove(position);
Log.d("editText onClick", "removed previous entry");
ds.getList().add(position, new CellContent(position + 1, edittext.getText().toString().trim()));
Log.d("editText onClick", "added new entry");
ListDataSourceAdapter adapter = new ListDataSourceAdapter(context,ds);
Log.d("editText onClick","reestablished link to adapter");
listViewToDo.setAdapter(adapter);
Log.d("editText onClick", "adapter set");
adapter.notifyDataSetChanged();
Log.d("editText onClick", "DataSetChanged");
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertDialog = editItem.create();
alertDialog.show();
}
});
}
}
The Error
java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference

You're calling "(EditText)v.findViewById" on the view v.
The view v is the view passed back in the onClickListener, which is the button itself.
Since that button does not contain the EditTexts within it, those views are null. And crash when you try to access them.
I'm a little uncertain where the layout with the edit texts is in this code. Is it in the same layout as the listview, or in create_item_layout?
If its create_item_layout, that needs to be inflated before getting the EditTexts. Use the view you inflate to findViewById.

Related

Error getting in validation

I am working on android application in my application there are registration page in that page i am using #slackid, when user fill the registration form and enter slack id without # its show validation message like # is necessary. Than he move to the next. Kindly please tell me how i use this # validation message. Here is the code
activity_registration.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:context=".RegisterActivity">
<EditText
android:id="#+id/name_reg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Your Name"/>
<EditText
android:id="#+id/email_reg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Your email id"
android:inputType="textEmailAddress"/>
<EditText
android:id="#+id/slackid_reg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint=" #slackId"/>
<EditText
android:id="#+id/password_reg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="Password"/>
<EditText
android:id="#+id/confirm_password_reg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="Retype Password"/>
<EditText
android:id="#+id/info_reg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Information/Phone no/Optional"/>
<Button
android:id="#+id/register_reg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:text="Register"/>
</LinearLayout>
RegistrationActivity.java
public class RegisterActivity extends AppCompatActivity implements View.OnClickListener {
private EditText name,emailId,slackId,password,conPasword,info;
private Button registerB;
// Alert dialog
AlertDialog.Builder alertBuilder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
name = findViewById(R.id.name_reg);
emailId = findViewById(R.id.email_reg);
slackId = findViewById(R.id.slackid_reg);
password = findViewById(R.id.password_reg);
conPasword = findViewById(R.id.confirm_password_reg);
info = findViewById(R.id.info_reg);
registerB = findViewById(R.id.register_reg);
//set register to onClick event
registerB.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.register_reg:
// Check all requir field empty or not
//Apply the validation in each field including slack Id
if(name.getText().toString().length()==0) {
name.setError("Name cannot be blank");
}
if(emailId.getText().toString().equals("")) {
emailId.setError("Email cannot be blank");
}
if(String.valueOf(slackId.getText().toString().charAt(0)).equals("#")) {
slackId.setError("Slack id cannot be blank");
}
if (password.getText().toString().equals("")) {
password.setError("password cannot be blank");
}
if(conPasword.getText().toString().equals("")) {
conPasword.setError("confirm password cannot be blank");
// if any of the required field empty "Show Dialog to fill the required field
alertBuilder = new AlertDialog.Builder(RegisterActivity.this);
alertBuilder.setTitle("Something Wrong");
alertBuilder.setMessage("Please Fill all required field");
alertBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
AlertDialog alertDialog = alertBuilder.create();
alertDialog.show();
}else if(!(password.getText().toString().equals(conPasword.getText().toString()))){
//check pasword and confirm pasword mismatch
alertBuilder = new AlertDialog.Builder(RegisterActivity.this);
alertBuilder.setTitle("Something Wrong");
alertBuilder.setMessage("Pasword Mismatch");
alertBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
password.setText("");
conPasword.setText("");
}
});
AlertDialog alertDialog = alertBuilder.create();
alertDialog.show();
}else{
// Background task to insert user information into database
BackgroundLoginTask backgroundLoginTask = new BackgroundLoginTask(RegisterActivity.this);
backgroundLoginTask.execute("register",name.getText().toString(),
emailId.getText().toString(),
slackId.getText().toString(),
password.getText().toString(),
info.getText().toString());
}
break;
}
}
}
Try :
edittext.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if(!edittext.getText().toString().contains("#")) {
edittext.setError("# not detected");
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void afterTextChanged(Editable s) {
}
});
If you want something that the id should start with # then can use this pattern : ^#.*
You can blank validation by using TextUtils.isEmpty(slackId.getText().toString())
This will check if text is null or empty
In your code you did validation like
if(String.valueOf(slackId.getText().toString().charAt(0)).equals("#")) {
slackId.setError("Slack id cannot be blank");
}
this will not validate weather is contains # or not.
do this:
if(!slackId.getText().toString().contains("#")){
//show your error message here
}
Hope it will help you!!
You can make a validation like
if(!slackId.getText().toString().contains("#")){}
You can use this as its better than using textChange listener for your case to check the text edit after losing focus , which will give you the needed validation without submitting .
EditText ed= (EditText) findViewById(R.id.edittxt);
ed.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus && !ed.getText().toString().contains("#")) {
ed.setError("# not detected")
}
}
});

Java EditText not validating correctly

Can someone help with this? My EditText is not empty but the toast still shows up. My app require users to select Date and Time, then select 1 item on the listview to proceed. A dialog will pop out after that. However for some reason, even though my edittext isn't empty, it still won't allow me to continue. I can't seem to figure out what's wrong, I mean the code is just that simple, nothing complicate.
final String date = textDate1.getText().toString().trim();
final String time = textTime1.getText().toString().trim();
listViewHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Team team = teams.get(i);
if(TextUtils.isEmpty(date)){
Toast.makeText(RecreateActivity.this,"Please choose a date.",Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(time)){
Toast.makeText(RecreateActivity.this,"Please choose a time.",Toast.LENGTH_LONG).show();
return;
}
//the rest of the code
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(RecreateActivity.this);
LayoutInflater inflater = getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.confirm_layout, null);
dialogBuilder.setView(dialogView);
final Button buttonYes2 = (Button) dialogView.findViewById(R.id.buttonYes2);
final Button buttonNo2 = (Button) dialogView.findViewById(R.id.buttonNo2);
//final Team team = teams.get();
final AlertDialog b = dialogBuilder.create();
b.show();
buttonYes2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
databaseMembers.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final ArrayList<String> CheckList = new ArrayList<String>();
for (DataSnapshot check : dataSnapshot.child("teams").getChildren()) {
CheckList.add(check.getKey());
}
if (CheckList.contains(team.getTeamName())) {
Toast.makeText(RecreateActivity.this, "Team already exist.", Toast.LENGTH_LONG).show();
return;
}
databaseMembers.child("History").child(team.getTeamName()).child("date").setValue(date);
databaseMembers.child("History").child(team.getTeamName()).child("time").setValue(time);
for (DataSnapshot history : dataSnapshot.child("History").child(encodedEmailAddress).getChildren()) {
String key = history.getKey();
if (key.equals(team.getTeamName())) {
teams.clear();
Team team = history.getValue(Team.class);
teams.add(team);
databaseTeams.child(team.getTeamName()).setValue(team);
}
if (key.equals("teamMember")) {
for (DataSnapshot members : dataSnapshot.child("History").child(encodedEmailAddress).child("teamMember").getChildren()) {
String key2 = members.getKey();
String value = members.getValue(String.class);
Map<String, Object> map = new HashMap<>();
map.put(key2, value);
databaseMembers.child("members").child(team.getTeamName()).child("teamMember").updateChildren(map);
b.dismiss();
}
}
}
Toast.makeText(RecreateActivity.this, "Team created.", Toast.LENGTH_LONG).show();
Intent myIntent = new Intent(RecreateActivity.this,
MainActivity.class);
startActivity(myIntent);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
XML:
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Previous Team"
android:textAppearance="#style/TextAppearance.AppCompat.Title"
android:textAlignment="center"/>
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select new Date/Time and tap on the Team."
android:textAlignment="center"/>
<ListView
android:id="#+id/listViewHistory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</ListView>
<TextView
android:id="#+id/textView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Members:"
android:textAppearance="#style/TextAppearance.AppCompat.Headline" />
<TextView
android:id="#+id/textViewList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAppearance="#style/TextAppearance.AppCompat.Medium" />
<EditText
android:id="#+id/textDate1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Select Date..."
android:layout_alignParentStart="true" />
<EditText
android:id="#+id/textTime1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Select Time..."
android:layout_below="#+id/textDate"
android:layout_alignParentStart="true" />
<Button
android:id="#+id/buttonAddHistory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create Team"
android:textAlignment="center"
android:textAllCaps="false"
tools:textSize="20sp" />
You are getting string from EditText only once - before setting OnItemClickListener. You need to get string inside the listener.
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Team team = teams.get(i);
final String date = textDate1.getText().toString().trim();
final String time = textTime1.getText().toString().trim();
if(TextUtils.isEmpty(date)){
Toast.makeText(RecreateActivity.this,"Please choose a date.",Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(time)){
Toast.makeText(RecreateActivity.this,"Please choose a time.",Toast.LENGTH_LONG).show();
return;
}
}
Your field is initialized only once. I don't know the context, this may be actually what you want, but then it doesn't make any sense to validate it every time, those fields have the same value every time the listener code is run. Try to add the code to get date and time in the listener itself.
Your code is setting [date] and [time] outside of the onClickListener. When the user clicks the button, your code isn't resetting the variables. I'd evaluate the EditText directly from your onClickListener code:
listViewHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Team team = teams.get(i);
if(TextUtils.isEmpty(textDate1.getText().toString().trim())){
Toast.makeText(RecreateActivity.this,"Please choose a date.",Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(textTime1.getText().toString().trim())){
Toast.makeText(RecreateActivity.this,"Please choose a time.",Toast.LENGTH_LONG).show();
return;
}
Try getting date value of edittext inside the click listener.
listViewHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Team team = teams.get(i);
final String date = textDate1.getText().toString().trim();
final String time = textTime1.getText().toString().trim();
if(date.isEmpty()){
Toast.makeText(RecreateActivity.this,"Please choose a date.",Toast.LENGTH_LONG).show();
return;
}
if(time.isEmpty()){
Toast.makeText(RecreateActivity.this,"Please choose a time.",Toast.LENGTH_LONG).show();
return;
}

Inflated layout to alertdialog doesn't work

I have the following method where I must confirm the user's password before he is allowed to access the Setup menu. To do so, I make him login again because Parse (my cloud storage) doesn't allow me to confirm passwords. So far so good. The problem is when I inflate the view to my AlertDialog to use a custom button and EditText. You can see in my code below that I have commented the Button section, because when I try to get the onClickListener it doesn't work. It just does nothing. So I'm currently using the alertDialogPositiveButton and it's ok. The second problem and the real one is that I cannot retrieve the data insert into the editText. The SUpassword3is always equals to blank, not null. Can someone please help?
method:
public void confirmPassword(){
final LayoutInflater inflateSetup = getLayoutInflater();
AlertDialog.Builder alertSetup = new AlertDialog.Builder(this);
alertSetup.setView(inflateSetup.inflate(R.layout.inflate_setup, null));
alertSetup.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
System.out.println("User has clicked the [confirm] button");
View viewInflate_setup = inflateSetup.inflate(R.layout.inflate_setup, null);
edtPassword3 = (EditText)viewInflate_setup.findViewById(R.id.edtPassword3);
SUpassword3 = edtPassword3.getText().toString();
final ParseUser beforeConfirmPassword = ParseUser.getCurrentUser();
ParseUser.logInInBackground(beforeConfirmPassword.getUsername(), SUpassword3, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if(e==null){
//password confirmed, logout last user and go to next setup
System.out.println("Password [" +SUpassword3+ "] and user [" +beforeConfirmPassword.getUsername()+ "] confirmed, logout last user and go to setup");
beforeConfirmPassword.logOut();
}else{
//passwords don't match
System.out.println("Password don't match: [" +SUpassword3 + "] USER [" +beforeConfirmPassword.getUsername()+ "]");
}
}
});
}
});
final AlertDialog dialogSetup = alertSetup.create();
dialogSetup.show();
/**
btnConfirmPassowod = (Button)viewInflate_setup.findViewById(R.id.btnConfirm);
btnConfirmPassowod.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
System.out.println("User has clicked the [confirm] button");
final ParseUser beforeConfirmPassword = ParseUser.getCurrentUser();
ParseUser.logInInBackground(beforeConfirmPassword.getUsername(), SUpassword3, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if(e==null){
//password confirmed, logout last user and go to next setup
System.out.println("Password confirmed, logout last user and go to setup");
beforeConfirmPassword.logOut();
}else{
//passwords don't match
dialogSetup.dismiss();
Snackbar.make(v, "Wrong password, try again.", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}
});
}
}); */
}
inflate_setup.xml(the xml file I inflate on the alertDialog)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:id="#+id/edtPassword3"
android:layout_gravity="center_horizontal"
android:hint="#string/EN_txt.confirmPassword"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/btnConfirm"
android:layout_gravity="center_horizontal" />
</LinearLayout>
Final version(working):
public void confirmPassword(){
final LayoutInflater inflateSetup = getLayoutInflater();
final View viewInflate_setup = inflateSetup.inflate(R.layout.inflate_setup, null);
AlertDialog.Builder alertSetup = new AlertDialog.Builder(this);
alertSetup.setView(viewInflate_setup);
alertSetup.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
System.out.println("User has clicked the [confirm] button");
edtPassword3 = (EditText)viewInflate_setup.findViewById(R.id.edtPassword3);
SUpassword3 = edtPassword3.getText().toString();
...
You inflate another view inside your onClickListener. That's why you actually check text of another edtPassword3, not that one which visible for user. It should be something like that:
View view = inflateSetup.inflate(R.layout.inflate_setup;
final EditText edtPassword3 = (EditText)viewInflate_setup.findViewById(R.id.edtPassword3);
alertSetup.setView(view, null));
alertSetup.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
System.out.println("User has clicked the [confirm] button");
SUpassword3 = edtPassword3.getText().toString();
....
Try to use: Dialog class
// custom dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.custom);
dialog.setTitle("Title...");
Get a reference of the inflated view:
View dialogView = inflateSetup.inflate(R.layout.inflate_setup, null);
In dialog use:
alertSetup.setView(dialogView);
Then, access button using:
Button myButton = (Button) dialogView.findViewById(R.id.btnConfirm);

Android custom AlertDialog height not honoring layout parameters

So I am creating a custom AlertDialog using the Builder. I have a custom view I am inflating in the dialog with the following layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<EditText android:id="#+id/edit_username"
style="#style/EditPassword"
android:hint="#string/login_username_hint" />
<EditText android:id="#+id/edit_password"
style="#style/EditPassword"
android:hint="#string/login_password_hint" />
</LinearLayout>
The android:layout_height style for the EditText controls is set to "wrap_content". When I show the dialog with this custom view the dialog is stretched to fill the height of the entire screen. No matter what I set the layout_height on the LinearLayout to (including hardcoded pixel values), it still fills the entire screen on my emulator.
I'm hoping there's something simple that I'm missing here?
EDIT: I looked in the Hierarchy Viewer and the layout I included in this question is correctly defined, but it is wrapped within a FrameLayout within a FrameLayout, and the outermost FrameLayout is set to "wrap_content" but is rendering in the Viewer with a bunch of empty space below it.
EDIT 2: As requested, the code that inflates the layout.
protected Dialog onCreateDialog(int id) {
switch(id) {
case AUTHENTICATION_DIALOG:
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
final View loginView = inflater.inflate(R.layout.login_dialog, null);
return new AlertDialog.Builder(HomeActivity.this)
.setTitle("Upload profile data")
.setView(loginView)
.setPositiveButton("Upload", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
EditText userName = (EditText)loginView.findViewById(R.id.edit_username);
EditText password = (EditText)loginView.findViewById(R.id.edit_password);
String userNameStr = StringUtils.convertToTrimmedString(userName.getText());
String passwordStr = StringUtils.convertToTrimmedString(password.getText());
if (userNameStr.equals("") || passwordStr.equals("")) {
new AlertDialog.Builder(HomeActivity.this)
.setTitle("Required fields missing")
.setMessage("You must enter a username and password")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
HomeActivity.this.showDialog(AUTHENTICATION_DIALOG);
dialog.dismiss();
}
}).show();
} else {
dialog.dismiss();
} // end if user entered username and password
} // end "Upload" onClick
}) // end setPositiveButton DialogInterface.OnClickListener()
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
} // end "Cancel" onClick
}).create();
default:
return null;
}
}
So I switched to using a RelativeLayout like so:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<EditText android:id="#+id/edit_username"
style="#style/EditPassword"
android:hint="#string/login_username_hint" />
<EditText android:id="#+id/edit_password"
style="#style/EditPassword"
android:layout_below="#+id/edit_username"
android:hint="#string/login_password_hint" />
</RelativeLayout>
and it works fine. I switched back to Linear to test and it exhibited the old broken behavior when I switched back to the LinearLayout. I'm going to leave this answer unmarked in the hopes that someone can tell me why it's freaking out over LinearLayout vs Relative.

Parse XML and display it in an AlertDialog in Android

I have this .xml file with countries and their countrycodes in them. This is how it looks like:
<?xml version="1.0" encoding="UTF-8"?>
<landen>
<land>
<naam>Afghanistan</naam>
<code>AF</code>
</land>
<land>
<naam>Albani�</naam>
<code>AL</code>
</land>
<land>
<naam>Algerije</naam>
<code>DZ</code>
</land>
<land>
</landen>
Now I want people to choose one country out of an list. I though an AlertDialog would be nice to display everything.
The way i get the values out of my xml-file is like this:
protected ArrayList<Land> getLanden() {
ArrayList<Land> lijst = new ArrayList<Land>();
try {
DocumentBuilder builder =DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(getAssets().open("landenlijst.xml"));
NodeList nl = doc.getElementsByTagName("land");
for (int i=0;i<nl.getLength();i++) {
Node node = nl.item(i);
Land land = new Land();
land.land = Xml.innerHtml(Xml.getChildByTagName(node, "naam"));
land.landcode = Xml.innerHtml(Xml.getChildByTagName(node, "code"));
lijst.add(land);
}
Log.d("Gabug","Klaar met parsen");
Log.d("Gabug","Landen: " + lijst);
} catch (Exception e) {
e.printStackTrace();
}
return lijst;
}
And I use this to make my AlertDialog:
public void KiesLandMenu(){
ArrayList<Land> alleLanden = getLanden();
final CharSequence[] items = alleLanden.toArray(new CharSequence[alleLanden.size()]);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Kies land");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
switch (item){
case 0:
break;
case 1:
break;
case 2:
break;
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
I don't know if this works as DDMS returns some bytecode or something when i Log it. And after that it Force Closes because of ArrayStoreException..
Now my question is; is this the best way to do this? if yes, how can I fix the ArrayStoreException? If no, what are better ways to let my user choose a country (a whole new view maybe)?
Furthermore, how can I register what country someone tapped?
EDIT:
I slightly changed the sample code below and I get an NullPointerException now..
public void KiesLandMenu(){
ArrayAdapter<Land> arrAdapter;
ArrayList<Land> alleLanden = getLanden();
arrAdapter = new ArrayAdapter<Land>(this, android.R.layout.simple_list_item_single_choice, alleLanden);
ListView list = (ListView)findViewById(R.layout.lijstview);
list.setAdapter(arrAdapter);
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> list, View view, int position,
long id) {
Log.e("item clicked", String.valueOf(position));
}
});
}
The NullPointerException is at list.setAdapter(arrAdapter);
Make a layout with a ListView, then set that layout in your onCreate. To make the list, you can do something like:
public class RunTestProject extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); //whatever you want your layout to be
}
// getLanden() implementation goes here
public void KiesLandMenu(){
ArrayList<Land> alleLanden = getLanden();
arrAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice, alleLanden);
Dialog dialog = new Dialog(this);
dialog.setTitle("Kies land");
dialog.setContentView(R.layout.withList); // The dialog layout
ListView list = (ListView) dialog.findViewById(android.R.id.list); //note that it's not simply findViewById
list.setAdapter(arrAdapter);
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> list, View view, int position,
long id) {
Log.e("item clicked", String.valueOf(position));
}
});
dialog.show();
}
}
When the user chooses on an item, you can see in the log that the item's position in the array is shown.
Your layout file can be something like:
<?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"
>
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>
</LinearLayout>
You could probably extend AlertDialog and give it a ListView as a view. Then bind the ListView to an ListAdapter which uses your ArrayList.
Edit:
ListView lv = new ListView(context);
ArrayAdapter aa = new ListAdapter(context, viewid, lijst);
lv.setAdapter(aa);
AlertDialog ad = new AlertDialog(context);
ad.setView(lv);
There is a bit more work than that though. You need to specify viewid which is the View representing each item in the ListView.
The sdk reference is very good you know.
new AlertDialog.Builder(this)
.setIcon(R.drawable.alert_dialog_icon)
.setTitle(R.string.alert_dialog_single_choice)
.setSingleChoiceItems(<ListAdapter> or CharaSequnce[] , 0, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked on a radio button do some stuff */
}
})
.setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked Yes so do some stuff */
}
})
.setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked No so do some stuff */
}
})
.create();
Note :
Please see This link to Api for Bold text mentioned below
.setSingleChoiceItems(CharacterSequnce[] , 0, new DialogInterface.OnClickListener()....
Hope this helps . Thanks :)

Categories

Resources