Browse Source

Keep the same item in the CENTER of the files list when the device is turned to other position

David A. Velasco 12 năm trước cách đây
mục cha
commit
0bb59e0f9b

+ 55 - 0
src/com/owncloud/android/ui/ExtendedListView.java

@@ -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;
+    }
+}

+ 4 - 5
src/com/owncloud/android/ui/FragmentListView.java

@@ -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) {

+ 3 - 3
src/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -485,7 +485,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
             registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
         
             // List current directory
-            mFileList.listDirectory(mCurrentDir);   // we should find the way to avoid the need of this
+            mFileList.listDirectory(mCurrentDir);   // TODO we should find the way to avoid the need of this (maybe it's not necessary yet; to check)
             
         } else {
             
@@ -721,7 +721,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                         mStorageManager.saveFile(newDir);
     
                         // Display the new folder right away
-                        mFileList.listDirectory(mCurrentDir);
+                        mFileList.listDirectory();
                     }
                 });
                 
@@ -802,7 +802,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                     OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager()
                             .findFragmentById(R.id.fileList);
                     if (fileListFragment != null) {
-                        fileListFragment.listDirectory(mCurrentDir);  
+                        fileListFragment.listDirectory(mCurrentDir);
                     }
                 }
                 

+ 34 - 6
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java

@@ -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,12 +112,36 @@ 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.
      */
@@ -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;
     }
     
 

+ 33 - 9
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -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;
         }
     }