Keep the same item in the CENTER of the files list when the device is turned to other...
authorDavid A. Velasco <dvelasco@solidgear.es>
Wed, 17 Oct 2012 11:44:36 +0000 (13:44 +0200)
committerDavid A. Velasco <dvelasco@solidgear.es>
Wed, 17 Oct 2012 11:45:19 +0000 (13:45 +0200)
src/com/owncloud/android/ui/ExtendedListView.java [new file with mode: 0644]
src/com/owncloud/android/ui/FragmentListView.java
src/com/owncloud/android/ui/activity/FileDisplayActivity.java
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

diff --git a/src/com/owncloud/android/ui/ExtendedListView.java b/src/com/owncloud/android/ui/ExtendedListView.java
new file mode 100644 (file)
index 0000000..5a2bc36
--- /dev/null
@@ -0,0 +1,55 @@
+package com.owncloud.android.ui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.widget.ListView;
+
+/**
+ * ListView allowing to specify the position of an item that should be centered in the visible area, if possible.
+ * 
+ * The cleanest way I found to overcome the problem due to getHeight() returns 0 until the view is really drawn. 
+ *  
+ * @author David A. Velasco
+ */
+public class ExtendedListView extends ListView {
+
+    private int mPositionToSetAndCenter;
+
+    public ExtendedListView(Context context) {
+        super(context);
+    }
+
+    public ExtendedListView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public ExtendedListView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * 
+     */
+    @Override
+    protected void onDraw (Canvas canvas) {
+        super.onDraw(canvas);
+        if (mPositionToSetAndCenter > 0) {
+            this.setSelectionFromTop(mPositionToSetAndCenter, getHeight() / 2);
+            mPositionToSetAndCenter = 0;
+        }
+    }
+    
+    /**
+     * Public method to set the position of the item that should be centered in the visible area of the view.
+     * 
+     * The position is saved here and checked in onDraw().
+     *  
+     * @param position         Position (in the list of items) of the item to center in the visible area.     
+     */
+    public void setAndCenterSelection(int position) {
+        mPositionToSetAndCenter = position;
+    }
+}
index 4165afa..54ada01 100644 (file)
@@ -9,12 +9,12 @@ import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.ListAdapter;
-import android.widget.ListView;
 import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
 
 public class FragmentListView extends SherlockFragment implements
         OnItemClickListener, OnItemLongClickListener {
-    protected ListView mList;
+    protected ExtendedListView mList;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -29,15 +29,14 @@ public class FragmentListView extends SherlockFragment implements
     public ListView getListView() {
         return mList;
     }
-
+    
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
-        mList = new ListView(getActivity());
+        mList = new ExtendedListView(getActivity());
         mList.setOnItemClickListener(this);
         mList.setOnItemLongClickListener(this);
         return mList;
-        // return super.onCreateView(inflater, container, savedInstanceState);
     }
 
     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
index 77612e3..6519a66 100644 (file)
@@ -485,7 +485,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
             registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);\r
         \r
             // List current directory\r
-            mFileList.listDirectory(mCurrentDir);   // we should find the way to avoid the need of this\r
+            mFileList.listDirectory(mCurrentDir);   // TODO we should find the way to avoid the need of this (maybe it's not necessary yet; to check)\r
             \r
         } else {\r
             \r
@@ -721,7 +721,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                         mStorageManager.saveFile(newDir);\r
     \r
                         // Display the new folder right away\r
-                        mFileList.listDirectory(mCurrentDir);\r
+                        mFileList.listDirectory();\r
                     }\r
                 });\r
                 \r
@@ -802,7 +802,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                     OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager()\r
                             .findFragmentById(R.id.fileList);\r
                     if (fileListFragment != null) {\r
-                        fileListFragment.listDirectory(mCurrentDir);  \r
+                        fileListFragment.listDirectory(mCurrentDir);\r
                     }\r
                 }\r
                 \r
index d60adbd..46775b9 100644 (file)
@@ -19,6 +19,7 @@ package com.owncloud.android.ui.fragment;
 
 import java.io.File;
 
+import com.owncloud.android.ui.ExtendedListView;
 import com.owncloud.android.ui.FragmentListView;
 import com.owncloud.android.ui.adapter.LocalFileListAdapter;
 
@@ -44,6 +45,7 @@ import com.owncloud.android.R;
  */
 public class LocalFileListFragment extends FragmentListView {
     private static final String TAG = "LocalFileListFragment";
+    private static final String SAVED_LIST_POSITION = "LIST_POSITION"; 
     
     /** Reference to the Activity which this fragment is attached to. For callbacks */
     private LocalFileListFragment.ContainerActivity mContainerActivity;
@@ -98,8 +100,8 @@ public class LocalFileListFragment extends FragmentListView {
         
         if (savedInstanceState != null) {
             Log.i(TAG, "savedInstanceState is not null");
-            int position = savedInstanceState.getInt("LIST_POSITION");
-            getListView().setSelectionFromTop(position, 0);
+            int position = savedInstanceState.getInt(SAVED_LIST_POSITION);
+            setReferencePosition(position);
         }
         
         Log.i(TAG, "onActivityCreated() stop");
@@ -110,13 +112,37 @@ public class LocalFileListFragment extends FragmentListView {
     public void onSaveInstanceState(Bundle savedInstanceState) {
         Log.i(TAG, "onSaveInstanceState() start");
         
-        savedInstanceState.putInt("LIST_POSITION", getListView().getFirstVisiblePosition());
+        savedInstanceState.putInt(SAVED_LIST_POSITION, getReferencePosition());
+        
         
         Log.i(TAG, "onSaveInstanceState() stop");
     }
     
     
     /**
+     * Calculates the position of the item that will be used as a reference to reposition the visible items in the list when
+     * the device is turned to other position. 
+     * 
+     * THe current policy is take as a reference the visible item in the center of the screen.  
+     * 
+     * @return      The position in the list of the visible item in the center of the screen.
+     */
+    private int getReferencePosition() {
+        return (getListView().getFirstVisiblePosition() + getListView().getLastVisiblePosition()) / 2;
+    }
+
+    
+    /**
+     * Sets the visible part of the list from the reference position.
+     * 
+     * @param   position    Reference position previously returned by {@link LocalFileListFragment#getReferencePosition()}
+     */
+    private void setReferencePosition(int position) {
+        ((ExtendedListView)getListView()).setAndCenterSelection(position);
+    }
+    
+
+    /**
      * Checks the file clicked over. Browses inside if it is a directory. Notifies the container activity in any case.
      */
     @Override
@@ -207,10 +233,12 @@ public class LocalFileListFragment extends FragmentListView {
             directory = directory.getParentFile();
         }
 
-        mDirectory = directory;
         mList.clearChoices();   // by now, only files in the same directory will be kept as selected
-        mAdapter.swapDirectory(mDirectory);
-        mList.setSelectionFromTop(0, 0);
+        mAdapter.swapDirectory(directory);
+        if (mDirectory == null || !mDirectory.equals(directory)) {
+            mList.setSelectionFromTop(0, 0);
+        }
+        mDirectory = directory;
     }
     
 
index 60ded05..afac955 100644 (file)
@@ -19,6 +19,7 @@ package com.owncloud.android.ui.fragment;
 
 import com.owncloud.android.datamodel.DataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.ui.ExtendedListView;
 import com.owncloud.android.ui.FragmentListView;
 import com.owncloud.android.ui.activity.TransferServiceGetter;
 import com.owncloud.android.ui.adapter.FileListListAdapter;
@@ -40,6 +41,7 @@ import com.owncloud.android.R;
  */
 public class OCFileListFragment extends FragmentListView {
     private static final String TAG = "FileListFragment";
+    private static final String SAVED_LIST_POSITION = "LIST_POSITION"; 
     
     private OCFileListFragment.ContainerActivity mContainerActivity;
     
@@ -90,25 +92,48 @@ public class OCFileListFragment extends FragmentListView {
         
         if (savedInstanceState != null) {
             Log.i(TAG, "savedInstanceState is not null");
-            int position = savedInstanceState.getInt("LIST_POSITION");
-            getListView().setSelectionFromTop(position, 0);
+            int position = savedInstanceState.getInt(SAVED_LIST_POSITION);
+            setReferencePosition(position);
         }
-        //mAdapter = new FileListListAdapter();
         
         Log.i(TAG, "onActivityCreated() stop");
     }
     
     
+
     @Override
     public void onSaveInstanceState(Bundle savedInstanceState) {
         Log.i(TAG, "onSaveInstanceState() start");
         
-        savedInstanceState.putInt("LIST_POSITION", getListView().getFirstVisiblePosition());
+        savedInstanceState.putInt(SAVED_LIST_POSITION, getReferencePosition());
         
         Log.i(TAG, "onSaveInstanceState() stop");
     }
     
     
+    /**
+     * Calculates the position of the item that will be used as a reference to reposition the visible items in the list when
+     * the device is turned to other position. 
+     * 
+     * THe current policy is take as a reference the visible item in the center of the screen.  
+     * 
+     * @return      The position in the list of the visible item in the center of the screen.
+     */
+    private int getReferencePosition() {
+        return (getListView().getFirstVisiblePosition() + getListView().getLastVisiblePosition()) / 2;
+    }
+
+    
+    /**
+     * Sets the visible part of the list from the reference position.
+     * 
+     * @param   position    Reference position previously returned by {@link OCFileListFragment#getReferencePosition()}
+     */
+    private void setReferencePosition(int position) {
+        ((ExtendedListView)getListView()).setAndCenterSelection(position);
+    }
+
+    
     @Override
     public void onItemClick(AdapterView<?> l, View v, int position, long id) {
         OCFile file = (OCFile) mAdapter.getItem(position);
@@ -158,9 +183,7 @@ public class OCFileListFragment extends FragmentListView {
      * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter
      */
     public void listDirectory(){
-        int position = mList.getFirstVisiblePosition();
         listDirectory(null);
-        mList.setSelectionFromTop(position, 0);
     }
     
     /**
@@ -191,10 +214,11 @@ public class OCFileListFragment extends FragmentListView {
                 directory = storageManager.getFileById(directory.getParentId());
             }
 
-            mFile = directory;
             mAdapter.swapDirectory(mFile, storageManager);
-            mList.setSelectionFromTop(0, 0);
-            mList.invalidate();
+            if (mFile == null || !mFile.equals(directory)) {
+                mList.setSelectionFromTop(0, 0);
+            }
+            mFile = directory;
         }
     }