Basically what I'm trying to do is setting the color of the buttons. The "ganzjahrbutton" includes the other buttons. Therefore I wanna change the color of all the buttons (besides the ganzjahrbutton) to the grey color (162,162,162) if it's clicked.
If any of the other buttons is clicked, they should turn green and the ganzjahrbutton should become grey again. It kinda works, but the buttons need to be pressed twice.
Does anybody have an idea why?
switch (v.getId()){
case R.id.ganzjahrbutton:
ganzjahrbtnstate = !ganzjahrbtnstate;
if (ganzjahrbtnstate==true){
ganzjahrbutton.setBackgroundColor(Color.rgb(30,168,1));
fruhlungbutton.setBackgroundColor(Color.rgb(162,162,162));
sommerbutton.setBackgroundColor(Color.rgb(162,162,162));
herbstbutton.setBackgroundColor(Color.rgb(162,162,162));
winterbutton.setBackgroundColor(Color.rgb(162,162,162));
}
else {ganzjahrbutton.setBackgroundColor(Color.rgb(162,162,162));}
break;
case R.id.fruhlingbutton:
fruhlingbtnstate = !fruhlingbtnstate;
if (fruhlingbtnstate==true){fruhlungbutton.setBackgroundColor(Color.rgb(30,168,1));
ganzjahrbutton.setBackgroundColor(Color.rgb(162,162,162)); }
else {fruhlungbutton.setBackgroundColor(Color.rgb(162,162,162));}
break;
case R.id.sommerbutton:
sommerbtnstate = !sommerbtnstate;
if (sommerbtnstate==true){sommerbutton.setBackgroundColor(Color.rgb(30,168,1));
ganzjahrbutton.setBackgroundColor(Color.rgb(162,162,162)); }
else {sommerbutton.setBackgroundColor(Color.rgb(162,162,162));}
break;
case R.id.herbstbutton:
herbstbtnstate = !herbstbtnstate;
if (herbstbtnstate==true){herbstbutton.setBackgroundColor(Color.rgb(30,168,1));
ganzjahrbutton.setBackgroundColor(Color.rgb(162,162,162)); }
else {herbstbutton.setBackgroundColor(Color.rgb(162,162,161));}
break;
case R.id.winterbutton:
winterbtnstate = !winterbtnstate;
if (winterbtnstate==true){winterbutton.setBackgroundColor(Color.rgb(30,168,1));
ganzjahrbutton.setBackgroundColor(Color.rgb(162,162,162)); }
else {winterbutton.setBackgroundColor(Color.rgb(162,162,162));}
break;
Move the lines where you change the boolean states to the end of cases just before break statements
case R.id.ganzjahrbutton:
****FROM HERE*****ganzjahrbtnstate = !ganzjahrbtnstate;****
if (ganzjahrbtnstate==true){
ganzjahrbutton.setBackgroundColor(Color.rgb(30,168,1));
fruhlungbutton.setBackgroundColor(Color.rgb(162,162,162));
sommerbutton.setBackgroundColor(Color.rgb(162,162,162));
herbstbutton.setBackgroundColor(Color.rgb(162,162,162));
winterbutton.setBackgroundColor(Color.rgb(162,162,162));
}
else {ganzjahrbutton.setBackgroundColor(Color.rgb(162,162,162));}
TO HERE*****ganzjahrbtnstate = !ganzjahrbtnstate;****
break;
Related
So I have a POJO with a question, and in my recycler I wanna show a question itself with answers and correct answer should have the background color.
When I try to add background color, items get colored based on some serious magic.
First few items do not get any color, and closer to the bottom of the recycler here is what happens.
enter image description here
The further the better, when I scroll from the bottom to the top, items at the top get the color as well.
public void bind(Question question) {
int correctAnswerNumber = question.getCorrectAnswer();
switch (correctAnswerNumber) {
case 1:
answer1.setBackground(AppCompatResources.getDrawable(context, R.drawable.correct_answer_border));
break;
case 2:
answer2.setBackground(AppCompatResources.getDrawable(context, R.drawable.correct_answer_border));
break;
case 3:
answer3.setBackground(AppCompatResources.getDrawable(context, R.drawable.correct_answer_border));
break;
case 4:
answer4.setBackground(AppCompatResources.getDrawable(context, R.drawable.correct_answer_border));
break;
}
}
The context here is passed from the activity, and I have to ideas what to do.
I tried to remove the logic to the constructor, change the context, address items through holder, didn't change much.
You have a classic case of "stale state from a recycled view item".
Your Problem
You only set the background for a correct answer. When that item view is recycled and used for an incorrect answer, you are not updating it and it keeps the old background that was set on it.
The Solution
Always explicitly set the full state of a recycler item view. In this case, set the background for whatever it should be when it's not a correct answer.
public void bind(Question question) {
int correctAnswerNumber = question.getCorrectAnswer();
// Reset all backgrounds to default before setting the current correct one
answer1.setBackground(getDefaultBackgroundBorder());
answer2.setBackground(getDefaultBackgroundBorder());
answer3.setBackground(getDefaultBackgroundBorder());
answer4.setBackground(getDefaultBackgroundBorder());
switch (correctAnswerNumber) {
case 1:
answer1.setBackground(AppCompatResources.getDrawable(context, R.drawable.correct_answer_border));
break;
case 2:
answer2.setBackground(AppCompatResources.getDrawable(context, R.drawable.correct_answer_border));
break;
case 3:
answer3.setBackground(AppCompatResources.getDrawable(context, R.drawable.correct_answer_border));
break;
case 4:
answer4.setBackground(AppCompatResources.getDrawable(context, R.drawable.correct_answer_border));
break;
}
}
Here is my image button Click action below.
It will show "1 null" after clicked, while holding the button it shows rightAnswer. I want to illustrate the saved string of questionLabel after finishing the holding button.
What I want to do is that define "sharedFact" before Action_down happens and keep that text to show after the user button untouched.
The "rightAnswer" should be only shown while the user holding imageButton
I tried to use normal String text like "test", it works, however String sharedFact = questionLabel.getText().toString();
↑ is not working like what I thought, what is the problem and how to fix?
findViewById(R.id.image_button_check).setOnTouchListener((v, event) -> {
String sharedFact = null;
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
sharedFact = questionLabel.getText().toString();
questionLabel.setText(rightAnswer);
break;
case MotionEvent.ACTION_UP:
//Here is only test "1" is for identify this code is working
//How can I save questionLabel Text before action down but inside click action?
questionLabel.setText(1 + sharedFact);
break;
}
return false;
});
move your definition from inside the function to a class data member.
String sharedFact = null;
onCreate(){
// your code
findViewById(R.id.image_button_check).setOnTouchListener((v, event) -> {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
sharedFact = questionLabel.getText().toString();
questionLabel.setText(rightAnswer);
break;
case MotionEvent.ACTION_UP:
//Here is only test "1" is for identify this code is working
//How can I save questionLabel Text before action down but inside click action?
questionLabel.setText(1 + sharedFact);
sharedFact = null
break;
}
return false;
});
}
I've tried quite a few different tactics to achieve my desired result, but nothing is making these buttons do what they're 'sposed to... Basically I have 14 buttons. Four with the text "X", digitOne, digitTwo, digitThree and digitFour. Then, there are 10 with "1", "2", etc, named "one", "two", etc. All the buttons are tied to the same OnClickListener that will use a switch statement to determine which button was pressed, then find the soonest display button (buttons initially marked "X"), and change that buttons text to the entered digit. What I want to happen is:
Say someone clicks the "5" button. If its the first button pressed, the first "digit" button will change from displaying "X" to "5", and so-on, so-forth. This is not what is happening... In fact, nomatter what I've tried, nothing is happening. Not even an error... An error would be nice, at least I'd know where my logical flaw is -_-. Here's the code:
The button declarations:
one=(Button)findViewById(R.id.button1);
two=(Button)findViewById(R.id.Button2);
three=(Button)findViewById(R.id.Button3);
four=(Button)findViewById(R.id.Button4);
five=(Button)findViewById(R.id.Button5);
six=(Button)findViewById(R.id.Button6);
seven=(Button)findViewById(R.id.Button7);
eight=(Button)findViewById(R.id.Button8);
nine=(Button)findViewById(R.id.Button9);
zero=(Button)findViewById(R.id.Button0);
add=(Button)findViewById(R.id.buttonAdd);
digitOne=(Button)findViewById(R.id.Number1);
digitTwo=(Button)findViewById(R.id.Number2);
digitThree=(Button)findViewById(R.id.Number3);
digitFour=(Button)findViewById(R.id.Number4);
one.setOnClickListener(listener);
two.setOnClickListener(listener);
three.setOnClickListener(listener);
four.setOnClickListener(listener);
five.setOnClickListener(listener);
six.setOnClickListener(listener);
seven.setOnClickListener(listener);
eight.setOnClickListener(listener);
nine.setOnClickListener(listener);
zero.setOnClickListener(listener);
The OnClickListener private inner class (I guess that's what you'd call it. It's inside Activity class):
private OnClickListener listener = new OnClickListener(){
public void onClick(View button) {
switch(button.getId()){
case R.id.Button0:
addANumber(0);
break;
case R.id.button1:
addANumber(1);
break;
case R.id.Button2:
addANumber(2);
break;
case R.id.Button3:
addANumber(3);
break;
case R.id.Button4:
addANumber(4);
break;
case R.id.Button5:
addANumber(5);
break;
case R.id.Button6:
addANumber(6);
break;
case R.id.Button7:
addANumber(7);
break;
case R.id.Button8:
addANumber(8);
break;
case R.id.Button9:
addANumber(9);
break;
}
}
};
And finally, the "addANumber" method being called:
public void addANumber(int i){
if(digitOne.getText()=="X"){
digitOne.setText(i);
}else if(digitTwo.getText()=="X"){
digitTwo.setText(i);
}else if(digitThree.getText()=="X"){
digitThree.setText(i);
}else if(digitFour.getText()=="X"){
digitFour.setText(i);
}
}
I've done this before... I know I'm missing something so blatantly stupid it deserves a smack in the head...
Before all:
digitOne.getText()=="X" should be "X".equals(digitOne.getText())
you need checking for string equality in terms of content, not in term of reference.
Nothing happens because with == none of your if condition is evaluated to true and addANumber() simply results as an empty method
This is a fairly simple question I am sure, but I can't seem to figure out a way around this little thing. First, here is my code:
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
Log.w("Platformer", "primary down");
break;
case MotionEvent.ACTION_UP:
Log.w("Platformer", "primary up");
break;
case MotionEvent.ACTION_POINTER_1_DOWN:
Log.w("Platformer", "secondary down");
break;
case MotionEvent.ACTION_POINTER_1_UP:
Log.w("Platformer", "secondary up");
break;
}
All I wanted it to do was when I pressed down, it would show me in the log whether the primary or secondary pointer was down, and when I release, do the same thing. The problem is, it always works on the down, but on up, whatever the 1st finger that comes up is, regardless of if it was the primary or secondary pointer originally, it returns that the secondary pointer was removed. Any idea around this? I am guessing it is something simple, but I don't know where to look truthfully. Thanks in advance.
WWaldo
ACTION_UP means that the gesture is over, that is, all pointers are up.
ACTION_POINTER_UP means that a non-primary pointer is up, you'll have to check the event to figure out which, i.e.:
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int pointerId = event.getPointerId(pointerIndex)
ACTION_POINTER_1_UP and ACTION_POINTER_2_UP are deprecated now.
You should note that this is extremely buggy on Android versions less than Gingerbread. I find that if I lift the first of two touches and place it back down, the pointers swap index and ID. Very frustrating.
Use getPointerId to get which pointer is being selected.
Edit
To answer the question in the comment, try:
for (int i = 0; i < ev.getPointerCount(); i++) {
switch (ev.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
Log.d(TAG,"down "+ ev.getPointerId(i));
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG,"move "+ ev.getPointerId(i));
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
Log.d(TAG,"up "+ ev.getPointerId(i));
break;
}
}
I am a self taught programmer, so I do not know the proper ways to do things. I have made simple games like asteroids and snake, but in those games, you can easily modify the variables within the keyevent functions. Here is how I did it in my simple Asteroids game:
/*
* key listener events
*/
public void keyReleased(KeyEvent k){
int keyCode = k.getKeyCode();
switch(keyCode){
case KeyEvent.VK_LEFT:
turnLeft = false;
break;
case KeyEvent.VK_RIGHT:
turnRight = false;
break;
case KeyEvent.VK_UP:
accel = false;
break;
case KeyEvent.VK_1:
cls = true;
break;
case KeyEvent.VK_ENTER:
break;
case KeyEvent.VK_SPACE:
fire = false;
}
}
public void keyTyped(KeyEvent K){}
public void keyPressed(KeyEvent k){
int keyCode = k.getKeyCode();
switch(keyCode){
case KeyEvent.VK_LEFT:
turnLeft = true;
break;
case KeyEvent.VK_RIGHT:
turnRight = true;
break;
case KeyEvent.VK_UP:
accel = true;
break;
case KeyEvent.VK_1:
cls = false;
break;
case KeyEvent.VK_ENTER:
clearAllBullets();
break;
case KeyEvent.VK_SPACE:
fire = true;
}
}
If I were to make a more advanced game (with a main menu, options, main game, etc.) How should I do the key/mouse input?
Also, if I were to go into the single-player, should I put all of the gameplay code into one class? Is there a way to put the single player code into a separate class and somehow have the key input still modify the variables and such?
Thank you for your time!
P.S. Any links or source is extremely appreciated. :D
"Is there a way to put the single player code into a separate class and somehow have the key input still modify the variables and such?"
Yes, there is way to encapsulate all event-based behaviours- http://en.wikipedia.org/wiki/Mediator_pattern but, it can make yor code very complicated, so firstly try to implement your game in more "normal" way.
Anyway - you will need other classes, to present domain model of your game (Player, Gameboard, UserInterfaces etc...)