Reputation:
I want to hide progressBar
once all elements in boolean[3]
are true. I am using MutableLiveData
for that. Now progresssBar
is GONE immediately and seems without waiting for all trues. Here is my code.
LeftDrawerAdapter:
if (drawerItemList.get(pos).getTitle().equals(activity.getResources().getString(R.string.statistics_drawer))) {
Dialog dialog = new MyDialog(activity, R.layout.statistics);
ProgressBar progressBar = dialog.findViewById(R.id.bigProgressBar);
MutableLiveData<boolean[]> listen = new MutableLiveData<>();
listen.setValue(new boolean[]{false, false, false});
restModel.getAllUsers(listen.getValue(), dialog.findViewById(R.id.usersRegisteredValue));
restModel.getUsersOnline(listen.getValue(), dialog.findViewById(R.id.usersOnlineValue));
restModel.getMaxNumberOfUsersOnline(listen.getValue(), dialog.findViewById(R.id.maxNumberOnlineValue));
listen.observe((LifecycleOwner)activity, new Observer<boolean[]>() {
@Override
public void onChanged(boolean[] booleans) {
if (Stream.of(booleans).allMatch(val -> true))
progressBar.setVisibility(View.GONE);
}
});
dialog.show();
}
RestModel:
public void getAllUsers(final boolean isThreeStatisticsCallSucceeded[], TextView textView) {
Call<String> result = Api.getClient1Or2().getAllUsers();
result.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if(response.body() != null) {
textView.setText(response.body());
isThreeStatisticsCallSucceeded[0] = true;
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.e("getAllUsers failure", t.toString());
call.clone().enqueue(this);
}
});
}
public void getUsersOnline(boolean isThreeStatisticsCallSucceeded[], TextView textView) {
Call<String> result = Api.getClient1Or2().getUsersOnline();
result.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.body() != null) {
textView.setText(response.body());
isThreeStatisticsCallSucceeded[1] = true;
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.e("getUsersOnline failure", t.toString());
call.clone().enqueue(this);
}
});
}
public void getMaxNumberOfUsersOnline(boolean isThreeStatisticsCallSucceeded[], TextView textView) {
Call<String> result = Api.getClient1Or2().getMaxUsersOnline();
result.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.body() != null) {
textView.setText(response.body());
isThreeStatisticsCallSucceeded[2] = true;
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.e("getMaxNumberOfUsersOnli", t.toString());
call.clone().enqueue(this);
}
});
}
How to solve that?
Upvotes: 1
Views: 273
Reputation: 4536
There are two problems here. First, you cannot easily turn a boolean[]
into a Stream<Boolean>
. In your case, when you write Stream.of(booleans)...
you actually end up with a Stream<boolean[]>
instead, which is not what you want.
Other "direct" approaches don't work either: Arrays.stream(booleans)
will give you a compiler error and Arrays.asList(booleans)
also gives you a Stream<boolean[]>
You can follow the following approach from this answer. You basically transform an IntStream
to a Stream<Boolean>
with this:
Stream<Boolean> stream = IntStream.range(0, foo.length).mapToObj(idx -> foo[idx]);
The second problem is how you're checking if all elements are true
. Currently you have ...allMatch(val -> true)
which returns true
for all elements in the stream, regardless of what the actual value is. You need to return the value itself: ...allMatch(val -> val)
.
In the end, your method should look something like this:
@Override
public void onChanged(boolean[] booleans) {
Stream<Boolean> stream = IntStream.range(0, booleans.length).mapToObj(idx -> booleans[idx]);
if (stream.allMatch(val -> val))
progressBar.setVisibility(View.GONE);
}
Upvotes: 0