1

I was using MVP in a previous application with my View component essentially an RelativeLayout.

Anytime I would want to block any touch interaction on the RelativeLayout (for example while a network access) I would return true from touchIntercept like this.

public abstract class RootView<T> extends RelativeLayout implements BaseView<T> {

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mIsScreenLocked)
            return true;
        else
            return super.onInterceptTouchEvent(ev);
    }

  @Override
public void showProgress(boolean show, boolean lockScreen) {
    ProgressBar progressBar = ((ProgressBar) findViewById(R.id.progress_bar));

    if (progressBar != null) {
        if (show) {
            progressBar.setVisibility(View.VISIBLE);
        } else {
            progressBar.setVisibility(View.GONE);
        }
    }
    mIsScreenLocked = lockScreen;
    freezeBottomBar(show);

}
}

In my new application my views are Fragments , the base of which extends a fragment

public abstract class BaseFragment
{

}

I would like to achieve something similar , to block all touch interactions on the fragment when a user initiates any network access.

public abstract class BaseFragment
    {

@Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mIsScreenLocked = true;
        initializeControls();
        attachListeners();

        if (savedInstanceState == null)
            onScreenInitializationComplete(getArguments());
        else
            onScreenInitializationComplete(getArguments(), savedInstanceState);

        ***createTouchInterceptor***(view);

        //should we run ignition here?
    }

    private void createTouchInterceptor(View fragmentView) {
        fragmentView.setOnTouchListener((view, motionEvent) -> {
            if (mIsScreenLocked)
                return true;
            else
                return false;
        });

    }     
    }

This ofcourse wont work , since when a button is pressed on the fragment , the button would receive the touch.

Any ideas?

Muhammad Ahmed AbuTalib
  • 4,080
  • 4
  • 36
  • 59

1 Answers1

0

I am not sure that this is the best idea from a UX point of view, since the user doesn't really know why his/her actions are doing nothing, but for the sake of answering the question you can either

  • Use the same solution as you did for the RelativeLayout with the top container ViewGroup in your fragment's view.
  • disable setEnabled(false) only the "clickable" views, like buttons...etc, other views like TextViews and such, don't need to be disabled
    • Use an overlay transparent view, a view that is fully transparent over your root view that consumes the events in case of your fragment being disbaled.

However, you might want to consider a different approach such as

  • Showing a blocking progress dialog
  • Only disabling the button in question and let the user touch other views
elmorabea
  • 3,243
  • 1
  • 14
  • 20
  • I agree with you when you say that the user would be lost and would think that the application has stuck. I actually skipped some code in the snippet. I did display a progress dialog. As you can see the showProgress method was the one which instructed the view to start intercepting. I like your blocking progress dialog suggestion. Never heard of it before. Any pointers? – Muhammad Ahmed AbuTalib Dec 20 '17 at 17:52
  • use setCanceledOnTouchOutside(false), setCancellable(false) on your progress dialog – elmorabea Dec 20 '17 at 17:55
  • elmorbea. Thanks for your aid. I however took the approach listed here as the selected answerhttps://stackoverflow.com/questions/36918219/how-to-disable-user-interaction-while-progressbar-is-visible-in-android – Muhammad Ahmed AbuTalib Dec 20 '17 at 18:04