Android Hangman game - User input - java

I am currently creating a Hangman android application and I am having trouble registering inputted letters and updating the game. I input a letter with the onscreen keyboard into the EditText created, and nothing happens.
Below is the code I am using:
// Setting up user input
input = (EditText) findViewById(R.id.inputguess);
input.setFocusable(true);
input.setFocusableInTouchMode(true);
//Getting user input
input.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
String temp;
String newLetter;
newLetter = input.getText().toString();
temp = (String)enteredText.getText();
if (temp.indexOf(newLetter.toUpperCase(Locale.ENGLISH)) >= 0) {
input.setText("");
return true;
}
input.setText(""); // clearing input
entered += newLetter.toUpperCase(Locale.ENGLISH); // adding inputted letter to the entered string
enteredText.setText(temp + newLetter.toUpperCase(Locale.ENGLISH));
word.setText(hideString(text, newLetter.toUpperCase(Locale.ENGLISH)));
The XML code of my EditText is the following:
<EditText
android:id="#+id/inputguess"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/guessedwords"
android:layout_alignLeft="#+id/button1"
android:layout_marginBottom="24dp"
android:ems="10"
android:hint="#string/guessletter"
android:inputType="text"
android:maxLength="1"
android:singleLine="true"
android:imeOptions="actionDone">
</EditText>
After researching, the only reason I can think of is the type of listener being used, but I am not entirely sure. Any help would be greatly appreciated (Let me know if I should add more of my code).

Actually, the OnKeyListener only works with hardware keyboards. To make use of the software (onscreen) keyboard, you must add a TextWatcher
editText.addTextChangedListener(new TextWatcher() { ... })

Related

I need to enable or disable the POSITIVE button of an AlertDialog based on input fields and dismiss only on good validation

I would like to enable or disable the OK (POSITIVE) button of the AlertDialog with a custom layout such that I can:
Disable the OK button initially
Enable the OK button when all required fields have been entered
Disable the OK button again if a required field has been cleared
Perform validation after the OK button is selected and prevent dismissal upon validation errors
Assume the AlertDialog layout is as follows with one required field description and one optional field age:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<EditText
android:id="#+id/description"
android:hint="Field is required"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="#id/age" />
<EditText
android:id="#+id/age"
android:hint="Optional"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#id/description"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Assume I have a button to kick off the dialog
Button b = findViewById(R.id.main_button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.e(TAG,"button");
View viewcustom = getLayoutInflater().inflate(R.layout.customdialog,null);
EditText edt1 = viewcustom.findViewById(R.id.description);
EditText edt2 = viewcustom.findViewById(R.id.age);
// render alertdialog
}
});
Here is the code. I created a custom layout with 2 EditText fields and require only 1 to be entered. The first is treated as just text that must be present and the second is treated as an optional Age. The final example shows how to add validation and to "not dismiss" after OK is pressed and validation fails.
The OK button is initially disabled and when data is entered in the first text field the OK button is enabled.
By controlling the enable/disable of the positive (OK) button it requires the user to the enter fields necessary (rather than giving them an error when omitted).
Note that when the user clears the same field the OK button is disabled.
You can also add a hint to the EditText field(s) to indicate required (shown in second example).
Note that this was used as reference for the EditText listening (as I linked to in comment).
Finally, the last demo shows if you really wanted to show an error on field validation after the OK button is enabled and pressed. (From here.)
This should be obvious how to expand it to all your EditText fields. And bear in mind you can an condition to enabling the OK button - here it is just at least one character.
Button b = findViewById(R.id.main_button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.e(TAG,"button");
View viewcustom = getLayoutInflater().inflate(R.layout.customdialog,null);
EditText edt1 = viewcustom.findViewById(R.id.description);
EditText edt2 = viewcustom.findViewById(R.id.age);
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this)
.setView(viewcustom)
.setPositiveButton("Ok", (dialogInterface, i) -> {
String d = edt1.getText().toString();
String a = edt2.getText().toString();
Toast.makeText(MainActivity.this,d, Toast.LENGTH_LONG).show();
});
alertDialog.setNegativeButton("Cancel", null);
AlertDialog ad = alertDialog.create();
edt1.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence sequence, int i, int i1, int i2) {}
#Override
public void onTextChanged(CharSequence sequence, int i, int i1, int i2) {}
#Override
public void afterTextChanged(Editable editable) {
if (edt1.getText().length() > 0) {
// if user enters anything then enable - modify criteria as desired
ad.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
} else {
// if user deletes entry then back to disabled
ad.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
}
}
});
// Initially OK button is disabled.
ad.show();
ad.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
}
});
And demo:
You can also add a hint to each field to indicate it is required if nothing is entered as in :
<EditText
android:id="#+id/description"
android:hint="Field is required"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="#id/age" />
Finally, if you really, really want to allow the OK but then do further validation to display errors then add the following. Note that the second field is treated as an Age field and the data entered must be an integer. A bit contrived but used to show an example.
// add this after the AlertDialog create()
ad.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface anInterface) {
Button b = ad.getButton(DialogInterface.BUTTON_POSITIVE);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do some validation on edit text
String s = edt2.getText().toString();
try {
Integer age = Integer.valueOf(s);
Toast.makeText(MainActivity.this,d+":"+age, Toast.LENGTH_LONG).show();
ad.dismiss();
} catch (Exception e) {
// complain
Toast.makeText(MainActivity.this, "Age must be an integer", Toast.LENGTH_LONG).show();
}
}
});
}
});
And demo of requiring the optional Age to be an integer:

EditText Crashes App When It Set to Empty ( Android )

I have an EditText and when I set it to Empty and Click on my Button, my App crashes.
When I view it in Android Monitor it points to the line:
final int addTm = Integer.parseInt(Teaching);
Here is my code:
LinearLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="" />
<EditText
android:id="#+id/tM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginRight="50dp"
android:ems="1"
android:inputType="number"
android:maxLength="1"
android:text="0" />
<Button
android:id="#+id/submitBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit" />
</LinearLayout>
And my Java Code:
Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String Teaching = Tm.getText().toString();
final int addTm = Integer.parseInt(Teaching);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("sub").child("TM");
myRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer currentValue = mutableData.getValue(Integer.class);
if (currentValue == null) {
mutableData.setValue(0);
} else {
mutableData.setValue(currentValue + addTm);
}
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
System.out.println("Transaction completed");
}
});
}
});
The other answers are good, but I'd recommend wrapping with a try/catch for the NumberFormatException. I know you have the input set to accept numbers only, but always better safe than sorry.
Lowercase the String variable Teaching. In Java we only upper case Type names. (classes, interfaces, etc.) Notice how StackOverflow is highlighting the variable Teaching blue, a bit disorienting no?
Do this for your member fields as well Tm and Submit. They should be written tm and submit. Also, Tm is not a very descriptive name for a variable either. Imagine another programmer coming in and looking at your code, and wondering what a tm is. What is the context of this tm, where does it come from... what does it do? Is it a Teenage Mutant?
Regardless when using Integer.parseInt wrap it in a try/catch:
#Override
public void onClick(View view){
final int addTm;
try {
String teaching = Tm.getText().toString();
addTm = Integer.parseInt(teaching);
} catch (NumberFormatException e) {
addTm = 0;
}
// ...
}
Why should you do this? What if I enter a decimal number into your number input?
Using your accepted answer you will still crash. Integer.parseInt does not parse decimal numbers.
Or how about, if I switch the locale of the device and enter a number with odd characters that Integer.parseInt won't expect.
Gotta catch that exception to be full proof.
When executing Integer.parseInt() on an empty string it throws an NumberFormatException.
First, check the value of Teaching, and verify it's not empty string, or - try/catch for NumberFormatException, and set the value you want for Teaching in that case.

How to force a single line input in an Alert Dialog?

I have this AlertDialog showing up when the user presses the floating button. I don't want the user to be able to insert a multiple line input (i.e. ignoring her if she tries to press the enter key). How do I do this? Here's my code:
final EditText input = new EditText(getActivity());
new AlertDialog.Builder(getActivity()).setTitle("Package creation").setMessage("Insert package name:").setView(input).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
CharSequence toastText;
if (input.length() > 0) {
/* save the package name in the database */
toastText = getString(R.string.toast_package_saved);
} else toastText = getString(R.string.toast_empty_text);
Toast toast = Toast.makeText(getActivity(), toastText, Toast.LENGTH_SHORT);
toast.show();
input.getText().clear();
}
}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// do nothing
}
}).show();
In Xml
Put android:maxLines="1" in the EditText from the input xml layout.
Also choose an InputType, as Frédéric Letellier mentionated in his answer.
For example, android:inputType="phone"
More info in Specifying the Input Method Type
In Java
input.setMaxLines(1);
input.setInputType(InputType.TYPE_CLASS_PHONE);
In these examples, it is showed a setting for phone number. You can view the other types in InputType
ps: Also in xml, you can use android:singleLine="true", but this parameter is deprecated. So the first option sounds better.
Define the maximum of lines alone without changing inputType isn't enough
In your xml, to make it look like single line EditText :
android:maxLines="1"
And to prevent entering a new line :
android:inputType="text"
Which translates programmatically :
input.setMaxLines(1);
input.setInputType(InputType.TYPE_CLASS_TEXT);
Use below attribute for EditText i.e input View
android:ellipsize="end"

TextView attribute in android for displaying intergers?

public void onClick(View v) {
if (v == button1){
counter++;
textView2.setText(Integer.toString(counter));
textView2.setText(counter);
}
}
I have tried to create a program that counts the number of clicks on a button, but for some reason it is not displaying it. Here is my textview component.
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="180dp"
android:layout_alignParentTop="true"
android:layout_above="#+id/button1"
android:layout_toRightOf="#+id/textView1"
android:layout_centerHorizontal="true"
android:textColor="#000000"/>
I can't seem to find an attribute for display the number of clicks. Is this because it interprets it as an interger instead of a string?
textView2.setText(String.valueOf(counter));
This takes your Integer and converts it to its String value, and sets it to your TextView.
try casting your counter variable to string variable and then try assigning it to button text as:
public void onClick(View v) {
if (v == button1){
counter++;
String s=counter.toString();
textView2.setText(S);
}
}
what your code might be doing as of what you have posted you are trying to pass an integer which is creating problem here..

I can't do the key enter Go

I am beginner in android but not in Java , and have a problem.
Took hours losses in my application ignores keyboard to enter and you put the code below.
What I want is that when I do a thing to enter and go. Since it seems redundant and have not optimal OK button when you have an OK in the Enter itself.
t_Num = (EditText) findViewById(R.id.eTT);
...
t_Num.setFocusableInTouchMode(true);
t_Num.requestFocus();
t_Num.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
System.out.println("entra en Onkey" + event.toString());
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)){
tV.setText("OK");
System.out.println("Press OK");
return true;
}
return false;
}
});
Whit this code i get spam the keypress , but not spam the keypress OK.
And XML:
<EditText
android:layout_width="75dp"
android:layout_height="wrap_content"
android:inputType="numberSigned|phone"
android:digits="-0123456789"
android:ems="10"
android:id="#+id/eTT"
android:imeActionLabel="#string/OK"
android:maxLength="6"
android:maxLines="1"
android:layout_alignBottom="#+id/tV2_1"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_toRightOf="#+id/btnOk"
android:layout_toEndOf="#+id/btnOk" />
thanks for help
PD : I search in this page but not get solution , font1 , font2 , etc...
I use search :)
Try this:
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_GO) {
//your code
return true;
}
return false;
}
});
This is if the editText has
android:imeOptions="actionGo"
in its xml. Same should apply with Enter. Just change the EditorInfo action.
EditText is a subclass of TextView.

Categories

Resources