I have a couple of dynamically created EditText fields.
I am trying to disable the fields if the value in another field doesn't match certain criteria.
The issue is that if other criteria is met, the field is disabled properly by setting setEnabled(false);.
Essentially in a part number field, we check if the part number requires a serial number or a lot number.
If the part requires a serial number, the serial number field displays an error, the lot number field is disabled, and the quantity field is set to "1" and disabled
If a lot number is required, the lot number field shows an error and the serial number field is disabled. This works as intended.
public void onTextChanged(#NotNull EditText target, #NotNull Editable s) {
int serialIndex = 4;
int lotIndex = 5;
int quantityIndex = 6;
EditText serial = findViewById(serialIndex);
EditText lot = findViewById(lotIndex);
EditText quantity = findViewById(quantityIndex);
String txt = partNum.getText().toString().toUpperCase();
partNumber = txt;
Global.isSerialized = DatabaseManager.isSerialized(txt);
Global.isLot = DatabaseManager.isLot(txt);
//this is not working. The fields do not get disabled.
if (!Global.isSerialized && !Global.isLot) {
lot.setEnabled(false);
serial.setEnabled(false);
findViewById(id).setNextFocusDownId(quantityIndex);
}
if (txt.equals("")) {
serial.setError(null);
lot.setError(null);
if (!quantity.isEnabled()) {
quantity.setEnabled(true);
quantity.setText("");
}
}
//This is working. The lot number field gets disabled.
if (Global.isSerialized) {
lot.setEnabled(false);
snRequired = true;
serial.setError("Serial Number Required");
quantity.setText("1");
quantity.setEnabled(false);
findViewById(id).setNextFocusDownId(serialIndex);
} else {
snRequired = false;
serial.setError(null);
quantity.setText("");
quantity.setEnabled(true);
}
//this is also working. The serial number field gets disabled.
if (Global.isLot) {
lot.setEnabled(true);
lnRequired = true;
lot.setError("Lot Number Required");
serial.setEnabled(false);
quantity.setText("");
quantity.setEnabled(true);
findViewById(id).setNextFocusDownId(lotIndex);
} else {
lot.setError(null);
lnRequired = false;
}
Any ideas?
I'm surprised this is still an issue. It's been asked before way back in the past: How to set editable true/false EditText in Android programmatically?
Maybe try this and see what comes of it?
I was able to figure it out. Hard coding the field indexes was the wrong approach. I was able to get the proper indexes by using a for loop on a fieldList array, and assigning the indexes to the variables based on the name of the field. Once I did that, I was able to setEnabled(true) or setEnabled(false) as needed without issue.
Related
I'm working on a project that involves creating a Spring Boot REST Application using JDBC Template to access a database of my own creation (MySQL). I'm using Postman to verify endpoints and entering data using JSON through postman. I'm currently tasked with creating a guessing game that generates a random 4 digit number, easy enough. My issue is this; " Returns a specific game based on ID. Be sure in-progress games do not display their answer" I've created a "starter" method that fulfills the requirement, but only at it's most basic level. I cannot operate on an object once it's field's value is changed to "Hidden" as it is no longer a 4 digit number. I'd like to hide the answer while still being able to operate in a functional manner on the randomly generate number. Here is my base method for this return:
#Override
public Game gameById(int id) {
Game game = gameDao.getGameById(id);
if (game.getFinished() == false) { // "Hides" the answer
game.setGameAnswer("Hidden");
}
return game;
}
Here is my method that uses the above code in my application:
#PostMapping("/guess")
public ResponseEntity<Game> play( int id, String guess) {
Game game = service.gameById(id); // Get method
if (game == null) {
return new ResponseEntity(null, HttpStatus.NOT_FOUND);
}
Round round = new Round();
round.setGuess(guess);
service.guess(round, game);
return ResponseEntity.ok(game);
}
Any ideas?
EDIT:
Game Object:
public class Game {
int gameId;
String gameAnswer;
Boolean finished;
List<Round> Rounds = new ArrayList<>();
I will also include the database game table which i am storing said fields into:
CREATE TABLE game(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
gameAnswer CHAR(4) NOT NULL,
finished BOOLEAN DEFAULT false
);
To clarify my question, when running the game in postman, the game object and it's fields are all displayed as well as the games answer. My goal is to hide this answer as long as the games status reads "false". Once the number has been correctly guessed the status of the game will automatically be set to true.
Here is an example from the JSON output of postman:
{
"gameId": 1,
"gameAnswer": "2651",
"finished": false,
"rounds": [
{
"roundId": 1,
"guess": "1234",
"timeOfGuess": "2021-06-18 09:28:29",
"exactMatch": 0,
"partialMatch": 0,
"gameId": 1
}
]
}
While the "Finished" is set to false, I want the game answer to read "Hidden", but still have the numerical value be present to operate on.
Guess Method:
#Override
public void guess(Round round, Game game) {
// Takes the games generated answer and the user's guess and breaks them down into character array's
round.setGameId(game.getGameId());
char[] gameAnswer = characterBreakDown(game.getGameAnswer());
char[] roundGuess = characterBreakDown(round.getGuess());
// used for comparing the array elements one by one
int min = 0;
int max = 1;
int exact = 0;
boolean run = true;
while (run) {
for (int i = 0; i <= 3; i++) {
if (Arrays.equals(roundGuess, gameAnswer)) {
round.setExactMatch(4);
game.setFinished(true);
gameDao.updateGameById(game);
run = false;
} else if (Arrays.equals(roundGuess, min, max, gameAnswer, min, max)) {
exact++;
round.setExactMatch(exact);
min++;
max++;
if (i == 3 && round.getExactMatch() >= 2) {
round.setPartialMatch(round.getExactMatch());
run = false;
} else if (i == 3) {
run = false;
}
} else if (!Arrays.equals(roundGuess, min, max, gameAnswer, min, max)) {
min++;
max++;
if (i == 3 && round.getExactMatch() >= 2) {
round.setPartialMatch(round.getExactMatch());
run = false;
} else if (i == 3) {
run = false;
}
}
}
}
game.getRounds().add(round);
roundDao.createRound(round);
}
If I understand correctly, your issue is that in one use case (when you are responding to an API request), you want to retrieve a Game and respond to the API request with the Game's "gameAnswer" field hidden, but for other, purely background operations, you want to retrieve the Game with the "gameAnswer" field intact.
Assuming that's the case, I think that your only real issue is where you "blank-out" the "gameAnswer" field.
It looks like you are currently doing that in the "gameById" method of the repository. That results in the gameAnswer being hidden in all cases, right?
So, the solution would be to blank-out the gameAnswer in the controller method instead.
If I have this wrong / backwards I apologize, but the way that you posted your code, in pieces, makes it hard to follow. But anyway, I believe that the solution to your problem is to only blank-out the field where it actually needs to be blanked out. Or if you are having some other issue with it being blanked out / not blanked out because you are doing so in some shared method, perhaps create a new method for the use-case that needs it the other way.
I am creating an Android Studios tasklist app. For some reason, an IF statement is being called even though the expression is false, and thus producing errors at runtime. Code is provided below:
if (taskArray5.get(0).equals( "Goal Time Not Specified") ) {
Log.d("hello", taskArray5.get(0).getClass().toString());
Log.d("hello", taskArray5.get(0));
String[] localTimeList = localTime.split(":");
String previouslySetTime = taskArray5.get(0).substring(0, taskArray5.get(0).length() - 5);
String[] previouslySetTimeList = previouslySetTime.split(":");
Integer localTimeHours = Integer.parseInt(localTimeList[0]);
Integer localTimeMinutes = Integer.parseInt(localTimeList[1]);
Integer localTimeSeconds = Integer.parseInt(localTimeList[2]);
char AMORPM = taskArray5.get(0).charAt(taskArray5.get(0).length() - 4);
Integer previouslySetTimeHours;
if (AMORPM == 'A') {
previouslySetTimeHours = Integer.parseInt(previouslySetTimeList[0]);
} else {
previouslySetTimeHours = Integer.parseInt(previouslySetTimeList[0]) + 12;
}
I used Log.d to confirm that taskArray5.get(0) is a String that has the specific value "Goal Time Not Specified." In addition, using the equals() function also did not solve the problem. What am I doing wrong? Any help is appreciated.
Things to do in this case:
Use breakpoints, simply logging sometimes is not enough, you can miss something, ie, the if is not called when you think it is called or it could be called multiple times
You wrote:
taskArray.get(0) is a String that has the specific value "Goal Time Not Specified.", however you used taskArray5 in the code. Also if it has the specific value, which is required for the condition, is not normal that for that to enter?
I have ten buttons, 0-9 and when one is pressed I want to display its value into a TextView. So the initial display looks like this:
0.00
If I press the 2 button then it should be displayed to the TextView like this:
0.02
Now if I pressed 5 then the new value should be:
0.25
and so on. I've never done anything like this so I'm not exactly sure where to begin. So my question is, whats the best way to implement something like this?
EDIT: I know how to display content when a button is pressed, however, I'm not sure how to transition the each number when a new button is pressed into its new position.
Store an int with the value you are displaying and as you input the number multiply that value by 10 and add the new number on.
Something like:
public void updateValue(int buttonPressed){
currentValue = (currentValue*10) + buttonPressed;
}
then where you're updating the TextView make sure you format the string in a suitable way:
public String formatNum(){
String valueAsString = Integer.toString(currentValue);
while(valueAsString.length()<3){
valueAsString = '0' + valueAsString;
}
char[] stringBuilding = new char[valueAsString.length()+(((valueAsString.length())-2)/3)+1];
int valueAsStringPtr = valueAsString.length()-1;
int stringBuildingPtr = stringBuilding.length-1;
while(stringBuildingPtr>=0){
if(stringBuildingPtr==stringBuilding.length-3){
stringBuilding[stringBuildingPtr--] = '.';
} else if((stringBuilding.length-stringBuildingPtr-3)%4==0){
stringBuilding[stringBuildingPtr--] = ',';
} else {
stringBuilding[stringBuildingPtr--] = valueAsString.charAt(valueAsStringPtr--);
}
}
String returnVal = String.copyValueOf(stringBuilding);
return returnVal;
}
All this assumes you have an integer field currentValue.
Also try to do this on a worker thread ideally to avoid lagging out UI, it shouldn't really take too long, but still a good idea.
Note: for anyone wondering why I elected to use ints instead of float/double is because then we will introduce error displaying a binary representation as a decimal.
Hi I am making an android App, I want to add some values to a database and I want to do N times so I used a for loop as seen below:
private void addCodeToDataBase() {
for (int i = 1; i <= 100; i++) {
//indexnumber is a TextView
indexNumber.setText("Please enter the TAN code for Index number " + i);
//tanCode is an EditText
if (tanCode.getText().toString() != null) {
//index here is just an int so i can use the i inside the onClick
index = i;
//add is a button
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String codeText = tanCode.getText().toString();
dbHandler.addcode(index, codeText);
}
});
} else {
Toast.makeText(addcode.this, "Please enter your code !!!", Toast.LENGTH_LONG).show();
}
}
}
but what I am facing here is the for loop jumps to 100 at the first run, What I mean is the text will show :
Please enter the TAN code for Index number 100
it skips 99 numbers!! how would I fix it ?
It's Because your for loop executes so fast that you can't notice that the change of the text.First i is 0,and then it becomes 1,then the text will be "Please enter the TAN code for Index number 1" ......
your loop is working correctly but it is replacing text on each iteration that's why you think that it is jumping on last value please use break point and debug you will see each value on each iteration or use log in which you will see each value
It's not easy to imagine what your code does without seeing your declarations of indexNumber, tanCode, index, and, in particular, add. So, e.g., we don't know how often your if condition yields true.
However, most probably, the problem is that your assignment add.setOnClickListener(...) is just iterated with no user interaction in between. Now if you repeatedly assign something to your add (whatever that is), the last assignment will win.
If you want 100 buttons, you'll need to have an array or List of buttons to press, where each has a different tan code. If you want one button that repeatedly asks for the different tans, then you have to assign the data for click i + 1 only after click i has been handled, i.e. in the on click listener.
To give more specific help, we would need to know how your user interface should look (how many widgets of what kind) and how each widget should behave.
Just a brief description of what I am doing - I have random equation generator and buttons with all the digits. In order to answer the question the user has to click the corresponding buttons to form the question(digits are written from left to right) e.g. 9 + 6 = user clicks 1 and 5. If the answer is correct another equation should come up. The issue I am encountering for now is that SOMETIMES when the answer is a single digit there is no new equation showing up, nor any errors or something. Just nothing happens. Most of the time this occurs is when the answer is "0". Any idea what might be causing this ? Here is part of the code :
public void checkAnswer(){
int answer = question.getAnswer();
if(ansID2==-1){
if(String.valueOf(answer).equals(String.valueOf(ansID1))){
makeEquation();
}
}else{
if(String.valueOf(answer).equals(String.valueOf(ansID1) + String.valueOf(ansID2))){
makeEquation();
}
}
}
ansID2 is set to be -1 so if the answer is only a single digit the second digit place is skipped. ansID's are assigned when the button with the digit is clicked.
checkAnswer is called from a button "Check Answer" with the following code
EventHandler checkHandler = new EventHandler(){
#Override
public void handle(Event arg0) {
checkAnswer();
}
};
ansID2 is set to -1 in the field declaration
I would do this numerically:
public void checkAnswer(){
int answer = question.getAnswer();
int response = ansID1;
if(ansID2 >= 0) {
response = 10 * response + ansID2;
} // else a one-digit response
if (answer == response) {
makeEquation();
}
}
At minimum, that's more efficient than performing all the string manipulation you do in the original code. With that said, I don't see why this version would produce different results from yours. I'm inclined to suppose that your real problem is elsewhere, such as either the answer or the response digits being incorrect.
In particular, you say
ansID2 is set to -1 in the field declaration
but that's sufficient only until the first question with a two-digit answer, which will cause ansID2 to be set to something else. It (and also ans1ID) should be reset when a new equation is created.