LayoutManager findCompletelyVisibleItemPosition returns wrong values - java

I have this code below, my adapter and my LayoutManager (Grid) are set above this code, but the values returned by
findLastCompletelyVisibleItemPosition
are sometimes wrong (returns 1 instead of 5 for example)
I think this method is little bugged,
how can i get the good values ?
holder.mRecyclerViewImage.postDelayed(new Runnable() {
#Override
public void run() {
if (holder.mLastVisibleItems == -1)
holder.mLastVisibleItems = holder.mGridLayoutManager.findLastCompletelyVisibleItemPosition();
Log.d("myItemPosition", holder.mLastVisibleItems + "");
if (holder.mLastVisibleItems == 0 || holder.mLastVisibleItems == -1)
return;
int deleted = 0;
ArrayList<String> saveList = new ArrayList<>(listUrlImg);
while (holder.mLastVisibleItems + 1 < listUrlImg.size()) {
listUrlImg.remove(holder.mLastVisibleItems + 1);
deleted++;
}
holder.mRecyclerViewImage.setAdapter(new ImageAdapter(saveList, listUrlImg, deleted));
}
}, 100);

Related

How can I increment the variable more than one time when sensor event changed?

As you can see that I am trying to increment the variable 'c' when the accelerometer z-axis value greater than 12. But I can do it at one time, it will change the value 0 to 1 after executing the program. But I want to collect how many times the z-axis value becomes more than 12.
#Override
public void onSensorChanged (SensorEvent event) {
textView.setText(event.values[0] + "");
textView1.setText(event.values[1] + "");
textView2.setText(event.values[2] + "");
String s = new String();
s = textView2.getText().toString().trim();
Float t = Float.parseFloat(s);
int c = 0;
if (t > 11) {
c++;
txt.setText(Integer.toString(c));
}
}
int counter = 0;
#Override
public void onSensorChanged (SensorEvent event) {
textView.setText(event.values[0] + "");
textView1.setText(event.values[1] + "");
textView2.setText(event.values[2] + "");
String s = new String();
s = textView2.getText().toString().trim();
Float t = Float.parseFloat(s);
int c = 0; // ???
if (t > 11) {
c++;
counter++;
txt.setText(Integer.toString(c));
System.out.println("I need to learn how to use global
variables.\n
also the thing has been greater than \"12\"
"+counter" times."
);
}
}
Also maybe using more meaningful variable names other than "textView#" would make it less of a pain for people to figure out what you're trying to do.
You can define the variable c as a field member like below:
public class MainActivity {
private int c = 0;
(...)
#Override
public void onSensorChanged (SensorEvent event) {
textView.setText(event.values[0] + "");
textView1.setText(event.values[1] + "");
textView2.setText(event.values[2] + "");
String s = new String();
s = textView2.getText().toString().trim();
Float t = Float.parseFloat(s);
if (t > 11) {
c++;
txt.setText(Integer.toString(c));
}
}
}

Display two number pickers on textview

I made a created two number pickers to fake as timepicker for the simple purpose of been able to rotate 0 - 30 repeatedly, which works.
But now I want to display these two number pickers to a textview.
So if the numberpickers shows what's in the image below:
enter image description here
then the timeoutput should display this:
enter image description here
Here's my code:
public void timepicker() {
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue(3);
mMinuteSpinner.setDisplayedValues(new String[]{"00", "30", "00", "30"});
mMinuteSpinner.setOnValueChangedListener(this);
mHourSpinner.setMinValue(0);
mHourSpinner.setMaxValue(23);
String[] hours = new String[24];
for (int i = 0; i < 24; i++) {
hours[i] = String.format("%02d", i );
}
mHourSpinner.setDisplayedValues(hours);
}
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
boolean advanced = (newVal == 0 && oldVal == 3) || (newVal == 2 && oldVal == 1);
boolean regressed = (newVal == 3 && oldVal == 0) || (newVal == 1 && oldVal == 2);
if (advanced) {
mHourSpinner.setValue(mHourSpinner.getValue() + 1);
} else if (regressed) {
mHourSpinner.setValue(mHourSpinner.getValue() - 1);
}
I also tried variations of below:
timeoutput.setText("" + mHourSpinner.getValue() + "h" + mMinuteSpinner.getValue());
But it didn't work. Getvalue seems to get the position of the number instead of the actual number.
The change to display textview also seems to only happen when the user rotates the numbers on the right(minutes), when the change should also occur if they rotate the numbers on the left(hours)
This is because you did not set onValueChangeListener to mHourSpinner.
Try this instead:
public void timepicker() {
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue(3);
mMinuteSpinner.setDisplayedValues(new String[]{"00", "30", "00", "30"});
mMinuteSpinner.setOnValueChangedListener(this);
mHourSpinner.setMinValue(0);
mHourSpinner.setMaxValue(23);
mHourSpinner.setOnValueChangedListener(this); // Add this line
String[] hours = new String[24];
for (int i = 0; i < 24; i++) {
hours[i] = String.format("%02d", i );
}
mHourSpinner.setDisplayedValues(hours);
}
And for your onValueChangeListener, instead of reading the oldVal and newVal of from any of the spinners, you get the value directly from the spinners like this:
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
//Remove the unnecessary lines and just update the value
timeoutput.setText(mHourSpinner.getDisplayedValue()[mHourSpinner.getValue()] + "h" + mMinuteSpinner.getDisplayedValue()[mMinuteSpinner.getValue()]);
}
Root cause
When you select the mHourSpinner, nothing happens because you forgot to call setOnValueChangedListener on it.
getValue() just return the value of the Picker not displayed value, you must use getDisplayedValues() to do that.
Solution: Change your code to
public void timepicker() {
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue(3);
mMinuteSpinner.setDisplayedValues(new String[]{"00", "30", "00", "30"});
mMinuteSpinner.setOnValueChangedListener(this);
mHourSpinner.setMinValue(0);
mHourSpinner.setMaxValue(23);
String[] hours = new String[24];
for (int i = 0; i < 24; i++) {
hours[i] = String.format("%02d", i);
}
mHourSpinner.setDisplayedValues(hours);
mHourSpinner.setOnValueChangedListener(this);
displaySelectedHourAndMinute();
}
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
displaySelectedHourAndMinute();
}
private void displaySelectedHourAndMinute() {
String hour = mHourSpinner.getDisplayedValues()[mHourSpinner.getValue()];
String minute = mMinuteSpinner.getDisplayedValues()[mMinuteSpinner.getValue()];
timeoutput.setText(hour + "h" + minute);
}

Observe livedata inside a for loop

I want to update a list in my activity that depends on the data of another list. Both the data list are being observed from the activity from the my viewmodel. After I get the data from my firstlist I need to run a for loop on this list to get the required ids and get the data for the second list.
But keeping the livedata observer in the for loop is causing a lot of problems. The for loop runs as expected but the livedata observer is getting called almost double the amount of the for loop. This happens only the first time when the list in being brought from the api. When I do the same operation a second time where the list is cached and is being brought from the database, the problem does not occur. Below is the source code for the problem,
for (int i = 0; i < firstList.size(); i++) {
final String uId = firstList.get(i).item.uid;
final long id = firstList.get(i).item.id;
viewModel.initAnotherItemRepository(uId, id);
viewModel.getSecondItem().observe(this, new Observer<Resource<List<SecondItem>>>() {
#Override
public void onChanged(Resource<List<SecondItem>> listResource) {
if (listResource.data != null) {
secondItemList.addAll(listResource.data);
if (count == firstList.size() - 1) {
//Do something
}
count = count + 1;
}
if (listResource.state == Resource.STATE_FAILURE) {
showLoadingSpinner(false);
}
}
}
);
}
Try to observe SecondItem outside the for loop. It gets data whenever update
viewModel.getSecondItem().observe(this, new Observer<Resource<List<SecondItem>>>() {
#Override
public void onChanged(Resource<List<SecondItem>> listResource) {
if (listResource.data != null) {
secondItemList.addAll(listResource.data);
if (count == firstList.size() - 1) {
//Do something
}
count = count + 1;
}
if (listResource.state == Resource.STATE_FAILURE) {
showLoadingSpinner(false);
}
}
}
);
for (int i = 0; i < firstList.size(); i++) {
final String uId = firstList.get(i).item.uid;
final long id = firstList.get(i).item.id;
viewModel.initAnotherItemRepository(uId, id);
}

HashMap only printing out last value in JTable row

I really tried searching for the solution to this problem, but I cant seem to get it right. I have an application that Im working on, and I would like to print out all of a customers orders in a JTable with rows. So if a customer has three orders I want it to show each order on a separate row.
With this code (the next block) I got it to work, but it's only printing out the last value. So if I have Order 3 attached to a customer, and then add Order 4, it only shows Order 4.
JButton btnHämtaKund = new JButton("Hämta");
btnHämtaKund.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String searchTerm = sökrutaKund.getText();
Customer c = Controller.findCustomer(searchTerm);
String sum = "";
if (c != null) {
if (c.getOrders() != null) {
for (Order tmp : c.getOrders().values()) {
String date = tmp.getDate();
String price = Double.toString(tmp.getPrice());
String rfd = "";
if (tmp.getRdyForDelivery() == true) {
rfd = "Ready for delivery";
} else if (tmp.getRdyForDelivery() == false) {
rfd = "Processing";
}
model.addRow(new String[] {date, price, rfd});
}
txtfieldTestKund.setText(sum);
} else {
txtfieldTestKund.setText("c.getOrders() == null");
}
} else {
txtfieldTestKund.setText("c == null");
}
}
});
Model is my DefaultModelTable.
I also tried with a for-loop like this in case I was overwriting my last row all the time:
for (int i = 0; i < c.getOrders().size(); i++) {
String date = c.getOrders().get(i).getDate();
String price = Double.toString(c.getOrders().get(i).getPrice());
String rfd = "";
if (c.getOrders().get(i).getRdyForDelivery() == true) {
rfd = "Ready for delivery";
} else if (c.getOrders().get(i).getRdyForDelivery() == false) {
rfd = "Processing";
}
Object row[] = {date, price, rfd};
model.addRow(row);
}
but that just gave a Nullpointerexception.
Any ideas what to do? Really thankful for help!
I had to fix a method to increase the key for each Order i added to Customer, looks like I was overwriting the previous with the last one.
private int counter = 0;
public void add(Order o) {
counter += 1;
String newCounter = Integer.toString(counter);
this.orders.put(newCounter, o);
}

junit arrays not equal test

I'm trying to write a test case where my scenario is that two byte arrays should be not equal.
Can I do this with junit?
Or do I have to use something external like Hamcrest? I couldn't change the code in this answer to do the job
Please give a sample.
You can use
assertFalse(Arrays.equals(array1, array2));
If you wanted to check they were equal, I would use the following instead.
assertEquals(Arrays.toString(array1), Arrays.toString(array2));
as this produces a readable output as to what was different rather than just failing.
I prefer doing this the Hamcrest way, which is more expressive:
Assert.assertThat(array1, IsNot.not(IsEqual.equalTo(array2)));
Or the short version with static imports:
assertThat(array1, not(equalTo(array2)));
(The IsEqual matcher is smart enough to understand arrays, fortunately.)
Note that a limited version of Hamcrest is part of the JUnit 4.x distribution, so you don't need to add an external library.
Newer versions of JUnit offer org.junit.Assert.assertArrayEquals(byte[], byte[]), with overloads for other array types. Failures show the first index with a non-match and the differing elements at that index.
I also enjoy assertEquals(Arrays.asList(expected), Arrays.asList(actual)). The Hamcrest-powered rendition mentioned above is probably best.
Here is a possible alternative, which has the advantage of using the same code as assertArrayEquals() :
private void assertArrayNotEquals(byte[] expecteds, byte[] actuals) {
try {
assertArrayEquals(expecteds, actuals);
} catch (AssertionError e) {
return;
}
fail("The arrays are equal");
}
You could do it like this:
assertNotEquals(arrayOne, arrayTwo)
Sorry this is a bit long but it's easy to debug with and you can cut and paste it into your unit test.
private int span = 10;
private boolean equal(byte[] expected, byte[] got) {
final boolean result;
String message = null;
int offset = -1;
int length = -1;
if(expected == null && got == null) {
result = true;
} else if(expected == null || got == null) {
message = "One array is null: " + (expected == null ? "expected" : "got");
result = false;
} else if(expected.length != got.length) {
message = "Lengths differ: expected = " + expected.length + ", got = " + got.length;
result = false;
} else {
length = expected.length;
for(int i = 0; i < length; i++) {
if(expected[i] != got[i]) {
offset = i;
break;
}
}
result = offset == -1;
if(!result) {
message = "Contents differ";
}
}
if(!result) {
System.err.println(message);
if(offset >= 0) {
hexDump("Expected: ", expected, offset, length);
hexDump(" Got: ", got, offset, length);
}
}
return result;
}
private void hexDump(String label, byte[] ba, int offset, int length) {
System.err.print(label);
if(ba == null) {
System.err.println("<null>");
} else if(ba.length == 0) {
System.err.println("<zero-length-array>");
} else {
// <span> bytes either side
final int from = Math.max(0, offset - span);
final int to = Math.min(length, offset + span);
if(from != 0) {
System.err.print("(offset:" + from + ") ");
}
for(int i = from; i < to; i++) {
System.err.printf("%02X ", new Byte(ba[i]));
}
System.err.println();
}
}
#Test
public void testExample() {
assertTrue(equal(new byte[] { 1, 2, 3 }, new byte[] { 1, 8, 3 }));
}

Categories

Resources