diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java index 0ae3b8b8c..33f4e6983 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java @@ -10,6 +10,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; @@ -24,6 +25,7 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver; import androidx.recyclerview.widget.RecyclerView.ItemAnimator; +import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener; import androidx.recyclerview.widget.SimpleItemAnimator; import butterknife.BindView; import butterknife.ButterKnife; @@ -156,6 +158,50 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl } } }); + + //Fab close on touch outside (Scrolling or taping on item triggers this action). + rvContributionsList.addOnItemTouchListener(new OnItemTouchListener() { + + /** + * Silently observe and/or take over touch events sent to the RecyclerView before + * they are handled by either the RecyclerView itself or its child views. + */ + @Override + public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { + if (e.getAction() == MotionEvent.ACTION_DOWN) { + if (isFabOpen) { + animateFAB(isFabOpen); + } + } + return false; + } + + /** + * Process a touch event as part of a gesture that was claimed by returning true + * from a previous call to {@link #onInterceptTouchEvent}. + * + * @param rv + * @param e MotionEvent describing the touch event. All coordinates are in the + * RecyclerView's coordinate system. + */ + @Override + public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { + //required abstract method DO NOT DELETE + } + + /** + * Called when a child of RecyclerView does not want RecyclerView and its ancestors + * to intercept touch events with {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}. + * + * @param disallowIntercept True if the child does not want the parent to intercept + * touch events. + */ + @Override + public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { + //required abstract method DO NOT DELETE + } + + }); } private int getSpanCount(final int orientation) { diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java index 558e6244f..721982d0f 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java @@ -8,6 +8,7 @@ import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween; import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT; import android.Manifest; +import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -28,6 +29,7 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; @@ -445,14 +447,41 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment } /** - * Creates bottom sheet behaviours from bottom sheets, sets initial states and visibility + * a) Creates bottom sheet behaviours from bottom sheets, sets initial states and visibility + * b) Gets the touch event on the map to perform following actions: + * if fab is open then close fab. + * if bottom sheet details are expanded then collapse bottom sheet details. + * if bottom sheet details are collapsed then hide the bottom sheet details. + * if listBottomSheet is open then hide the list bottom sheet. */ + @SuppressLint("ClickableViewAccessibility") private void initBottomSheets() { bottomSheetListBehavior = BottomSheetBehavior.from(rlBottomSheet); bottomSheetDetailsBehavior = BottomSheetBehavior.from(bottomSheetDetails); bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); bottomSheetDetails.setVisibility(View.VISIBLE); bottomSheetListBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); + + mapView.setOnTouchListener((v, event) -> { + + // Motion event is triggered two times on a touch event, one as ACTION_UP + // and other as ACTION_DOWN, we only want one trigger per touch event. + + if(event.getAction() == MotionEvent.ACTION_DOWN) { + if (isFABsExpanded) { + collapseFABs(true); + } else if (bottomSheetDetailsBehavior.getState() + == BottomSheetBehavior.STATE_EXPANDED) { + bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + } else if (bottomSheetDetailsBehavior.getState() + == BottomSheetBehavior.STATE_COLLAPSED) { + bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); + } else if (isListBottomSheetExpanded()) { + bottomSheetListBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); + } + } + return false; + }); } public void initNearbyFilter() {