1

According this answer , I wanna to show dilaog until the next 10 posts is loaded so I created the static alertDialog method to use it in different places in my app, but the problem is the dialog doesn't cancel or dismiss

setProgressDialog in Utils class

 public static AlertDialog setProgressDialog(Context context) {

        int llPadding = 30;
        LinearLayout ll = new LinearLayout(context);
        ll.setOrientation(LinearLayout.HORIZONTAL);
        ll.setPadding(llPadding, llPadding, llPadding, llPadding);
        ll.setGravity(Gravity.CENTER);
        LinearLayout.LayoutParams llParam = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        llParam.gravity = Gravity.CENTER;
        ll.setLayoutParams(llParam);

        ProgressBar progressBar = new ProgressBar(context);
        progressBar.setIndeterminate(true);
        progressBar.setPadding(0, 0, llPadding, 0);
        progressBar.setLayoutParams(llParam);

        llParam = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        llParam.gravity = Gravity.CENTER;
        TextView tvText = new TextView(context);
        tvText.setText("Loading ...");
        tvText.setTextColor(context.getResources().getColor(R.color.black));
        tvText.setTextSize(20);
        tvText.setLayoutParams(llParam);

        ll.addView(progressBar);
        ll.addView(tvText);

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setCancelable(false);
        builder.setView(ll);

        AlertDialog dialog = builder.create();
        dialog.show();
        Window window = dialog.getWindow();
        if (window != null) {
            WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
            layoutParams.copyFrom(dialog.getWindow().getAttributes());
            layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
            layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
            dialog.getWindow().setAttributes(layoutParams);
        }
        return dialog;
    }

then I used it in HomeFragment on click load more button

binding.loadMoreBtn.setOnClickListener(view -> {

            Utils.setProgressDialog(requireContext());

            if (Utils.hasNetworkAccess(requireContext())) {
                postViewModel.getPosts();
//                Log.w(TAG, "loadMoreBtn: "+dialog.isShowing() );
            } else {
                postViewModel.getAllItemsFromDataBase.getValue();
            }
            Utils.setProgressDialog(requireContext()).cancel();
            Utils.setProgressDialog(requireContext()).dismiss();

        });

PS: I tried also to create dialog AlertDialog dialog = Utils.setProgressDialog(requireContext()); instead to call the method directly then dialod.show(), and after the getPosts cancel or dismiss it but it dosen't appear

Dr Mido
  • 2,414
  • 4
  • 32
  • 72

2 Answers2

1
binding.loadMoreBtn.setOnClickListener(view -> {

        Utils.setProgressDialog(requireContext());

        if (Utils.hasNetworkAccess(requireContext())) {
            postViewModel.getPosts(); //                Log.w(TAG, "loadMoreBtn: "+dialog.isShowing() );
        } else {
            postViewModel.getAllItemsFromDataBase.getValue();
        }
        Utils.setProgressDialog(requireContext()).cancel();
        Utils.setProgressDialog(requireContext()).dismiss();

    });

Here you invoked the static method Utils.setProgressDialog() multiple times; and each time it is called, it returns back a brand new dialog, so you'd dismiss a dialog that is not displayed on the screen.

Instead, you need to store the dialog that is returned from the first call to the method into a variable:

AlertDialog dialog = Utils.setProgressDialog(requireContext());

And then call dismiss on that dialog version: dialog.dismiss() or dialog.cancel() whenever you need to dismiss it.

Zain
  • 37,492
  • 7
  • 60
  • 84
  • I tried this `AlertDialog dialog = Utils.setProgressDialog(requireContext());` then `dialog.show();` and dismiss the dialog dosen't apper, it seems the dialog returns from the method is different than the one created – Dr Mido Oct 08 '21 at 01:00
  • @DrMido As per the code you shared you dismiss the dialog just after you show it; so it does not take the chance to be displayed on the screen.. Instead you need to have a callback when the `postViewModel.getPosts` or when `postViewModel.getAllItemsFromDataBase.getValue()` are finished so that you can dismiss the dialog then. Let me know if something is confusing. – Zain Oct 08 '21 at 01:14
  • If I understand you well, I can't create callback from this method `postViewModel.getPosts();` becasue it's void inside the viewmodel and contains a rxjava retrofit call, I think this well' make the problem too complecated to just show dialog with progressbar, at the first time I show the dialog with progressbar but it dosen't dismiss, at the second time when I use `AlertDialog dialog = Utils.setProgressDialog(requireContext());` it dosen't seen at all :"D, there's something missing – Dr Mido Oct 08 '21 at 01:27
  • @DrMido If you just want to see it at the second option, just remove `dialog.dismiss()` and `dialog.cancel()` :) – Zain Oct 08 '21 at 01:29
  • 1
    thanks I got it, I'll search about how to detect if Response call finished to dismiss it – Dr Mido Oct 08 '21 at 01:38
  • 1
    Cool.. I would suggest to search for the java listener interface callback. It is the simplest one.. Good luck! – Zain Oct 08 '21 at 01:41
0

I fixed it by adding a flag boolean in the viewmodel to detect loading state

public final MutableLiveData<Boolean> isLoading = new MutableLiveData<>();

and use it in getPosts() like this

public void getPosts() {
        Log.e(TAG, finalURL.getValue());

        isLoading.setValue(true);
        repository.remoteDataSource.getPostList(finalURL.getValue())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Response<PostList>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull Response<PostList> postListResponse) {

                        if (postListResponse.isSuccessful()) {
                            if (postListResponse.body() != null
                                    && postListResponse.body().getNextPageToken() != null) {
                                Log.e(TAG, postListResponse.body().getNextPageToken());
                                token.setValue(postListResponse.body().getNextPageToken());
                                isLoading.setValue(false);
                            }
                            postListMutableLiveData.setValue(postListResponse.body());

and finally in the fragment on button click

binding.loadMoreBtn.setOnClickListener(view -> {
            AlertDialog dialog = Utils.setProgressDialog(requireContext());

            postViewModel.isLoading.observe(getViewLifecycleOwner(), isLoading -> {
                if (isLoading) {
                    dialog.show();
                } else {
                    dialog.dismiss();
                }
            });

            if (Utils.hasNetworkAccess(requireContext())) {
                postViewModel.getPosts();
                Log.w(TAG, "loadMoreBtn: " + dialog.isShowing());
            } else {
                postViewModel.isLoading.postValue(true);
                postViewModel.getAllItemsFromDataBase.getValue();
                postViewModel.isLoading.postValue(false);
            }

        });
Dr Mido
  • 2,414
  • 4
  • 32
  • 72