I have the following situation:
In my MatchActivity there is a method called executeBustConsequences() which is updating attributes that are included in lists that are the base of my custom RecyclerView.Adapter MatchRecyclerViewAdapter.
After updating the values executeBustConsequences() looks like that:
updateAverages(playerDarts, playerPoints, playerAverage);
// reset boolean, update match view and go to next player
resetMultiplier();
getAdapter().notifyDataSetChanged();
nextPlayer();
Right before getAdapter().notifyDataSetChanged() is executed, getCurrentDart() == 2 and getPlayerIndex() == 0.
Inside the adapter then I see the following attribute values:
getCurrentDart() == 1 and getPlayerIndex() == 1.
At first I didn't understand why that happened, but now I think I do.
This is the method nextPlayer():
private void nextPlayer() {
if (getPlayerIndex() == getMatchParticipants().size()-1) {
setPlayerIndex(0);
} else {
setPlayerIndex(getPlayerIndex() + 1);
}
setCurrentDart(1);
}
To me it looks like nextPlayer() was executed before notifyDataSetChanged() even though nextPlayer() should be executed after notifyDataSetChanged().
Can anybody explain to me why that is the case? Am I missing something obvious?
Related
I have a RecyclerView item on Java that contains several images that will be visible based on some conditions. However, I noticed if most of the conditions are met, many images will be visible and will be out of bound from its parent layout.
Below illustrates how my intention is for this purpose:
The working code is simple for each image in the RecyclerView, e.g.:
if (iJobType == 1) {
imageView1.setVisibility(View.VISIBLE)
} else {
imageView1.setVisibility(View.GONE)
}
if (iJobType == 2) {
imageView2.setVisibility(View.VISIBLE)
} else {
imageView2.setVisibility(View.GONE)
}
However, I'm not sure what to do to only show 3 images once 3 conditions are met. Let's say iJobType given is 1, 2, 3, 4, 5 ,6; that means 6 images will be shown based on such condition, but right now I only need 3 images to be shown.
I hope it's clear enough, feel free to leave comments below to understand this better. Cheers!
What i would do in this case is:
Firstly I will create a getter setter boolean isConditionmeet in Object class which is used in adapter class.
e.g. list is used in Adapter class as:
private ArrayList<MyObject> list;
and the Object class:
public class MyObject
{
private boolean conditionMeet;
public boolean isconditionMeet()
{
return conditionMeet;
}
public void setconditionMeet(boolean conditionMeet)
{
this.conditionMeet = conditionMeet;
}
}
Now whenever condition will meet to show Item, i will set setconditionMeet(true) for that item and conditionMeet is false for other Items. Lastly update adapter to get changes in UI.
I know there are multiple ways to find out if a word is palindromic, like using the reverse function of StringBuilder or even the reverse function of Collections, but in an attempt to learn recursion, I wrote it this way. I even had it working iteratively.
I kind of added return true in my embedded else statement, but I'm really not sure what to do, because when I run this in debug mode, it returns false, then invokes checkPalindrome again, which I don't understand why, because it should return and terminate, no? I would really appreciate an explanation of what I'm doing wrong and how to get it working this way.
public static boolean checkPalindrome(Deque deq) {
if(deq.pollFirst() != deq.pollLast()) {
return false;
} else {
if(deq.size() == 1 || deq.size() == 0) {
return true;
} else {
checkPalindrome(deq);
return true // TODO ?? figure out What to put here ??
}
}
}
It's that you are not returning anything when you call yourself. The inner else statement should read this:
else {
return checkPalindrome(deq);
}
You have a followup question in the comments below that leads me to want to explain how recursive methods work, but in essence, they all follow the following pseudo-code:
public boolean someMethod(T[] someArrayOrList) {
// return true -OR-
// return false -OR-
// call yourself and return whatever that call returns
}
No matter what, when you call the method it will return SOMETHING... Either it will return something itself, or it will return whatever some other call of itself will return. In a way it is AND'ing all the responses, but in reality TRUE is only generated once.
I've created a static Input class, that basicly have a method that I can call, which is this:
public static boolean GetKeyDown(int keyCode) {
while(Keyboard.next()) {
Keyboard.enableRepeatEvents(false);
if (Keyboard.getEventKeyState()) {
if (Keyboard.getEventKey() == keyCode) {
return true;
} else {
return false;
}
}
}
return false;
}
And in my game update loop, I've wanted to use this, instead of having to make a single while-loop:
if(Input.GetKeyDown(KeyCode.S)) {
//Something happens
}
if(Input.GetKeyDown(KeyCode.R)) {
//Something happens
}
//etc..
But it seems that only the first one loaded, will work. In this case 'S'. Is there a way for me to do be able to use the others too?
That is because in your GetKeyDown() method, you call Keyboard.next(), when you call that method it removes the Event of the current key from Keyboard, the only gets refilled with Events, when you call Display.update();
NOTE: This method does not query the operating system for new events. To do that, Display.processMessages() (or Display.update()) must be called first.
Source: LWJGL Docs
You Could
Instead you can use the Keyboard.isKeyDown(int key) method, to achieve what you're trying to do.
Though it returns true/false depending on the following.
Returns: true if the key is down according to the last poll()
But that still doesn't quite fix the problem because it relies on the poll() method.
Fixing The Problem
You can fix the problem by creating some custom methods to use with the Keyboard class, as you already did, though as said the Keyboard Events only gets updated when you call the Display.update(); method.
You already got the right idea about which function to create, though you need to split them into, two different methods. You need a secondary method which you call once each time you want to update your keyboard.
public class MyKeyboard {
/*
* Remember that the index where we store the value,
* is the index of the key. Thereby one key might have
* an index of 400, then your array need to have at least
* the same size, to be able to store it.
*/
public static boolean[] keys = new boolean[100]; // 100 is the amount of keys to remember!
public static void update() {
while(Keyboard.next()) {
if (Keyboard.getEventKey() < keys.length) {
keys[Keyboard.getEventKey()] = Keyboard.getEventKeyState();
}
}
}
public static boolean isKeyDown(int key) {
if ((key > 0) && (key < keys.length)) {
return keys[key];
}
return false;
}
}
Remember to only call the MyKeyboard.update() method once per Display.update() I also renamed your GetKeyDown() method to isKeyDown(), because I think that sounds and describes it better, but you can rename it again in your project if you want to.
The above code was made within this answer, without the use of an IDE, etc. So if there's anything wrong with it I apologize, but just comment and I will fix it.
One problem that arises with this method is the lack of rechecking. Since Keyboard.next() only checks the inputs that have occurred in the current frame. A button which was once pressed will remain "pressed" until it is pressed again. I ran into this problem while trying to implement this solution. The answer to this new problem is here:
public static void update() {
for(int i = 0; i < keys.length; i++) {
keys[i] = false;
}
while(Keyboard.next()) {
keys[Keyboard.getEventKey()] = Keyboard.getEventKeyState();
}
}
You must clear the keypresses of the previous frame by setting everything to false.
I'm currently fixing a bug in someone else's Java code, but I cannot explain the bug. The code in question is the following if-statement:
if (locked && DEBUG_ENABLED
&& owner != null
&& (owner.equals(playerName) || subowner.equals(playerName))
&& handleCommand(playerName, message)) {
....
} else {
....
}
In which DEBUG_ENABLED is initialized as private static boolean DEBUG_ENABLED = false; and handleCommand functions like this:
public boolean handleCommand(String name, String msg) {
if(msg.equals("Command1")) {
....
} else if(msg.equals("Command2")) {
....
} ....
} else { // No matching command
return false;
}
return true;
}
What puzzles me is that even though DEBUG_ENABLED is set to false, the code still calls and executes the handleCommand function. I always thought this wasn't supposed to happen due to short circuiting.
The if-statement itself in total is still evaluated as false, since only the code inside the else-block in the first snippet is executed.
So, how come this if-statement is behaving like this? Is it failing to short-circuit, or do I misunderstand the principle, or is there something completely different wrong with this part of code? (Besides the missing null check for subowner that is, which is done outside of this part.)
It is not possible that the && operator fails to short-circuit. Were you using & perhaps? If not it means you have made some false assumptions that previous conditions before the last one were false.
I'm making an Android app and my implementation of adapter.add() seems to crash the app. I had to use Log tags to find that my code strangely becomes stuck in a loop. Here's the code:
int i =0;
if(cards.size()>0){
Log.i("KOOL","Checked arraylist size =" + cards.size());
while(i < cards.size()){
Log.i("KOOL","Inside while loop");
adapter.add(cards.get(i));
i++;
}
Log.i("KOOL","Added data to adapter");
adapter.notifyDataSetChanged();
Log.i("KOOL","Finished OnActivityResult");
}
The app gets up to the Log tag "Inside while loop" and repeats it until the app crashes. I know that cards.size() is 2 right before the while loop so i see no reason for the app to crash. Am I using the adapter correctly? Please help!
Your question is missing some context. Luckily I know that your adapter is of type ArrayAdapter and its being initialized with cards. When your loop starts, cards.size() is 2. But then you add something to it, making cards.size() be 3. And then... I guess you get the point. You either add something to your adapter/list pair through the adapters add, or through your list add. If you add it to both, then you are adding it two times.
Here is the code for ArrayAdapter::add:
public void add(T object) {
synchronized (mLock) {
if (mOriginalValues != null) {
mOriginalValues.add(object);
} else {
mObjects.add(object);
}
}
if (mNotifyOnChange) notifyDataSetChanged();
}
where mOriginalValues is the very same list you used to construct the adapter. mObjects is a filtered version of them.