mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-28 05:13:53 +01:00
Implement nearby Fabs logic with a small issue
This commit is contained in:
parent
32db7b3239
commit
22662acf65
2 changed files with 196 additions and 8 deletions
|
|
@ -18,6 +18,7 @@ import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
@ -56,6 +57,7 @@ import fr.free.nrw.commons.nearby.mvp.fragments.NearbyParentFragment;
|
||||||
import fr.free.nrw.commons.nearby.mvp.presenter.NearbyParentFragmentPresenter;
|
import fr.free.nrw.commons.nearby.mvp.presenter.NearbyParentFragmentPresenter;
|
||||||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||||
import fr.free.nrw.commons.utils.FragmentUtils;
|
import fr.free.nrw.commons.utils.FragmentUtils;
|
||||||
|
import fr.free.nrw.commons.utils.NearbyFABUtils;
|
||||||
import fr.free.nrw.commons.utils.NetworkUtils;
|
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||||
import fr.free.nrw.commons.utils.PermissionUtils;
|
import fr.free.nrw.commons.utils.PermissionUtils;
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
|
|
@ -71,6 +73,27 @@ import static fr.free.nrw.commons.nearby.NearbyTestFragmentLayersActivity.CONTRI
|
||||||
|
|
||||||
public class NearbyTestLayersFragment extends CommonsDaggerSupportFragment implements NearbyParentFragmentContract.View {
|
public class NearbyTestLayersFragment extends CommonsDaggerSupportFragment implements NearbyParentFragmentContract.View {
|
||||||
|
|
||||||
|
@BindView(R.id.bottom_sheet)
|
||||||
|
View bottomSheetList;
|
||||||
|
|
||||||
|
@BindView(R.id.bottom_sheet_details)
|
||||||
|
View bottomSheetDetails;
|
||||||
|
|
||||||
|
@BindView(R.id.transparentView)
|
||||||
|
View transparentView;
|
||||||
|
|
||||||
|
@BindView(R.id.directionsButtonText)
|
||||||
|
TextView directionsButtonText;
|
||||||
|
|
||||||
|
@BindView(R.id.wikipediaButtonText)
|
||||||
|
TextView wikipediaButtonText;
|
||||||
|
|
||||||
|
@BindView(R.id.wikidataButtonText)
|
||||||
|
TextView wikidataButtonText;
|
||||||
|
|
||||||
|
@BindView(R.id.commonsButtonText)
|
||||||
|
TextView commonsButtonText;
|
||||||
|
|
||||||
@BindView(R.id.fab_plus)
|
@BindView(R.id.fab_plus)
|
||||||
FloatingActionButton fabPlus;
|
FloatingActionButton fabPlus;
|
||||||
|
|
||||||
|
|
@ -80,16 +103,9 @@ public class NearbyTestLayersFragment extends CommonsDaggerSupportFragment imple
|
||||||
@BindView(R.id.fab_gallery)
|
@BindView(R.id.fab_gallery)
|
||||||
FloatingActionButton fabGallery;
|
FloatingActionButton fabGallery;
|
||||||
|
|
||||||
|
|
||||||
@BindView(R.id.fab_recenter)
|
@BindView(R.id.fab_recenter)
|
||||||
FloatingActionButton fabRecenter;
|
FloatingActionButton fabRecenter;
|
||||||
|
|
||||||
@BindView(R.id.bottom_sheet)
|
|
||||||
View bottomSheetList;
|
|
||||||
|
|
||||||
@BindView(R.id.bottom_sheet_details)
|
|
||||||
View bottomSheetDetails;
|
|
||||||
|
|
||||||
@BindView(R.id.bookmarkButtonImage)
|
@BindView(R.id.bookmarkButtonImage)
|
||||||
ImageView bookmarkButtonImage;
|
ImageView bookmarkButtonImage;
|
||||||
|
|
||||||
|
|
@ -192,6 +208,63 @@ public class NearbyTestLayersFragment extends CommonsDaggerSupportFragment imple
|
||||||
fab_close = AnimationUtils.loadAnimation(getActivity(), R.anim.fab_close);
|
fab_close = AnimationUtils.loadAnimation(getActivity(), R.anim.fab_close);
|
||||||
rotate_forward = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_forward);
|
rotate_forward = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_forward);
|
||||||
rotate_backward = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_backward);
|
rotate_backward = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_backward);
|
||||||
|
|
||||||
|
bottomSheetDetailsBehavior.setBottomSheetCallback(new BottomSheetBehavior
|
||||||
|
.BottomSheetCallback() {
|
||||||
|
@Override
|
||||||
|
public void onStateChanged(@NonNull View bottomSheet, int newState) {
|
||||||
|
prepareViewsForSheetPosition(newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
|
||||||
|
if (slideOffset >= 0) {
|
||||||
|
transparentView.setAlpha(slideOffset);
|
||||||
|
if (slideOffset == 1) {
|
||||||
|
transparentView.setClickable(true);
|
||||||
|
} else if (slideOffset == 0) {
|
||||||
|
transparentView.setClickable(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bottomSheetListBehavior.setBottomSheetCallback(new BottomSheetBehavior
|
||||||
|
.BottomSheetCallback() {
|
||||||
|
@Override
|
||||||
|
public void onStateChanged(@NonNull View bottomSheet, int newState) {
|
||||||
|
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||||
|
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove button text if they exceed 1 line or if internal layout has not been built
|
||||||
|
// Only need to check for directions button because it is the longest
|
||||||
|
if (directionsButtonText.getLineCount() > 1 || directionsButtonText.getLineCount() == 0) {
|
||||||
|
wikipediaButtonText.setVisibility(View.GONE);
|
||||||
|
wikidataButtonText.setVisibility(View.GONE);
|
||||||
|
commonsButtonText.setVisibility(View.GONE);
|
||||||
|
directionsButtonText.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
title.setOnLongClickListener(view -> {
|
||||||
|
Utils.copy("place", title.getText().toString(), getContext());
|
||||||
|
Toast.makeText(getContext(), "Text copied to clipboard", Toast.LENGTH_SHORT).show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
title.setOnClickListener(view -> {
|
||||||
|
if (bottomSheetDetailsBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||||
|
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||||
|
} else {
|
||||||
|
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMapFragment(Bundle savedInstanceState) {
|
public void setMapFragment(Bundle savedInstanceState) {
|
||||||
|
|
@ -259,7 +332,6 @@ public class NearbyTestLayersFragment extends CommonsDaggerSupportFragment imple
|
||||||
(this, mapFragment, locationManager);
|
(this, mapFragment, locationManager);
|
||||||
Timber.d("Child fragment attached");
|
Timber.d("Child fragment attached");
|
||||||
nearbyParentFragmentPresenter.nearbyFragmentsAreReady();
|
nearbyParentFragmentPresenter.nearbyFragmentsAreReady();
|
||||||
//checkPermissionsAndPerformAction(this::registerLocationUpdates);
|
|
||||||
initViews();
|
initViews();
|
||||||
nearbyParentFragmentPresenter.setActionListeners(applicationKvStore);
|
nearbyParentFragmentPresenter.setActionListeners(applicationKvStore);
|
||||||
|
|
||||||
|
|
@ -429,6 +501,41 @@ public class NearbyTestLayersFragment extends CommonsDaggerSupportFragment imple
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showFABs() {
|
||||||
|
|
||||||
|
NearbyFABUtils.addAnchorToBigFABs(fabPlus, bottomSheetDetails.getId());
|
||||||
|
fabPlus.show();
|
||||||
|
NearbyFABUtils.addAnchorToSmallFABs(fabGallery, getView().findViewById(R.id.empty_view).getId());
|
||||||
|
NearbyFABUtils.addAnchorToSmallFABs(fabCamera, getView().findViewById(R.id.empty_view1).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides all fabs
|
||||||
|
*/
|
||||||
|
private void hideFABs() {
|
||||||
|
NearbyFABUtils.removeAnchorFromFAB(fabPlus);
|
||||||
|
fabPlus.hide();
|
||||||
|
NearbyFABUtils.removeAnchorFromFAB(fabCamera);
|
||||||
|
fabCamera.hide();
|
||||||
|
NearbyFABUtils.removeAnchorFromFAB(fabGallery);
|
||||||
|
fabGallery.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides camera and gallery FABs, turn back plus FAB
|
||||||
|
* @param isFabOpen
|
||||||
|
*/
|
||||||
|
private void closeFABs( boolean isFabOpen){
|
||||||
|
if (isFabOpen) {
|
||||||
|
fabPlus.startAnimation(rotate_backward);
|
||||||
|
fabCamera.startAnimation(fab_close);
|
||||||
|
fabGallery.startAnimation(fab_close);
|
||||||
|
fabCamera.hide();
|
||||||
|
fabGallery.hide();
|
||||||
|
this.isFabOpen = !isFabOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void displayLoginSkippedWarning() {
|
public void displayLoginSkippedWarning() {
|
||||||
if (applicationKvStore.getBoolean("login_skipped", false)) {
|
if (applicationKvStore.getBoolean("login_skipped", false)) {
|
||||||
|
|
@ -506,6 +613,36 @@ public class NearbyTestLayersFragment extends CommonsDaggerSupportFragment imple
|
||||||
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If nearby details bottom sheet state is collapsed: show fab plus
|
||||||
|
* If nearby details bottom sheet state is expanded: show fab plus
|
||||||
|
* If nearby details bottom sheet state is hidden: hide all fabs
|
||||||
|
* @param bottomSheetState
|
||||||
|
*/
|
||||||
|
public void prepareViewsForSheetPosition(int bottomSheetState) {
|
||||||
|
|
||||||
|
switch (bottomSheetState) {
|
||||||
|
case (BottomSheetBehavior.STATE_COLLAPSED):
|
||||||
|
closeFABs(isFabOpen);
|
||||||
|
if (!fabPlus.isShown()) showFABs();
|
||||||
|
this.getView().requestFocus();
|
||||||
|
break;
|
||||||
|
case (BottomSheetBehavior.STATE_EXPANDED):
|
||||||
|
this.getView().requestFocus();
|
||||||
|
break;
|
||||||
|
case (BottomSheetBehavior.STATE_HIDDEN):
|
||||||
|
mapFragment.getMapboxMap().deselectMarkers();
|
||||||
|
transparentView.setClickable(false);
|
||||||
|
transparentView.setAlpha(0);
|
||||||
|
closeFABs(isFabOpen);
|
||||||
|
hideFABs();
|
||||||
|
if (this.getView() != null) {
|
||||||
|
this.getView().requestFocus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same bottom sheet carries information for all nearby places, so we need to pass information
|
* Same bottom sheet carries information for all nearby places, so we need to pass information
|
||||||
* (title, description, distance and links) to view on nearby marker click
|
* (title, description, distance and links) to view on nearby marker click
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package fr.free.nrw.commons.utils;
|
||||||
|
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||||
|
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
|
||||||
|
public class NearbyFABUtils {
|
||||||
|
/*
|
||||||
|
* Add anchors back before making them visible again.
|
||||||
|
* */
|
||||||
|
public static void addAnchorToBigFABs(FloatingActionButton floatingActionButton, int anchorID) {
|
||||||
|
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams
|
||||||
|
(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
params.setAnchorId(anchorID);
|
||||||
|
params.anchorGravity = Gravity.TOP|Gravity.RIGHT|Gravity.END;
|
||||||
|
floatingActionButton.setLayoutParams(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add anchors back before making them visible again. Big and small fabs have different anchor
|
||||||
|
* gravities, therefore the are two methods.
|
||||||
|
* */
|
||||||
|
public static void addAnchorToSmallFABs(FloatingActionButton floatingActionButton, int anchorID) {
|
||||||
|
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams
|
||||||
|
(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
params.setAnchorId(anchorID);
|
||||||
|
params.anchorGravity = Gravity.CENTER_HORIZONTAL;
|
||||||
|
floatingActionButton.setLayoutParams(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are not able to hide FABs without removing anchors, this method removes anchors
|
||||||
|
* */
|
||||||
|
public static void removeAnchorFromFAB(FloatingActionButton floatingActionButton) {
|
||||||
|
//get rid of anchors
|
||||||
|
//Somehow this was the only way https://stackoverflow.com/questions/32732932
|
||||||
|
// /floatingactionbutton-visible-for-sometime-even-if-visibility-is-set-to-gone
|
||||||
|
CoordinatorLayout.LayoutParams param = (CoordinatorLayout.LayoutParams) floatingActionButton
|
||||||
|
.getLayoutParams();
|
||||||
|
param.setAnchorId(View.NO_ID);
|
||||||
|
// If we don't set them to zero, then they become visible for a moment on upper left side
|
||||||
|
param.width = 0;
|
||||||
|
param.height = 0;
|
||||||
|
floatingActionButton.setLayoutParams(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue