user21597761
user21597761

Reputation:

Android listen for all boolean[] elements to be true

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

Answers (1)

QBrute
QBrute

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

Related Questions