Skip to content

Commit 22662ac

Browse files
committed
Implement nearby Fabs logic with a small issue
1 parent 32db7b3 commit 22662ac

File tree

2 files changed

+196
-8
lines changed

2 files changed

+196
-8
lines changed

app/src/main/java/fr/free/nrw/commons/nearby/NearbyTestLayersFragment.java

Lines changed: 145 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import android.widget.LinearLayout;
1919
import android.widget.ProgressBar;
2020
import android.widget.TextView;
21+
import android.widget.Toast;
2122

2223
import androidx.annotation.NonNull;
2324
import androidx.annotation.Nullable;
@@ -56,6 +57,7 @@
5657
import fr.free.nrw.commons.nearby.mvp.presenter.NearbyParentFragmentPresenter;
5758
import fr.free.nrw.commons.theme.NavigationBaseActivity;
5859
import fr.free.nrw.commons.utils.FragmentUtils;
60+
import fr.free.nrw.commons.utils.NearbyFABUtils;
5961
import fr.free.nrw.commons.utils.NetworkUtils;
6062
import fr.free.nrw.commons.utils.PermissionUtils;
6163
import fr.free.nrw.commons.utils.ViewUtil;
@@ -71,6 +73,27 @@
7173

7274
public class NearbyTestLayersFragment extends CommonsDaggerSupportFragment implements NearbyParentFragmentContract.View {
7375

76+
@BindView(R.id.bottom_sheet)
77+
View bottomSheetList;
78+
79+
@BindView(R.id.bottom_sheet_details)
80+
View bottomSheetDetails;
81+
82+
@BindView(R.id.transparentView)
83+
View transparentView;
84+
85+
@BindView(R.id.directionsButtonText)
86+
TextView directionsButtonText;
87+
88+
@BindView(R.id.wikipediaButtonText)
89+
TextView wikipediaButtonText;
90+
91+
@BindView(R.id.wikidataButtonText)
92+
TextView wikidataButtonText;
93+
94+
@BindView(R.id.commonsButtonText)
95+
TextView commonsButtonText;
96+
7497
@BindView(R.id.fab_plus)
7598
FloatingActionButton fabPlus;
7699

@@ -80,16 +103,9 @@ public class NearbyTestLayersFragment extends CommonsDaggerSupportFragment imple
80103
@BindView(R.id.fab_gallery)
81104
FloatingActionButton fabGallery;
82105

83-
84106
@BindView(R.id.fab_recenter)
85107
FloatingActionButton fabRecenter;
86108

87-
@BindView(R.id.bottom_sheet)
88-
View bottomSheetList;
89-
90-
@BindView(R.id.bottom_sheet_details)
91-
View bottomSheetDetails;
92-
93109
@BindView(R.id.bookmarkButtonImage)
94110
ImageView bookmarkButtonImage;
95111

@@ -192,6 +208,63 @@ public void initViews() {
192208
fab_close = AnimationUtils.loadAnimation(getActivity(), R.anim.fab_close);
193209
rotate_forward = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_forward);
194210
rotate_backward = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_backward);
211+
212+
bottomSheetDetailsBehavior.setBottomSheetCallback(new BottomSheetBehavior
213+
.BottomSheetCallback() {
214+
@Override
215+
public void onStateChanged(@NonNull View bottomSheet, int newState) {
216+
prepareViewsForSheetPosition(newState);
217+
}
218+
219+
@Override
220+
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
221+
if (slideOffset >= 0) {
222+
transparentView.setAlpha(slideOffset);
223+
if (slideOffset == 1) {
224+
transparentView.setClickable(true);
225+
} else if (slideOffset == 0) {
226+
transparentView.setClickable(false);
227+
}
228+
}
229+
}
230+
});
231+
232+
bottomSheetListBehavior.setBottomSheetCallback(new BottomSheetBehavior
233+
.BottomSheetCallback() {
234+
@Override
235+
public void onStateChanged(@NonNull View bottomSheet, int newState) {
236+
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
237+
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
238+
}
239+
}
240+
241+
@Override
242+
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
243+
244+
}
245+
});
246+
247+
// Remove button text if they exceed 1 line or if internal layout has not been built
248+
// Only need to check for directions button because it is the longest
249+
if (directionsButtonText.getLineCount() > 1 || directionsButtonText.getLineCount() == 0) {
250+
wikipediaButtonText.setVisibility(View.GONE);
251+
wikidataButtonText.setVisibility(View.GONE);
252+
commonsButtonText.setVisibility(View.GONE);
253+
directionsButtonText.setVisibility(View.GONE);
254+
}
255+
title.setOnLongClickListener(view -> {
256+
Utils.copy("place", title.getText().toString(), getContext());
257+
Toast.makeText(getContext(), "Text copied to clipboard", Toast.LENGTH_SHORT).show();
258+
return true;
259+
}
260+
);
261+
title.setOnClickListener(view -> {
262+
if (bottomSheetDetailsBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) {
263+
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
264+
} else {
265+
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
266+
}
267+
});
195268
}
196269

197270
public void setMapFragment(Bundle savedInstanceState) {
@@ -259,7 +332,6 @@ public void childMapFragmentAttached() {
259332
(this, mapFragment, locationManager);
260333
Timber.d("Child fragment attached");
261334
nearbyParentFragmentPresenter.nearbyFragmentsAreReady();
262-
//checkPermissionsAndPerformAction(this::registerLocationUpdates);
263335
initViews();
264336
nearbyParentFragmentPresenter.setActionListeners(applicationKvStore);
265337

@@ -429,6 +501,41 @@ public void animateFABs() {
429501
}
430502
}
431503

504+
private void showFABs() {
505+
506+
NearbyFABUtils.addAnchorToBigFABs(fabPlus, bottomSheetDetails.getId());
507+
fabPlus.show();
508+
NearbyFABUtils.addAnchorToSmallFABs(fabGallery, getView().findViewById(R.id.empty_view).getId());
509+
NearbyFABUtils.addAnchorToSmallFABs(fabCamera, getView().findViewById(R.id.empty_view1).getId());
510+
}
511+
512+
/**
513+
* Hides all fabs
514+
*/
515+
private void hideFABs() {
516+
NearbyFABUtils.removeAnchorFromFAB(fabPlus);
517+
fabPlus.hide();
518+
NearbyFABUtils.removeAnchorFromFAB(fabCamera);
519+
fabCamera.hide();
520+
NearbyFABUtils.removeAnchorFromFAB(fabGallery);
521+
fabGallery.hide();
522+
}
523+
524+
/**
525+
* Hides camera and gallery FABs, turn back plus FAB
526+
* @param isFabOpen
527+
*/
528+
private void closeFABs( boolean isFabOpen){
529+
if (isFabOpen) {
530+
fabPlus.startAnimation(rotate_backward);
531+
fabCamera.startAnimation(fab_close);
532+
fabGallery.startAnimation(fab_close);
533+
fabCamera.hide();
534+
fabGallery.hide();
535+
this.isFabOpen = !isFabOpen;
536+
}
537+
}
538+
432539
@Override
433540
public void displayLoginSkippedWarning() {
434541
if (applicationKvStore.getBoolean("login_skipped", false)) {
@@ -506,6 +613,36 @@ public void displayBottomSheetWithInfo(Marker marker) {
506613
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
507614
}
508615

616+
/**
617+
* If nearby details bottom sheet state is collapsed: show fab plus
618+
* If nearby details bottom sheet state is expanded: show fab plus
619+
* If nearby details bottom sheet state is hidden: hide all fabs
620+
* @param bottomSheetState
621+
*/
622+
public void prepareViewsForSheetPosition(int bottomSheetState) {
623+
624+
switch (bottomSheetState) {
625+
case (BottomSheetBehavior.STATE_COLLAPSED):
626+
closeFABs(isFabOpen);
627+
if (!fabPlus.isShown()) showFABs();
628+
this.getView().requestFocus();
629+
break;
630+
case (BottomSheetBehavior.STATE_EXPANDED):
631+
this.getView().requestFocus();
632+
break;
633+
case (BottomSheetBehavior.STATE_HIDDEN):
634+
mapFragment.getMapboxMap().deselectMarkers();
635+
transparentView.setClickable(false);
636+
transparentView.setAlpha(0);
637+
closeFABs(isFabOpen);
638+
hideFABs();
639+
if (this.getView() != null) {
640+
this.getView().requestFocus();
641+
}
642+
break;
643+
}
644+
}
645+
509646
/**
510647
* Same bottom sheet carries information for all nearby places, so we need to pass information
511648
* (title, description, distance and links) to view on nearby marker click
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package fr.free.nrw.commons.utils;
2+
3+
import android.view.Gravity;
4+
import android.view.View;
5+
import android.view.ViewGroup;
6+
7+
import androidx.coordinatorlayout.widget.CoordinatorLayout;
8+
9+
import com.google.android.material.floatingactionbutton.FloatingActionButton;
10+
11+
public class NearbyFABUtils {
12+
/*
13+
* Add anchors back before making them visible again.
14+
* */
15+
public static void addAnchorToBigFABs(FloatingActionButton floatingActionButton, int anchorID) {
16+
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams
17+
(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
18+
params.setAnchorId(anchorID);
19+
params.anchorGravity = Gravity.TOP|Gravity.RIGHT|Gravity.END;
20+
floatingActionButton.setLayoutParams(params);
21+
}
22+
23+
/*
24+
* Add anchors back before making them visible again. Big and small fabs have different anchor
25+
* gravities, therefore the are two methods.
26+
* */
27+
public static void addAnchorToSmallFABs(FloatingActionButton floatingActionButton, int anchorID) {
28+
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams
29+
(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
30+
params.setAnchorId(anchorID);
31+
params.anchorGravity = Gravity.CENTER_HORIZONTAL;
32+
floatingActionButton.setLayoutParams(params);
33+
}
34+
35+
/*
36+
* We are not able to hide FABs without removing anchors, this method removes anchors
37+
* */
38+
public static void removeAnchorFromFAB(FloatingActionButton floatingActionButton) {
39+
//get rid of anchors
40+
//Somehow this was the only way https://stackoverflow.com/questions/32732932
41+
// /floatingactionbutton-visible-for-sometime-even-if-visibility-is-set-to-gone
42+
CoordinatorLayout.LayoutParams param = (CoordinatorLayout.LayoutParams) floatingActionButton
43+
.getLayoutParams();
44+
param.setAnchorId(View.NO_ID);
45+
// If we don't set them to zero, then they become visible for a moment on upper left side
46+
param.width = 0;
47+
param.height = 0;
48+
floatingActionButton.setLayoutParams(param);
49+
}
50+
51+
}

0 commit comments

Comments
 (0)