initial implementation of the FAB with Speed Dial
authorAndy Scherzinger <info@andy-scherzinger.de>
Mon, 17 Aug 2015 23:34:45 +0000 (01:34 +0200)
committerAndy Scherzinger <info@andy-scherzinger.de>
Mon, 17 Aug 2015 23:34:45 +0000 (01:34 +0200)
res/drawable/fab_label_background.xml [new file with mode: 0644]
res/layout/list_fragment.xml
res/values/colors.xml
res/values/styles.xml
src/com/owncloud/android/ui/activity/FileDisplayActivity.java
src/com/owncloud/android/ui/fragment/ExtendedListFragment.java
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

diff --git a/res/drawable/fab_label_background.xml b/res/drawable/fab_label_background.xml
new file mode 100644 (file)
index 0000000..4460dab
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/black_semi_transparent"/>
+    <padding
+        android:left="@dimen/standard_padding"
+        android:top="4dp"
+        android:right="@dimen/standard_padding"
+        android:bottom="4dp"/>
+    <corners
+        android:radius="2dp"/>
+</shape>
\ No newline at end of file
index 81b5210..1ed1c53 100644 (file)
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:fab="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
+    xmlns:fab="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_weight="1" >
+    android:layout_height="match_parent">
 
     <android.support.v4.widget.SwipeRefreshLayout
         android:id="@+id/swipe_containing_list"
         android:layout_width="match_parent"
-        android:layout_height="match_parent" 
-        android:layout_weight="1"
+        android:layout_height="match_parent"
         android:footerDividersEnabled="false"
         android:visibility="visible" >
         
             </ScrollView>
     </android.support.v4.widget.SwipeRefreshLayout>
 
-</FrameLayout>
\ No newline at end of file
+</FrameLayout>
+    <com.getbase.floatingactionbutton.FloatingActionsMenu
+        android:id="@+id/fab_main"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentEnd="true"
+        fab:fab_addButtonColorNormal="@color/owncloud_blue_accent"
+        fab:fab_addButtonColorPressed="@color/owncloud_blue"
+        fab:fab_addButtonPlusIconColor="@color/white"
+        fab:fab_labelStyle="@style/menu_labels_style"
+        android:layout_marginBottom="@dimen/standard_margin"
+        android:layout_marginRight="@dimen/standard_margin"
+        android:layout_marginEnd="@dimen/standard_margin">
+
+        <com.getbase.floatingactionbutton.FloatingActionButton
+            android:id="@+id/fab_upload"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            fab:fab_size="mini"
+            fab:fab_icon="@drawable/ic_action_upload"
+            fab:fab_colorNormal="@color/owncloud_blue_accent"
+            fab:fab_title="@string/actionbar_upload"
+            fab:fab_colorPressed="@color/owncloud_blue"/>
+
+        <com.getbase.floatingactionbutton.FloatingActionButton
+            android:id="@+id/fab_mkdir"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            fab:fab_size="mini"
+            fab:fab_icon="@drawable/ic_action_create_dir"
+            fab:fab_colorNormal="@color/owncloud_blue_accent"
+            fab:fab_title="@string/actionbar_mkdir"
+            fab:fab_colorPressed="@color/owncloud_blue"/>
+
+        <com.getbase.floatingactionbutton.FloatingActionButton
+            android:id="@+id/fab_upload_from_app"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            fab:fab_size="mini"
+            fab:fab_icon="@drawable/ic_action_upload"
+            fab:fab_colorNormal="@color/owncloud_blue_accent"
+            fab:fab_title="Upload from app"
+            fab:fab_colorPressed="@color/owncloud_blue_bright"/>
+
+    </com.getbase.floatingactionbutton.FloatingActionsMenu>
+</RelativeLayout>
\ No newline at end of file
index f755a1c..d342653 100644 (file)
     <color name="list_item_lastmod_and_filesize_text">#989898</color>
     <color name="black">#000000</color>
     <color name="white">#FFFFFF</color>
+    <color name="fab_white">#fafafa</color>
+    <color name="white_pressed">#f1f1f1</color>
+    <color name="half_black">#808080</color>
+    <color name="black_semi_transparent">#B2000000</color>
     <color name="textColor">#303030</color>
     <color name="drawerMenuTextColor">#000000</color>
     <color name="list_divider_background">#fff0f0f0</color>
index 765ee44..dac28d9 100644 (file)
                <item name="buttonBarStyle">@style/Theme.ownCloud.Dialog.ButtonBar</item>
        </style>
 
+       <style name="menu_labels_style">
+               <item name="android:background">@drawable/fab_label_background</item>
+               <item name="android:textColor">@color/fab_white</item>
+       </style>
+
        <!-- Button Bar hack due to Lollipop bug:
                https://code.google.com/p/android/issues/detail?id=78302
        fix see:
index c9545cf..fdc78d7 100644 (file)
@@ -490,9 +490,7 @@ public class FileDisplayActivity extends HookActivity
         boolean retval = true;
         switch (item.getItemId()) {
             case R.id.action_create_dir: {
-                CreateFolderDialogFragment dialog =
-                        CreateFolderDialogFragment.newInstance(getCurrentDir());
-                dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
+                createFolder();
                 break;
             }
             case R.id.action_sync_account: {
@@ -554,6 +552,34 @@ public class FileDisplayActivity extends HookActivity
         return retval;
     }
 
+    public void createFolder() {
+        CreateFolderDialogFragment dialog =
+                CreateFolderDialogFragment.newInstance(getCurrentDir());
+        dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
+    }
+
+    public void uploadLocalFilesSelected() {
+        Intent action = new Intent(this, UploadFilesActivity.class);
+        action.putExtra(
+                UploadFilesActivity.EXTRA_ACCOUNT,
+                getAccount()
+        );
+        startActivityForResult(action, ACTION_SELECT_MULTIPLE_FILES);
+    }
+
+    public void uploadFromOtherAppsSelected() {
+        Intent action = new Intent(Intent.ACTION_GET_CONTENT);
+        action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
+        //Intent.EXTRA_ALLOW_MULTIPLE is only supported on api level 18+, Jelly Bean
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            action.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+        }
+        startActivityForResult(
+                Intent.createChooser(action, getString(R.string.upload_chooser_title)),
+                ACTION_SELECT_CONTENT_FROM_APPS
+        );
+    }
+
     private void startSynchronization() {
         Log_OC.d(TAG, "Got to start sync");
         if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
index 937a50d..5f9e7e4 100644 (file)
@@ -36,7 +36,10 @@ import android.widget.GridView;
 import android.widget.ListAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
+import android.widget.Toast;
 
+import com.getbase.floatingactionbutton.FloatingActionButton;
+import com.getbase.floatingactionbutton.FloatingActionsMenu;
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.ExtendedListView;
@@ -64,6 +67,11 @@ public class ExtendedListFragment extends Fragment
     private SwipeRefreshLayout mRefreshGridLayout;
     private SwipeRefreshLayout mRefreshEmptyLayout;
     private TextView mEmptyListMessage;
+
+    private FloatingActionsMenu fabMain;
+    private FloatingActionButton fabUpload;
+    private FloatingActionButton fabMkdir;
+    private FloatingActionButton fabUploadFromApp;
     
     // Save the state of the scroll in browsing
     private ArrayList<Integer> mIndexes;
@@ -96,6 +104,21 @@ public class ExtendedListFragment extends Fragment
         return mCurrentListView;
     }
 
+    public FloatingActionButton getFabUpload() {
+        return fabUpload;
+    }
+
+    public FloatingActionButton getFabUploadFromApp() {
+        return fabUploadFromApp;
+    }
+
+    public FloatingActionButton getFabMkdir() {
+        return fabMkdir;
+    }
+
+    public FloatingActionsMenu getFabMain() {
+        return fabMain;
+    }
 
     protected void switchToGridView() {
         if ((mCurrentListView == mListView)) {
@@ -171,6 +194,11 @@ public class ExtendedListFragment extends Fragment
 
         mCurrentListView = mListView;   // list as default
 
+        fabMain = (FloatingActionsMenu) v.findViewById(R.id.fab_main);
+        fabUpload = (FloatingActionButton) v.findViewById(R.id.fab_upload);
+        fabMkdir = (FloatingActionButton) v.findViewById(R.id.fab_mkdir);
+        fabUploadFromApp = (FloatingActionButton) v.findViewById(R.id.fab_upload_from_app);
+
         return v;
     }
 
@@ -320,6 +348,23 @@ public class ExtendedListFragment extends Fragment
     }
 
     /**
+     * Disables FAB.
+     *
+     * Sets the 'visibility' state of the FAB contained in the fragment.
+     *
+     * When 'false' is set, FAB visibility is set to View.GONE programatically,
+     *
+     * @param   enabled     Desired visibility for the FAB.
+     */
+    public void setFabEnabled(boolean enabled) {
+        if(enabled) {
+            fabMain.setVisibility(View.VISIBLE);
+        } else {
+            fabMain.setVisibility(View.GONE);
+        }
+    }
+
+    /**
      * Set message for empty list view
      */
     public void setMessageForEmptyList(String message) {
index df5b34a..5441aea 100644 (file)
@@ -54,7 +54,6 @@ public class LocalFileListFragment extends ExtendedListFragment {
     /** Adapter to connect the data from the directory with the View object */
     private LocalFileListAdapter mAdapter = null;
 
-    
     /**
      * {@inheritDoc}
      */
@@ -79,6 +78,7 @@ public class LocalFileListFragment extends ExtendedListFragment {
         View v = super.onCreateView(inflater, container, savedInstanceState);
         setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
         setSwipeEnabled(false); // Disable pull-to-refresh
+        setFabEnabled(false); // Disable FAB
         setMessageForEmptyList(getString(R.string.local_file_list_empty));
         Log_OC.i(TAG, "onCreateView() end");
         return v;
index 65f8e11..ce9d2e6 100644 (file)
@@ -29,14 +29,19 @@ import android.content.Intent;
 import android.os.Bundle;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.view.ContextMenu;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.ListView;
 import android.widget.PopupMenu;
+import android.widget.Toast;
 
+import com.getbase.floatingactionbutton.FloatingActionsMenu;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.FileDataStorageManager;
@@ -108,6 +113,43 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        Log_OC.i(TAG, "onCreateView() start");
+        View v = super.onCreateView(inflater, container, savedInstanceState);
+
+        // Setup FAB listeners
+        getFabUpload().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                ((FileDisplayActivity)getActivity()).uploadLocalFilesSelected();
+                getFabMain().collapse();
+            }
+        });
+
+        getFabMkdir().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                ((FileDisplayActivity) getActivity()).createFolder();
+                getFabMain().collapse();
+            }
+        });
+
+        getFabUploadFromApp().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                ((FileDisplayActivity) getActivity()).uploadFromOtherAppsSelected();
+                getFabMain().collapse();
+            }
+        });
+
+        Log_OC.i(TAG, "onCreateView() end");
+        return v;
+    }
+
     
     @Override
     public void onDetach() {