From 975233829a220222300bc08c3e1ae3a0ac2174fb Mon Sep 17 00:00:00 2001 From: Jakob Nixdorf Date: Wed, 5 Jul 2017 12:42:11 +0200 Subject: [PATCH] Add initial implementation of a FloatingActionMenu for future use --- app/build.gradle | 2 +- .../flocke/andotp/FloatingActionMenu.java | 130 ++++++++++++++++++ .../shadowice/flocke/andotp/MainActivity.java | 20 +-- app/src/main/res/anim/fab_close.xml | 18 +++ app/src/main/res/anim/fab_open.xml | 18 +++ app/src/main/res/drawable/ic_camera_white.xml | 9 ++ app/src/main/res/drawable/ic_edit_white.xml | 9 ++ app/src/main/res/drawable/shape_fab_label.xml | 7 + app/src/main/res/layout/activity_main.xml | 8 +- app/src/main/res/layout/fab_menu.xml | 95 +++++++++++++ app/src/main/res/values/colors.xml | 18 +-- app/src/main/res/values/dimens.xml | 13 +- app/src/main/res/values/strings.xml | 2 + 13 files changed, 323 insertions(+), 26 deletions(-) create mode 100644 app/src/main/java/org/shadowice/flocke/andotp/FloatingActionMenu.java create mode 100644 app/src/main/res/anim/fab_close.xml create mode 100644 app/src/main/res/anim/fab_open.xml create mode 100644 app/src/main/res/drawable/ic_camera_white.xml create mode 100644 app/src/main/res/drawable/ic_edit_white.xml create mode 100644 app/src/main/res/drawable/shape_fab_label.xml create mode 100644 app/src/main/res/layout/fab_menu.xml diff --git a/app/build.gradle b/app/build.gradle index 515815bb..df098bfc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,6 +34,7 @@ dependencies { compile 'com.android.support:design:25.3.1' compile 'com.android.support:recyclerview-v7:25.3.1' compile 'com.android.support:cardview-v7:25.3.1' + compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.journeyapps:zxing-android-embedded:3.0.3@aar' compile 'com.google.zxing:core:3.2.1' compile 'commons-codec:commons-codec:1.5' @@ -47,5 +48,4 @@ dependencies { androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2' androidTestCompile 'org.hamcrest:hamcrest-library:1.3' - } diff --git a/app/src/main/java/org/shadowice/flocke/andotp/FloatingActionMenu.java b/app/src/main/java/org/shadowice/flocke/andotp/FloatingActionMenu.java new file mode 100644 index 00000000..3bbf69c8 --- /dev/null +++ b/app/src/main/java/org/shadowice/flocke/andotp/FloatingActionMenu.java @@ -0,0 +1,130 @@ +package org.shadowice.flocke.andotp; + +import android.content.Context; +import android.support.constraint.ConstraintLayout; +import android.support.design.widget.FloatingActionButton; +import android.support.v4.view.ViewCompat; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.view.animation.LinearInterpolator; +import android.widget.LinearLayout; + +public class FloatingActionMenu { + private boolean isFabMenuOpen = false; + + private ConstraintLayout mainLayout; + + private Animation fabOpenAnimation; + private Animation fabCloseAnimation; + + private FloatingActionButton baseFloatingActionButton; + private FloatingActionButton qrFAB; + private FloatingActionButton manualFAB; + + private LinearLayout qrLayout; + private LinearLayout manualLayout; + + private FABHandler fabHandler; + + public FloatingActionMenu(Context context, ConstraintLayout mainLayout) { + this.mainLayout = mainLayout; + + fabOpenAnimation = AnimationUtils.loadAnimation(context, R.anim.fab_open); + fabCloseAnimation = AnimationUtils.loadAnimation(context, R.anim.fab_close); + + baseFloatingActionButton = (FloatingActionButton) mainLayout.findViewById(R.id.baseFloatingActionButton); + + qrFAB = (FloatingActionButton) mainLayout.findViewById(R.id.qrFAB); + manualFAB = (FloatingActionButton) mainLayout.findViewById(R.id.manualFAB); + + qrLayout = (LinearLayout) mainLayout.findViewById(R.id.qrLayout); + manualLayout = (LinearLayout) mainLayout.findViewById(R.id.manualLayout); + + baseFloatingActionButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (isFabMenuOpen) + collapse(); + else + expand(); + } + }); + + qrFAB.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (fabHandler != null) + fabHandler.onQRFabClick(); + collapse(); + } + }); + + manualFAB.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (fabHandler != null) + fabHandler.onManualFabClick(); + collapse(); + } + }); + } + + public void setFABHandler(FABHandler fabHandler) { + this.fabHandler = fabHandler; + } + + public void show() { + mainLayout.setVisibility(View.VISIBLE); + } + + public void hide() { + mainLayout.setVisibility(View.GONE); + } + + public void expand() { + ViewCompat.animate(baseFloatingActionButton) + .rotation(45F) + .withLayer() + .setDuration(300) + .setInterpolator(new LinearInterpolator()) + .start(); + + qrLayout.setVisibility(View.VISIBLE); + manualLayout.setVisibility(View.VISIBLE); + + qrLayout.startAnimation(fabOpenAnimation); + manualLayout.startAnimation(fabOpenAnimation); + + qrFAB.setClickable(true); + manualFAB.setClickable(true); + + isFabMenuOpen = true; + } + + public void collapse() { + ViewCompat.animate(baseFloatingActionButton) + .rotation(0F) + .withLayer() + .setDuration(300) + .setInterpolator(new LinearInterpolator()) + .start(); + + qrLayout.startAnimation(fabCloseAnimation); + manualLayout.startAnimation(fabCloseAnimation); + + qrLayout.setVisibility(View.GONE); + manualLayout.setVisibility(View.GONE); + + qrFAB.setClickable(false); + manualFAB.setClickable(false); + + isFabMenuOpen = false; + + } + + public interface FABHandler { + void onQRFabClick(); + void onManualFabClick(); + } +} diff --git a/app/src/main/java/org/shadowice/flocke/andotp/MainActivity.java b/app/src/main/java/org/shadowice/flocke/andotp/MainActivity.java index 886b2b50..3cddbd9e 100644 --- a/app/src/main/java/org/shadowice/flocke/andotp/MainActivity.java +++ b/app/src/main/java/org/shadowice/flocke/andotp/MainActivity.java @@ -36,7 +36,7 @@ import android.os.Bundle; import android.os.Handler; import android.provider.Settings; import android.support.annotation.NonNull; -import android.support.design.widget.FloatingActionButton; +import android.support.constraint.ConstraintLayout; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v4.view.MenuItemCompat; @@ -61,11 +61,9 @@ import com.google.zxing.integration.android.IntentIntegrator; import org.shadowice.flocke.andotp.ItemTouchHelper.SimpleItemTouchHelperCallback; -import java.util.ArrayList; - public class MainActivity extends AppCompatActivity { private EntriesCardAdapter adapter; - private FloatingActionButton fab; + private FloatingActionMenu floatingActionMenu; private SimpleItemTouchHelperCallback touchHelperCallback; private Handler handler; @@ -242,12 +240,16 @@ public class MainActivity extends AppCompatActivity { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); - fab = (FloatingActionButton) findViewById(R.id.action_scan); - fab.setOnClickListener(new View.OnClickListener() { + floatingActionMenu = new FloatingActionMenu(this, (ConstraintLayout) findViewById(R.id.fab_main_layout)); + floatingActionMenu.setFABHandler(new FloatingActionMenu.FABHandler() { @Override - public void onClick(View view) { + public void onQRFabClick() { scanQRCode(); } + + @Override + public void onManualFabClick() { + } }); final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); @@ -382,14 +384,14 @@ public class MainActivity extends AppCompatActivity { MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item) { - fab.setVisibility(View.GONE); + floatingActionMenu.hide(); touchHelperCallback.setDragEnabled(false); return true; } @Override public boolean onMenuItemActionCollapse(MenuItem item) { - fab.setVisibility(View.VISIBLE); + floatingActionMenu.show(); touchHelperCallback.setDragEnabled(true); return true; } diff --git a/app/src/main/res/anim/fab_close.xml b/app/src/main/res/anim/fab_close.xml new file mode 100644 index 00000000..8e57a6c7 --- /dev/null +++ b/app/src/main/res/anim/fab_close.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/fab_open.xml b/app/src/main/res/anim/fab_open.xml new file mode 100644 index 00000000..4e85075b --- /dev/null +++ b/app/src/main/res/anim/fab_open.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_camera_white.xml b/app/src/main/res/drawable/ic_camera_white.xml new file mode 100644 index 00000000..4745545c --- /dev/null +++ b/app/src/main/res/drawable/ic_camera_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_edit_white.xml b/app/src/main/res/drawable/ic_edit_white.xml new file mode 100644 index 00000000..35a774a5 --- /dev/null +++ b/app/src/main/res/drawable/ic_edit_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/shape_fab_label.xml b/app/src/main/res/drawable/shape_fab_label.xml new file mode 100644 index 00000000..90f59ff7 --- /dev/null +++ b/app/src/main/res/drawable/shape_fab_label.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 55bc0e8c..5c58b8d8 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -44,12 +44,6 @@ - + diff --git a/app/src/main/res/layout/fab_menu.xml b/app/src/main/res/layout/fab_menu.xml new file mode 100644 index 00000000..0669e87f --- /dev/null +++ b/app/src/main/res/layout/fab_menu.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 912cbbe7..5d066822 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,11 +1,13 @@ -#388E3C -#00600F -#CFD8DC -#FFCC00 -#212121 -#727272 -#FFFFFF -#B6B6B6 + #388E3C + #00600F + #CFD8DC + #FFCC00 + #212121 + #727272 + #FFFFFF + #B6B6B6 + + #212121 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index a83456fe..fd1016be 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -5,7 +5,18 @@ 32dp 16dp 16dp - 16dp 0dp + + + 2dp + 8dp + 16dp + 8dp + 16dp + 4dp + 4dp + 8dp + 16dp + 16dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9f0f096c..08c97963 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,6 +32,8 @@ External storage currently not accessible Storage permissions not granted + Enter details + Scan QR-Code Search