Browse Source

Merge pull request #607 from nextcloud/integration-with-master

PNG files have full-screen checkerboard background & Better emptycontent view for file types which can not be shown
Tobias Kaminsky 8 years ago
parent
commit
8ff753f623

+ 3 - 3
src/main/java/com/owncloud/android/media/MediaControlView.java

@@ -39,12 +39,12 @@ import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 import android.widget.TextView;
 
-import java.util.Formatter;
-import java.util.Locale;
-
 import com.owncloud.android.R;
 import com.owncloud.android.utils.DisplayUtils;
 
+import java.util.Formatter;
+import java.util.Locale;
+
 
 /**
  * View containing controls for a {@link MediaPlayer}. 

+ 20 - 58
src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java

@@ -26,17 +26,13 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.os.Build;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.IBinder;
-import android.os.Message;
 import android.support.v4.view.ViewPager;
 import android.support.v4.widget.DrawerLayout;
 import android.support.v7.app.ActionBar;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.Window;
 
 import com.ortiz.touch.ExtendedViewPager;
 import com.owncloud.android.MainApp;
@@ -69,15 +65,12 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 public class PreviewImageActivity extends FileActivity implements
         FileFragment.ContainerActivity,
         ViewPager.OnPageChangeListener, OnRemoteOperationListener {
-    
-    public static final int DIALOG_SHORT_WAIT = 0;
 
     public static final String TAG = PreviewImageActivity.class.getSimpleName();
     
     public static final String KEY_WAITING_TO_PREVIEW = "WAITING_TO_PREVIEW";
     private static final String KEY_WAITING_FOR_BINDER = "WAITING_FOR_BINDER";
-
-    private static final int INITIAL_HIDE_DELAY = 0; // immediate hide
+    private static final String KEY_SYSTEM_VISIBLE = "TRUE";
 
     private ExtendedViewPager mViewPager;
     private PreviewImagePagerAdapter mPreviewImagePagerAdapter;
@@ -92,20 +85,22 @@ public class PreviewImageActivity extends FileActivity implements
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
-
         super.onCreate(savedInstanceState);
 
+        final ActionBar actionBar = getSupportActionBar();
+
+        if (savedInstanceState != null && !savedInstanceState.getBoolean(KEY_SYSTEM_VISIBLE, true) &&
+                actionBar != null) {
+            actionBar.hide();
+        }
+
         setContentView(R.layout.preview_image_activity);
 
         // Navigation Drawer
         setupDrawer();
 
         // ActionBar
-        ActionBar actionBar = getSupportActionBar();
         updateActionBarTitleAndHomeButton(null);
-        actionBar.hide();
-
 
         mFullScreenAnchorView = getWindow().getDecorView();
         // to keep our UI controls visibility in line with system bars visibility
@@ -115,7 +110,6 @@ public class PreviewImageActivity extends FileActivity implements
                     @Override
                     public void onSystemUiVisibilityChange(int flags) {
                         boolean visible = (flags & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
-                        ActionBar actionBar = getSupportActionBar();
                         if (visible) {
                             actionBar.show();
                             setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
@@ -125,11 +119,7 @@ public class PreviewImageActivity extends FileActivity implements
                         }
                     }
                 });
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            getWindow().setStatusBarColor(getResources().getColor(R.color.owncloud_blue_dark_transparent));
-        }
-            
+         
         if (savedInstanceState != null) {
             mRequestWaitingForBinder = savedInstanceState.getBoolean(KEY_WAITING_FOR_BINDER);
         } else {
@@ -164,43 +154,7 @@ public class PreviewImageActivity extends FileActivity implements
             mRequestWaitingForBinder = true;
         }
     }
-    
-    
-    protected void onPostCreate(Bundle savedInstanceState)  {
-        super.onPostCreate(savedInstanceState);
-        
-        // Trigger the initial hide() shortly after the activity has been 
-        // created, to briefly hint to the user that UI controls 
-        // are available
-        delayedHide(INITIAL_HIDE_DELAY);
-        
-    }
-    
-    Handler mHideSystemUiHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            hideSystemUI(mFullScreenAnchorView);
-            getSupportActionBar().hide();
-        }
-    };
-    
-    private void delayedHide(int delayMillis)   {
-        mHideSystemUiHandler.removeMessages(0);
-        mHideSystemUiHandler.sendEmptyMessageDelayed(0, delayMillis);
-    }
-    
-    /// handle Window Focus changes
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus) {
-        super.onWindowFocusChanged(hasFocus);
-        
-        // When the window loses focus (e.g. the action overflow is shown),
-        // cancel any pending hide action.
-        if (!hasFocus) {
-            mHideSystemUiHandler.removeMessages(0);
-        }
-    }
-    
+
     @Override
     public void onStart() {
         super.onStart();
@@ -209,7 +163,8 @@ public class PreviewImageActivity extends FileActivity implements
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
-        outState.putBoolean(KEY_WAITING_FOR_BINDER, mRequestWaitingForBinder);    
+        outState.putBoolean(KEY_WAITING_FOR_BINDER, mRequestWaitingForBinder);
+        outState.putBoolean(KEY_SYSTEM_VISIBLE, getSystemUIVisible());
     }
 
     @Override
@@ -463,6 +418,13 @@ public class PreviewImageActivity extends FileActivity implements
 
     }
 
+    public boolean getSystemUIVisible() {
+        if (getSupportActionBar() != null) {
+            return (getSupportActionBar().isShowing());
+        }
+        return true;
+    }
+
     @SuppressLint("InlinedApi")
     public void toggleFullScreen() {
 
@@ -543,7 +505,7 @@ public class PreviewImageActivity extends FileActivity implements
         anchorView.setSystemUiVisibility(
                 View.SYSTEM_UI_FLAG_LAYOUT_STABLE           // draw full window;     Android >= 4.1
             |   View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN       // draw full window;     Android >= 4.1
-            |   View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION  // draw full window;     Android >= 4.1
+            |   View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION  // draw full window;     Android >= 4.
         );
     }
 }

+ 167 - 107
src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java

@@ -1,33 +1,40 @@
 /**
- *   ownCloud Android client application
- *
- *   @author David A. Velasco
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * ownCloud Android client application
  *
+ * @author David A. Velasco
+ * Copyright (C) 2015 ownCloud Inc.
+ * <p>
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ * <p>
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * <p>
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 package com.owncloud.android.ui.preview;
 
 import android.accounts.Account;
 import android.annotation.SuppressLint;
 import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Color;
 import android.graphics.Point;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.StringRes;
 import android.support.v4.app.FragmentStatePagerAdapter;
+import android.util.DisplayMetrics;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -36,7 +43,9 @@ import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import com.owncloud.android.R;
@@ -61,7 +70,7 @@ import third_parties.michaelOrtiz.TouchImageViewCustom;
  *
  * Trying to get an instance with a NULL {@link OCFile} will produce an
  * {@link IllegalStateException}.
- * 
+ *
  * If the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is generated on
  * instantiation too.
  */
@@ -75,8 +84,13 @@ public class PreviewImageFragment extends FileFragment {
     private static final String SCREEN_NAME = "Image Preview";
 
     private TouchImageViewCustom mImageView;
-    private TextView mMessageView;
-    private ProgressBar mProgressWheel;
+    private RelativeLayout mMultiView;
+
+    protected LinearLayout mMultiListContainer;
+    protected TextView mMultiListMessage;
+    protected TextView mMultiListHeadline;
+    protected ImageView mMultiListIcon;
+    protected ProgressBar mMultiListProgress;
 
     public Bitmap mBitmap = null;
 
@@ -86,7 +100,6 @@ public class PreviewImageFragment extends FileFragment {
 
     private LoadBitmapTask mLoadBitmapTask = null;
 
-
     /**
      * Public factory method to create a new fragment that previews an image.
      *
@@ -101,7 +114,7 @@ public class PreviewImageFragment extends FileFragment {
      *                                  {@link FragmentStatePagerAdapter}
      *                                  ; TODO better solution
      */
-    public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState){
+    public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState) {
         PreviewImageFragment frag = new PreviewImageFragment();
         Bundle args = new Bundle();
         args.putParcelable(ARG_FILE, imageFile);
@@ -111,13 +124,12 @@ public class PreviewImageFragment extends FileFragment {
     }
 
 
-    
     /**
      *  Creates an empty fragment for image previews.
-     * 
+     *
      *  MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
      *  (for instance, when the device is turned a aside).
-     * 
+     *
      *  DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
      *  construction
      */
@@ -133,9 +145,9 @@ public class PreviewImageFragment extends FileFragment {
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         Bundle args = getArguments();
-        setFile((OCFile)args.getParcelable(ARG_FILE));
-            // TODO better in super, but needs to check ALL the class extending FileFragment;
-            // not right now
+        setFile((OCFile) args.getParcelable(ARG_FILE));
+        // TODO better in super, but needs to check ALL the class extending FileFragment;
+        // not right now
 
         mIgnoreFirstSavedState = args.getBoolean(ARG_IGNORE_FIRST);
         setHasOptionsMenu(true);
@@ -152,20 +164,39 @@ public class PreviewImageFragment extends FileFragment {
         View view = inflater.inflate(R.layout.preview_image_fragment, container, false);
         mImageView = (TouchImageViewCustom) view.findViewById(R.id.image);
         mImageView.setVisibility(View.GONE);
-        mImageView.setOnClickListener(new OnClickListener() {
+
+        view.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
                 ((PreviewImageActivity) getActivity()).toggleFullScreen();
+                toggleImageBackground();
             }
+        });
 
+        mImageView.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                ((PreviewImageActivity) getActivity()).toggleFullScreen();
+                toggleImageBackground();
+            }
         });
-        mMessageView = (TextView)view.findViewById(R.id.message);
-        mMessageView.setVisibility(View.GONE);
-        mProgressWheel = (ProgressBar)view.findViewById(R.id.progressWheel);
-        mProgressWheel.setVisibility(View.VISIBLE);
+        
+        mMultiView = (RelativeLayout) view.findViewById(R.id.multi_view);
+
+        setupMultiView(view);
+        setMultiListLoadingMessage();
+
         return view;
     }
 
+    protected void setupMultiView(View view) {
+        mMultiListContainer = (LinearLayout) view.findViewById(R.id.empty_list_view);
+        mMultiListMessage = (TextView) view.findViewById(R.id.empty_list_view_text);
+        mMultiListHeadline = (TextView) view.findViewById(R.id.empty_list_view_headline);
+        mMultiListIcon = (ImageView) view.findViewById(R.id.empty_list_icon);
+        mMultiListProgress = (ProgressBar) view.findViewById(R.id.empty_list_progress);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -203,7 +234,7 @@ public class PreviewImageFragment extends FileFragment {
     public void onStart() {
         super.onStart();
         if (getFile() != null) {
-            mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel);
+            mLoadBitmapTask = new LoadBitmapTask(mImageView);
             //mLoadBitmapTask.execute(new String[]{getFile().getStoragePath()});
 //            mLoadBitmapTask.execute(getFile().getStoragePath());
             mLoadBitmapTask.execute(getFile());
@@ -242,10 +273,10 @@ public class PreviewImageFragment extends FileFragment {
             setFile(mContainerActivity.getStorageManager().getFileById(getFile().getFileId()));
 
             FileMenuFilter mf = new FileMenuFilter(
-                getFile(),
-                mContainerActivity.getStorageManager().getAccount(),
-                mContainerActivity,
-                getActivity()
+                    getFile(),
+                    mContainerActivity.getStorageManager().getAccount(),
+                    mContainerActivity,
+                    getActivity()
             );
             mf.filter(menu);
         }
@@ -303,31 +334,31 @@ public class PreviewImageFragment extends FileFragment {
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
-            case R.id.action_share_file: {
+            case R.id.action_share_file:
                 mContainerActivity.getFileOperationsHelper().showShareFile(getFile());
                 return true;
-            }
-            case R.id.action_open_file_with: {
+            
+            case R.id.action_open_file_with:
                 openFile();
                 return true;
-            }
-            case R.id.action_remove_file: {
+
+            case R.id.action_remove_file:
                 RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(getFile());
                 dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
                 return true;
-            }
-            case R.id.action_see_details: {
+
+            case R.id.action_see_details:
                 seeDetails();
                 return true;
-            }
-            case R.id.action_send_file: {
+
+            case R.id.action_send_file:
                 mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
                 return true;
-            }
-            case R.id.action_sync_file: {
+
+            case R.id.action_sync_file:
                 mContainerActivity.getFileOperationsHelper().syncFile(getFile());
                 return true;
-            }
+
             default:
                 return super.onOptionsItemSelected(item);
         }
@@ -349,9 +380,9 @@ public class PreviewImageFragment extends FileFragment {
         if (mBitmap != null) {
             mBitmap.recycle();
             System.gc();
-                // putting this in onStop() is just the same; the fragment is always destroyed by
-                // {@link FragmentStatePagerAdapter} when the fragment in swiped further than the
-                // valid offscreen distance, and onStop() is never called before than that
+            // putting this in onStop() is just the same; the fragment is always destroyed by
+            // {@link FragmentStatePagerAdapter} when the fragment in swiped further than the
+            // valid offscreen distance, and onStop() is never called before than that
         }
         super.onDestroy();
     }
@@ -365,7 +396,7 @@ public class PreviewImageFragment extends FileFragment {
         finish();
     }
 
-    
+
     private class LoadBitmapTask extends AsyncTask<OCFile, Void, LoadImage> {
 
         /**
@@ -376,24 +407,6 @@ public class PreviewImageFragment extends FileFragment {
          */
         private final WeakReference<ImageViewCustom> mImageViewRef;
 
-        /**
-         * Weak reference to the target {@link TextView} where error messages will be written.
-         *
-         * Using a weak reference will avoid memory leaks if the target ImageView is retired from
-         * memory before the load finishes.
-         */
-        private final WeakReference<TextView> mMessageViewRef;
-
-
-        /**
-         * Weak reference to the target {@link ProgressBar} shown while the load is in progress.
-         * 
-         * Using a weak reference will avoid memory leaks if the target ImageView is retired from
-         * memory before the load finishes.
-         */
-        private final WeakReference<ProgressBar> mProgressWheelRef;
-
-
         /**
          * Error message to show when a load fails
          */
@@ -405,11 +418,8 @@ public class PreviewImageFragment extends FileFragment {
          *
          * @param imageView Target {@link ImageView} where the bitmap will be loaded into.
          */
-        public LoadBitmapTask(ImageViewCustom imageView, TextView messageView,
-                              ProgressBar progressWheel) {
+        public LoadBitmapTask(ImageViewCustom imageView) {
             mImageViewRef = new WeakReference<ImageViewCustom>(imageView);
-            mMessageViewRef = new WeakReference<TextView>(messageView);
-            mProgressWheelRef = new WeakReference<ProgressBar>(progressWheel);
         }
 
         @Override
@@ -443,8 +453,10 @@ public class PreviewImageFragment extends FileFragment {
                             Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
                             break;
                         } else {
-                            // Rotate image, obeying exif tag.
-                            result = BitmapUtils.rotateImage(result, storagePath);
+                            if (ocFile.getMimetype().equalsIgnoreCase("image/jpeg")) {
+                                // Rotate image, obeying exif tag.
+                                result = BitmapUtils.rotateImage(result, storagePath);
+                            }
                         }
 
                     } catch (OutOfMemoryError e) {
@@ -489,14 +501,12 @@ public class PreviewImageFragment extends FileFragment {
 
         @Override
         protected void onPostExecute(LoadImage result) {
-            hideProgressWheel();
             if (result.bitmap != null) {
                 showLoadedImage(result);
-            }
-            else {
+            } else {
                 showErrorMessage();
             }
-            if (result.bitmap != null && mBitmap != result.bitmap)  {
+            if (result.bitmap != null && mBitmap != result.bitmap) {
                 // unused bitmap, release it! (just in case)
                 result.bitmap.recycle();
             }
@@ -510,54 +520,75 @@ public class PreviewImageFragment extends FileFragment {
                 Log_OC.d(TAG, "Showing image with resolution " + bitmap.getWidth() + "x" +
                         bitmap.getHeight());
 
+
                 if (result.ocFile.getMimetype().equalsIgnoreCase("image/png")) {
-                    Drawable backrepeat = getResources().getDrawable(R.drawable.backrepeat);
-                    imageView.setBackground(backrepeat);
+                    if (getResources() != null) {
+                        Resources r = getResources();
+                        Drawable[] layers = new Drawable[2];
+                        layers[0] = r.getDrawable(R.color.white);
+                        Drawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
+                        layers[1] = bitmapDrawable;
+                        LayerDrawable layerDrawable = new LayerDrawable(layers);
+                        layerDrawable.setLayerHeight(0, convertDpToPixel(bitmap.getHeight(), getActivity()));
+                        layerDrawable.setLayerHeight(1, convertDpToPixel(bitmap.getHeight(), getActivity()));
+                        layerDrawable.setLayerWidth(0, convertDpToPixel(bitmap.getWidth(), getActivity()));
+                        layerDrawable.setLayerWidth(1, convertDpToPixel(bitmap.getWidth(), getActivity()));
+                        imageView.setImageDrawable(layerDrawable);
+                    } else {
+                        imageView.setImageBitmap(bitmap);
+                    }
                 }
 
                 if (result.ocFile.getMimetype().equalsIgnoreCase("image/gif")) {
                     imageView.setGIFImageFromStoragePath(result.ocFile.getStoragePath());
-                } else {
+                } else if (!result.ocFile.getMimetype().equalsIgnoreCase("image/png")) {
                     imageView.setImageBitmap(bitmap);
                 }
 
                 imageView.setVisibility(View.VISIBLE);
-                mBitmap  = bitmap;  // needs to be kept for recycling when not useful
+                mBitmap = bitmap;  // needs to be kept for recycling when not useful
             }
 
-            final TextView messageView = mMessageViewRef.get();
-            if (messageView != null) {
-                messageView.setVisibility(View.GONE);
-            } // else , silently finish, the fragment was destroyed
+            mMultiView.setVisibility(View.GONE);
+            if (getResources() != null) {
+                mImageView.setBackgroundColor(getResources().getColor(R.color.black));
+            }
+            mImageView.setVisibility(View.VISIBLE);
+
         }
 
         private void showErrorMessage() {
-            final ImageView imageView = mImageViewRef.get();
-            if (imageView != null) {
-                // shows the default error icon
-                imageView.setVisibility(View.VISIBLE);
-            } // else , silently finish, the fragment was destroyed
-
-            final TextView messageView = mMessageViewRef.get();
-            if (messageView != null) {
-                messageView.setText(mErrorMessageId);
-                messageView.setVisibility(View.VISIBLE);
-            } // else , silently finish, the fragment was destroyed
+            mImageView.setBackgroundColor(Color.TRANSPARENT);
+            setMessageForMultiList(mErrorMessageId, R.string.preview_sorry, R.drawable.file_image);
         }
+    }
 
-        private void hideProgressWheel() {
-            final ProgressBar progressWheel = mProgressWheelRef.get();
-            if (progressWheel != null) {
-                progressWheel.setVisibility(View.GONE);
-            }
+    private void setMultiListLoadingMessage() {
+        if (mMultiView != null) {
+            mMultiListHeadline.setText(R.string.file_list_loading);
+            mMultiListMessage.setText("");
+
+            mMultiListIcon.setVisibility(View.GONE);
+            mMultiListProgress.setVisibility(View.VISIBLE);
         }
+    }
+
+    public void setMessageForMultiList(@StringRes int headline, @StringRes int message, @DrawableRes int icon) {
+        if (mMultiListContainer != null && mMultiListMessage != null) {
+            mMultiListHeadline.setText(headline);
+            mMultiListMessage.setText(message);
+            mMultiListIcon.setImageResource(icon);
 
+            mMultiListIcon.setVisibility(View.VISIBLE);
+            mMultiListProgress.setVisibility(View.GONE);
+
+        }
     }
 
     /**
      * Helper method to test if an {@link OCFile} can be passed to a {@link PreviewImageFragment}
      * to be previewed.
-     * 
+     *
      * @param file      File to test if can be previewed.
      * @return          'True' if the file can be handled by the fragment.
      */
@@ -574,6 +605,35 @@ public class PreviewImageFragment extends FileFragment {
         container.finish();
     }
 
+    private void toggleImageBackground() {
+        if (getFile() != null && getFile().getMimetype().equalsIgnoreCase("image/png") && getActivity() != null
+                && getActivity() instanceof PreviewImageActivity && getResources() != null) {
+            PreviewImageActivity previewImageActivity = (PreviewImageActivity) getActivity();
+            LayerDrawable layerDrawable = (LayerDrawable) mImageView.getDrawable();
+            Drawable layerOne;
+
+            if (previewImageActivity.getSystemUIVisible()) {
+                layerOne = getResources().getDrawable(R.color.white);
+            } else {
+                layerOne = getResources().getDrawable(R.drawable.backrepeat);
+            }
+
+            layerDrawable.setDrawableByLayerId(layerDrawable.getId(0), layerOne);
+
+            mImageView.setImageDrawable(layerDrawable);
+            mImageView.invalidate();
+        }
+    }
+
+
+    private static int convertDpToPixel(float dp, Context context) {
+        Resources resources = context.getResources();
+        DisplayMetrics metrics = resources.getDisplayMetrics();
+        int px = (int) (dp * ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
+        return px;
+    }
+
+
     public TouchImageViewCustom getImageView() {
         return mImageView;
     }
@@ -582,7 +642,7 @@ public class PreviewImageFragment extends FileFragment {
         private Bitmap bitmap;
         private OCFile ocFile;
 
-        public LoadImage(Bitmap bitmap, OCFile ocFile){
+        public LoadImage(Bitmap bitmap, OCFile ocFile) {
             this.bitmap = bitmap;
             this.ocFile = ocFile;
         }

+ 60 - 18
src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java

@@ -23,7 +23,6 @@ import android.accounts.Account;
 import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.res.Configuration;
@@ -37,7 +36,8 @@ import android.media.MediaPlayer.OnErrorListener;
 import android.media.MediaPlayer.OnPreparedListener;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.support.v7.app.AlertDialog;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.StringRes;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -47,6 +47,10 @@ import android.view.View;
 import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
 import android.widget.Toast;
 import android.widget.VideoView;
 
@@ -69,7 +73,7 @@ import com.owncloud.android.utils.MimeTypeUtil;
  *
  * Trying to get an instance with NULL {@link OCFile} or ownCloud {@link Account} values will
  * produce an {@link IllegalStateException}.
- * 
+ *
  * By now, if the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is
  * generated on instantiation too.
  */
@@ -87,6 +91,15 @@ public class PreviewMediaFragment extends FileFragment implements
     private VideoView mVideoPreview;
     private int mSavedPlaybackPosition;
 
+    private RelativeLayout mMultiView;
+    private RelativeLayout mPreviewContainer;
+
+    protected LinearLayout mMultiListContainer;
+    protected TextView mMultiListMessage;
+    protected TextView mMultiListHeadline;
+    protected ImageView mMultiListIcon;
+    protected ProgressBar mMultiListProgress;
+
     private MediaServiceBinder mMediaServiceBinder = null;
     private MediaControlView mMediaController = null;
     private MediaServiceConnection mMediaServiceConnection = null;
@@ -157,16 +170,50 @@ public class PreviewMediaFragment extends FileFragment implements
 
         mView = inflater.inflate(R.layout.file_preview, container, false);
 
+        mPreviewContainer = (RelativeLayout) mView.findViewById(R.id.file_preview_container);
         mImagePreview = (ImageView) mView.findViewById(R.id.image_preview);
         mVideoPreview = (VideoView) mView.findViewById(R.id.video_preview);
         mVideoPreview.setOnTouchListener(this);
 
         mMediaController = (MediaControlView) mView.findViewById(R.id.media_controller);
+        mMultiView = (RelativeLayout) mView.findViewById(R.id.multi_view);
 
+        setupMultiView(mView);
+        setMultiListLoadingMessage();
         return mView;
     }
 
 
+    protected void setupMultiView(View view) {
+        mMultiListContainer = (LinearLayout) view.findViewById(R.id.empty_list_view);
+        mMultiListMessage = (TextView) view.findViewById(R.id.empty_list_view_text);
+        mMultiListHeadline = (TextView) view.findViewById(R.id.empty_list_view_headline);
+        mMultiListIcon = (ImageView) view.findViewById(R.id.empty_list_icon);
+        mMultiListProgress = (ProgressBar) view.findViewById(R.id.empty_list_progress);
+    }
+
+    private void setMultiListLoadingMessage() {
+        if (mMultiView != null) {
+            mMultiListHeadline.setText(R.string.file_list_loading);
+            mMultiListMessage.setText("");
+
+            mMultiListIcon.setVisibility(View.GONE);
+            mMultiListProgress.setVisibility(View.VISIBLE);
+        }
+    }
+
+    public void setMessageForMultiList(String headline, @StringRes int message, @DrawableRes int icon) {
+        if (mMultiListContainer != null && mMultiListMessage != null) {
+            mMultiListHeadline.setText(headline);
+            mMultiListMessage.setText(message);
+            mMultiListIcon.setImageResource(icon);
+
+            mMultiListIcon.setVisibility(View.VISIBLE);
+            mMultiListProgress.setVisibility(View.GONE);
+        }
+    }
+
+
     /**
      * {@inheritDoc}
      */
@@ -197,6 +244,7 @@ public class PreviewMediaFragment extends FileFragment implements
             mAutoplay = savedInstanceState.getBoolean(PreviewMediaFragment.EXTRA_PLAYING);
 
         }
+
         if (file != null && file.isDown()) {
             if (MimeTypeUtil.isVideo(file)) {
                 mVideoPreview.setVisibility(View.VISIBLE);
@@ -455,6 +503,8 @@ public class PreviewMediaFragment extends FileFragment implements
         @Override
         public void onPrepared(MediaPlayer vp) {
             Log_OC.v(TAG, "onPrepared");
+            mMultiView.setVisibility(View.GONE);
+            mPreviewContainer.setVisibility(View.VISIBLE);
             mVideoPreview.seekTo(mSavedPlaybackPosition);
             if (mAutoplay) {
                 mVideoPreview.start();
@@ -492,20 +542,12 @@ public class PreviewMediaFragment extends FileFragment implements
         @Override
         public boolean onError(MediaPlayer mp, int what, int extra) {
             Log_OC.e(TAG, "Error in video playback, what = " + what + ", extra = " + extra);
+            mPreviewContainer.setVisibility(View.GONE);
             if (mVideoPreview.getWindowToken() != null) {
                 String message = MediaService.getMessageForMediaError(
                         getActivity(), what, extra);
-                new AlertDialog.Builder(getActivity())
-                        .setMessage(message)
-                        .setPositiveButton(android.R.string.VideoView_error_button,
-                                new DialogInterface.OnClickListener() {
-                                    public void onClick(DialogInterface dialog, int whichButton) {
-                                        dialog.dismiss();
-                                        VideoHelper.this.onCompletion(null);
-                                    }
-                                })
-                        .setCancelable(false)
-                        .show();
+                mMultiView.setVisibility(View.VISIBLE);
+                setMessageForMultiList(message, R.string.preview_sorry, R.drawable.file_movie);
             }
             return true;
         }
@@ -556,7 +598,7 @@ public class PreviewMediaFragment extends FileFragment implements
             if (event.getX() / Resources.getSystem().getDisplayMetrics().density > 24.0) {
                 startFullScreenVideo();
             }
-            return true;        
+            return true;
         }
         return false;
     }
@@ -612,11 +654,11 @@ public class PreviewMediaFragment extends FileFragment implements
         }
         getActivity().bindService(  new Intent(getActivity(),
                                     MediaService.class),
-                                    mMediaServiceConnection, 
+                                    mMediaServiceConnection,
                                     Context.BIND_AUTO_CREATE);
             // follow the flow in MediaServiceConnection#onServiceConnected(...)
     }
-    
+
     /** Defines callbacks for service binding, passed to bindService() */
     private class MediaServiceConnection implements ServiceConnection {
 
@@ -657,7 +699,7 @@ public class PreviewMediaFragment extends FileFragment implements
                 else {
                     Toast.makeText(
                             getActivity(),
-                            "No media controller to release when disconnected from media service", 
+                            "No media controller to release when disconnected from media service",
                             Toast.LENGTH_SHORT).show();
                 }
                 mMediaServiceBinder = null;

+ 39 - 35
src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.java

@@ -22,15 +22,16 @@ package com.owncloud.android.ui.preview;
 import android.accounts.Account;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
 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.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import com.owncloud.android.R;
@@ -39,7 +40,6 @@ import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
-import com.owncloud.android.ui.dialog.LoadingDialog;
 import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
 import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.utils.MimeTypeUtil;
@@ -65,6 +65,15 @@ public class PreviewTextFragment extends FileFragment {
     private TextView mTextPreview;
     private TextLoadAsyncTask mTextLoadTask;
 
+    private RelativeLayout mMultiView;
+
+    protected LinearLayout mMultiListContainer;
+    protected TextView mMultiListMessage;
+    protected TextView mMultiListHeadline;
+    protected ImageView mMultiListIcon;
+    protected ProgressBar mMultiListProgress;
+
+
     /**
      * Creates an empty fragment for previews.
      * <p/>
@@ -93,9 +102,33 @@ public class PreviewTextFragment extends FileFragment {
 
         mTextPreview = (TextView) ret.findViewById(R.id.text_preview);
 
+        mMultiView = (RelativeLayout) ret.findViewById(R.id.multi_view);
+
+        setupMultiView(ret);
+        setMultiListLoadingMessage();
+
         return ret;
     }
 
+    protected void setupMultiView(View view) {
+        mMultiListContainer = (LinearLayout) view.findViewById(R.id.empty_list_view);
+        mMultiListMessage = (TextView) view.findViewById(R.id.empty_list_view_text);
+        mMultiListHeadline = (TextView) view.findViewById(R.id.empty_list_view_headline);
+        mMultiListIcon = (ImageView) view.findViewById(R.id.empty_list_icon);
+        mMultiListProgress = (ProgressBar) view.findViewById(R.id.empty_list_progress);
+    }
+
+    private void setMultiListLoadingMessage() {
+        if (mMultiView != null) {
+            mMultiListHeadline.setText(R.string.file_list_loading);
+            mMultiListMessage.setText("");
+
+            mMultiListIcon.setVisibility(View.GONE);
+            mMultiListProgress.setVisibility(View.VISIBLE);
+        }
+    }
+
+
     /**
      * {@inheritDoc}
      */
@@ -168,7 +201,6 @@ public class PreviewTextFragment extends FileFragment {
 
         @Override
         protected void onPreExecute() {
-            showLoadingDialog();
         }
 
         @Override
@@ -224,39 +256,12 @@ public class PreviewTextFragment extends FileFragment {
                 textView.setVisibility(View.VISIBLE);
             }
 
-            dismissLoadingDialog();
-        }
-
-        /**
-         * Show loading dialog
-         */
-        public void showLoadingDialog() {
-            // only once
-            Fragment frag = getActivity().getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
-            LoadingDialog loading = null;
-            if (frag == null) {
-                // Construct dialog
-                loading = new LoadingDialog(getResources().getString(R.string.wait_a_moment));
-                FragmentManager fm = getActivity().getSupportFragmentManager();
-                FragmentTransaction ft = fm.beginTransaction();
-                loading.show(ft, DIALOG_WAIT_TAG);
-            } else {
-                loading = (LoadingDialog) frag;
-                loading.setShowsDialog(true);
+            if (mMultiView != null) {
+                mMultiView.setVisibility(View.GONE);
             }
 
         }
 
-        /**
-         * Dismiss loading dialog
-         */
-        public void dismissLoadingDialog() {
-            final Fragment frag = getActivity().getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
-            if (frag != null) {
-                LoadingDialog loading = (LoadingDialog) frag;
-                loading.dismissAllowingStateLoss();
-            }
-        }
     }
 
     /**
@@ -426,7 +431,6 @@ public class PreviewTextFragment extends FileFragment {
         Log_OC.e(TAG, "onStop");
         if (mTextLoadTask != null) {
             mTextLoadTask.cancel(Boolean.TRUE);
-            mTextLoadTask.dismissLoadingDialog();
         }
     }
 

+ 2 - 2
src/main/java/third_parties/michaelOrtiz/TouchImageViewCustom.java

@@ -10,8 +10,6 @@
 
 package third_parties.michaelOrtiz;
 
-import com.owncloud.android.ui.preview.ImageViewCustom;
-
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -37,6 +35,8 @@ import android.view.animation.AccelerateDecelerateInterpolator;
 import android.widget.OverScroller;
 import android.widget.Scroller;
 
+import com.owncloud.android.ui.preview.ImageViewCustom;
+
 /**
  * Extends Android ImageView to include pinch zooming, panning, fling and double tap zoom.
  */

+ 65 - 41
src/main/res/layout/file_preview.xml

@@ -19,46 +19,70 @@
 -->
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/top"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:gravity="center"
-    tools:context=".ui.fragment.FilePreviewFragment">
-
-    <FrameLayout
-        android:id="@+id/visual_area"
-   	    android:layout_width="match_parent"
-   	    android:layout_height="0dp"
-   	    android:layout_alignParentTop="true"
-   	    android:layout_above="@+id/media_controller"
-        >
-    
-	    <ImageView
-	        android:id="@+id/image_preview"
-	        android:layout_width="match_parent"
-	        android:layout_height="match_parent"
-	        android:layout_margin="@dimen/standard_margin"
-	        android:layout_gravity="center"
-	        android:contentDescription="@string/preview_image_description"
-	        android:src="@drawable/logo" />
-	    
-	   	<VideoView  
-	   	    android:id="@+id/video_preview"
-			android:layout_width="match_parent"
-			android:layout_height="match_parent"  
-			android:layout_gravity="center" 
-			android:visibility="gone"
-			/>
-	   	
-   	</FrameLayout>
-   	
-   	<com.owncloud.android.media.MediaControlView 
-   	    android:id="@id/media_controller"
-   	    android:layout_width="match_parent"
-   	    android:layout_height="wrap_content"
-   	    android:layout_alignParentBottom="true"
-		android:layout_margin="@dimen/standard_margin"
-   	    />
+                xmlns:tools="http://schemas.android.com/tools"
+                android:id="@+id/top"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:gravity="center"
+                tools:context=".ui.fragment.FilePreviewFragment">
+
+    <RelativeLayout
+        android:id="@+id/file_preview_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible"
+        android:background="@color/black">
+
+        <FrameLayout
+            android:id="@+id/visual_area"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_above="@+id/media_controller"
+            android:layout_alignParentTop="true"
+            >
+
+            <ImageView
+                android:id="@+id/image_preview"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_gravity="center"
+                android:layout_margin="@dimen/standard_margin"
+                android:contentDescription="@string/preview_image_description"
+                android:src="@drawable/logo"/>
+
+            <VideoView
+                android:id="@+id/video_preview"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_gravity="center"
+                android:visibility="gone"
+                />
+
+        </FrameLayout>
+
+        <com.owncloud.android.media.MediaControlView
+            android:id="@id/media_controller"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_margin="@dimen/standard_margin"
+            />
+    </RelativeLayout>
+
+
+    <RelativeLayout
+        android:id="@+id/multi_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+
+            <include layout="@layout/empty_list"/>
+
+        </ScrollView>
+    </RelativeLayout>
+
 
 </RelativeLayout>

+ 7 - 1
src/main/res/layout/media_control.xml

@@ -65,6 +65,7 @@
             android:layout_height="wrap_content"
             android:paddingEnd="@dimen/standard_quarter_padding"
             android:text="@string/placeholder_media_time"
+            android:textColor="@color/white"
             />
 
         <SeekBar
@@ -74,7 +75,11 @@
             android:layout_weight="1"
             android:layout_height="@dimen/seek_bar_height"
             android:layout_alignParentStart="true"
-            android:layout_alignParentEnd="true" />
+            android:layout_alignParentEnd="true"
+            android:progressDrawable="@color/white"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentRight="true"
+            android:splitTrack="false"/>
 
         <TextView android:id="@+id/totalTimeText"
             android:textSize="@dimen/two_line_secondary_text_size"
@@ -86,6 +91,7 @@
             android:layout_height="wrap_content"
             android:paddingStart="@dimen/standard_quarter_padding"
             android:text="@string/placeholder_media_time"
+            android:textColor="@color/white"
             />
         
     </LinearLayout>

+ 19 - 23
src/main/res/layout/preview_image_fragment.xml

@@ -31,36 +31,32 @@
     android:id="@+id/top"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="#000000"
-    tools:context=".ui.fragment.PreviewImageFragment" >
+    android:animateLayoutChanges="true">
 
-    <ProgressBar 
-        android:id="@+id/progressWheel"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:indeterminate="true"
-        android:indeterminateOnly="true"
-        android:layout_centerInParent="true"
-        />
 
     <third_parties.michaelOrtiz.TouchImageViewCustom
         android:id="@+id/image"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_margin="@dimen/zero"
         android:layout_centerInParent="true"
+        android:layout_margin="@dimen/zero"
         android:contentDescription="@string/preview_image_description"
-        android:src="@drawable/image_fail" />
-    
-    <TextView
-        android:id="@+id/message"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerHorizontal="true"
-        android:layout_alignParentBottom="true"
-        android:layout_margin="@dimen/preview_image_fragment_display_text_margin"
-        android:text="@string/placeholder_sentence"
-        android:textColor="@color/owncloud_blue_bright"
-        />
+        android:src="@drawable/image_fail"/>
+
+
+    <RelativeLayout
+        android:id="@+id/multi_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+
+            <include layout="@layout/empty_list"/>
+
+        </ScrollView>
+    </RelativeLayout>
+
 
 </RelativeLayout>

+ 26 - 6
src/main/res/layout/text_file_preview.xml

@@ -21,11 +21,31 @@
             android:layout_height="match_parent"
             android:fillViewport="true">
 
-    <TextView
-        android:id="@+id/text_preview"
+    <RelativeLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:padding="@dimen/standard_padding"
-        android:textIsSelectable="true"
-        android:visibility="gone"/>
+        android:layout_height="match_parent">
+
+        <TextView
+            android:id="@+id/text_preview"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="@dimen/standard_padding"
+            android:textIsSelectable="true"
+            android:visibility="gone"/>
+
+        <RelativeLayout
+            android:id="@+id/multi_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+
+            <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+                <include layout="@layout/empty_list"/>
+
+            </ScrollView>
+        </RelativeLayout>
+    </RelativeLayout>
+
 </ScrollView>

+ 1 - 1
src/main/res/values/strings.xml

@@ -352,7 +352,7 @@
 
     <string name="preview_sorry">Sorry about that!</string>
     <string name="preview_image_description">Image preview</string>
-    <string name="preview_image_error_unknown_format">This image cannot be shown</string>
+    <string name="preview_image_error_unknown_format">Image can\'t be shown</string>
 
     <string name="error__upload__local_file_not_copied">%1$s could not be copied to %2$s local folder</string>
     <string name="prefs_instant_upload_path_title">Instant upload folder</string>

+ 3 - 2
src/main/res/values/styles.xml

@@ -120,16 +120,17 @@
 	<!-- separat translucent action bar style -->
 	<style name="Theme.ownCloud.Overlay" parent="style/Theme.ownCloud">
 		<item name="android:actionBarStyle">@style/Theme.ownCloud.Overlay.ActionBar</item>
-		<item name="windowActionBarOverlay">true</item>
+		<item name="android:windowActionBarOverlay">true</item>
+		<item name="android:windowFullscreen">true</item>
 		<!-- Support library compatibility -->
 		<item name="actionBarStyle">@style/Theme.ownCloud.Overlay.ActionBar</item>
+		<item name="windowActionBarOverlay">true</item>
 	</style>
 
 	<!-- ACTION BAR STYLES -->
 	<style name="Theme.ownCloud.Overlay.ActionBar" parent="@style/Widget.AppCompat.ActionBar">
 		<item name="android:background">@color/owncloud_blue_transparent</item>
 		<item name="android:windowActionBarOverlay">true</item>
-
 		<!-- Support library compatibility -->
 		<item name="background">@color/owncloud_blue_transparent</item>
 		<item name="windowActionBarOverlay">true</item>