From e3193b93ad7bf33e2e45319084a99b9fc986622b Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 10 Sep 2010 11:44:42 -0700 Subject: Initital changes for new customization drawer/widget tab design. Change-Id: I160c8777fe2657ab303acfa20934f2e90f9e953e --- src/com/android/launcher2/CustomizePagedView.java | 355 ++++++++++++--------- src/com/android/launcher2/DragController.java | 31 +- src/com/android/launcher2/Launcher.java | 3 +- src/com/android/launcher2/PagedView.java | 59 +++- src/com/android/launcher2/PagedViewCellLayout.java | 59 ++-- 5 files changed, 306 insertions(+), 201 deletions(-) (limited to 'src') diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java index 786300bf7..d3d11db93 100644 --- a/src/com/android/launcher2/CustomizePagedView.java +++ b/src/com/android/launcher2/CustomizePagedView.java @@ -28,7 +28,9 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Configuration; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; @@ -38,8 +40,13 @@ import android.graphics.drawable.Drawable; import android.provider.LiveFolders; import android.util.AttributeSet; import android.util.Log; +import android.view.Gravity; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import com.android.launcher.R; @@ -55,6 +62,27 @@ public class CustomizePagedView extends PagedView WallpaperCustomization } + /** + * The linear layout used strictly for the widget tab of the customization tray + */ + private class WidgetLayout extends LinearLayout { + public WidgetLayout(Context context) { + super(context); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // We eat up the touch events here, since the PagedView (which uses the same swiping + // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when + // the user is scrolling between pages. This means that if the pages themselves don't + // handle touch events, it gets forwarded up to PagedView itself, and it's own + // onTouchEvent() handling will prevent further intercept touch events from being called + // (it's the same view in that case). This is not ideal, but to prevent more changes, + // we just always mark the touch event as handled. + return super.onTouchEvent(event) || true; + } + } + private static final String TAG = "CustomizeWorkspace"; private static final boolean DEBUG = false; @@ -64,33 +92,57 @@ public class CustomizePagedView extends PagedView private CustomizationType mCustomizationType; - private PagedViewCellLayout mTmpWidgetLayout; - private ArrayList> mWidgetPages; + // The layout used to emulate the workspace in resolve the cell dimensions of a widget + private PagedViewCellLayout mWorkspaceWidgetLayout; + + // The mapping between the pages and the widgets that will be laid out on them + private ArrayList> mWidgetPages; + + // The max dimensions for the ImageView we use for displaying the widget + private int mMaxWidgetWidth; + + // The max number of widget cells to take a "page" of widget + private int mMaxWidgetsCellHSpan; + + // The raw sources of data for each of the different tabs of the customization page private List mWidgetList; private List mFolderList; private List mShortcutList; - private int mCellCountX; - private int mCellCountY; + private static final int sCellCountX = 8; + private static final int sCellCountY = 4; + private static final int sMinWidgetCellHSpan = 2; + private static final int sMaxWidgetCellHSpan = 4; + + // The scale factor for widget previews inside the widget drawer + private static final float sScaleFactor = 0.75f; private final Canvas mCanvas = new Canvas(); private final LayoutInflater mInflater; public CustomizePagedView(Context context) { - this(context, null); + this(context, null, 0); } public CustomizePagedView(Context context, AttributeSet attrs) { - super(context, attrs); - mCellCountX = 8; - mCellCountY = 4; + this(context, attrs, 0); + } + + public CustomizePagedView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomizePagedView, + defStyle, 0); mCustomizationType = CustomizationType.WidgetCustomization; - mWidgetPages = new ArrayList>(); - mTmpWidgetLayout = new PagedViewCellLayout(context); + mWidgetPages = new ArrayList>(); + mWorkspaceWidgetLayout = new PagedViewCellLayout(context); mInflater = LayoutInflater.from(context); - setupPage(mTmpWidgetLayout); + mMaxWidgetsCellHSpan = a.getInt(R.styleable.CustomizePagedView_widgetCellCountX, 8); + a.recycle(); + setVisibility(View.GONE); setSoundEffectsEnabled(false); + setupWorkspaceLayout(); } public void setLauncher(Launcher launcher) { @@ -139,6 +191,7 @@ public class CustomizePagedView extends PagedView // reset the icon cache mPageViewIconCache.clear(); + // Refresh all the tabs invalidatePageData(); } @@ -166,26 +219,22 @@ public class CustomizePagedView extends PagedView final View animView = v; switch (mCustomizationType) { case WidgetCustomization: - // We assume that the view v is a TextView with a compound drawable on top, and that the - // whole text view is centered horizontally and top aligned. We get a more precise - // drag point using this information - final TextView textView = (TextView) animView; - final Drawable[] drawables = textView.getCompoundDrawables(); - final Drawable icon = drawables[1]; - int dragPointOffsetX = 0; - int dragPointOffsetY = 0; - Rect bounds = null; - if (icon != null) { - bounds = icon.getBounds(); - bounds.left = (v.getWidth() - bounds.right) / 2; - bounds.right += bounds.left; - } + // Get the icon as the drag representation + final LinearLayout l = (LinearLayout) animView; + final Drawable icon = ((ImageView) l.findViewById(R.id.icon)).getDrawable(); + Bitmap b = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), + Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(b); + icon.draw(c); AppWidgetProviderInfo appWidgetInfo = (AppWidgetProviderInfo) v.getTag(); LauncherAppWidgetInfo dragInfo = new LauncherAppWidgetInfo(appWidgetInfo.provider); dragInfo.minWidth = appWidgetInfo.minWidth; dragInfo.minHeight = appWidgetInfo.minHeight; - mDragController.startDrag(v, this, dragInfo, DragController.DRAG_ACTION_COPY, bounds); + mDragController.startDrag(v, b, this, dragInfo, DragController.DRAG_ACTION_COPY, null); + + // Cleanup the icon + b.recycle(); return true; case FolderCustomization: // animate some feedback to the long press @@ -236,80 +285,50 @@ public class CustomizePagedView extends PagedView return false; } + /** + * Pre-processes the layout of the different widget pages. + * @return the number of pages of widgets that we have + */ private int relayoutWidgets() { - final int widgetCount = mWidgetList.size(); - if (widgetCount == 0) return 0; + if (mWidgetList.isEmpty()) return 0; + // create a new page for the first set of widgets + ArrayList newPage = new ArrayList(); mWidgetPages.clear(); - ArrayList page = - new ArrayList(); - mWidgetPages.add(page); - int rowOffsetX = 0; - int rowOffsetY = 0; - int curRowHeight = 0; - // we only get the cell dims this way for the layout calculations because - // we know that we aren't going to change the dims when we construct it - // afterwards - for (int i = 0; i < widgetCount; ++i) { - AppWidgetProviderInfo info = mWidgetList.get(i); - PagedViewCellLayout.LayoutParams params; - - final int cellSpanX = mTmpWidgetLayout.estimateCellHSpan(info.minWidth); - final int cellSpanY = mTmpWidgetLayout.estimateCellVSpan(info.minHeight); + mWidgetPages.add(newPage); - if (((rowOffsetX + cellSpanX) <= mCellCountX) && - ((rowOffsetY + cellSpanY) <= mCellCountY)) { - // just add to end of current row - params = new PagedViewCellLayout.LayoutParams(rowOffsetX, rowOffsetY, - cellSpanX, cellSpanY); + // do this until we have no more widgets to lay out + final int maxNumCellsPerRow = mMaxWidgetsCellHSpan; + final int widgetCount = mWidgetList.size(); + int numCellsInRow = 0; + for (int i = 0; i < widgetCount; ++i) { + final AppWidgetProviderInfo info = mWidgetList.get(i); - rowOffsetX += cellSpanX; - curRowHeight = Math.max(curRowHeight, cellSpanY); - } else { - /* - // fix all the items in this last row to be bottom aligned - int prevRowOffsetX = rowOffsetX; - for (int j = page.size() - 1; j >= 0; --j) { - PagedViewCellLayout.LayoutParams params = page.get(j); - // skip once we get to the previous row - if (params.cellX > prevRowOffsetX) - break; - - params.cellY += curRowHeight - params.cellVSpan; - prevRowOffsetX = params.cellX; - } - */ - - // doesn't fit on current row, see if we can start a new row on - // this page - if ((rowOffsetY + curRowHeight + cellSpanY) > mCellCountY) { - // start a new page and add this item to it - page = new ArrayList(); - mWidgetPages.add(page); - - params = new PagedViewCellLayout.LayoutParams(0, 0, cellSpanX, cellSpanY); - rowOffsetX = cellSpanX; - rowOffsetY = 0; - curRowHeight = cellSpanY; - } else { - // add it to the current page on this new row - params = new PagedViewCellLayout.LayoutParams(0, rowOffsetY + curRowHeight, - cellSpanX, cellSpanY); + // determine the size of the current widget + int cellSpanX = Math.max(sMinWidgetCellHSpan, Math.min(sMaxWidgetCellHSpan, + mWorkspaceWidgetLayout.estimateCellHSpan(info.minWidth))); - rowOffsetX = cellSpanX; - rowOffsetY += curRowHeight; - curRowHeight = cellSpanY; - } + // create a new page if necessary + if ((numCellsInRow + cellSpanX) > maxNumCellsPerRow) { + numCellsInRow = 0; + newPage = new ArrayList(); + mWidgetPages.add(newPage); } - params.setTag(info); - page.add(params); + // add the item to the current page + newPage.add(info); + numCellsInRow += cellSpanX; } + return mWidgetPages.size(); } - private Drawable getWidgetIcon(PagedViewCellLayout.LayoutParams params, - AppWidgetProviderInfo info) { + /** + * This method will extract the preview image specified by the widget developer (if it exists), + * otherwise, it will try to generate a default image preview with the widget's package icon. + * @return the drawable will be used and sized in the ImageView to represent the widget + */ + private Drawable getWidgetIcon(AppWidgetProviderInfo info) { PackageManager packageManager = mLauncher.getPackageManager(); String packageName = info.provider.getPackageName(); Drawable drawable = null; @@ -327,15 +346,11 @@ public class CustomizePagedView extends PagedView if (drawable == null) { Resources resources = mLauncher.getResources(); - // Determine the size the widget will take in the layout // Create a new bitmap to hold the widget preview - int[] dims = mTmpWidgetLayout.estimateCellDimensions(getMeasuredWidth(), - getMeasuredHeight(), params.cellHSpan, params.cellVSpan); - final int width = dims[0]; - final int height = dims[1] - 35; - // TEMP - // TEMP: HACK ABOVE TO GET TEXT TO SHOW - // TEMP + final int minDim = mWorkspaceWidgetLayout.estimateCellWidth(1); + final int maxDim = mWorkspaceWidgetLayout.estimateCellWidth(3); + int width = (int) (Math.max(minDim, Math.min(maxDim, info.minWidth)) * sScaleFactor); + int height = (int) (Math.max(minDim, Math.min(maxDim, info.minHeight)) * sScaleFactor); Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); mCanvas.setBitmap(bitmap); // For some reason, we must re-set the clip rect here, otherwise it will be wrong @@ -349,19 +364,16 @@ public class CustomizePagedView extends PagedView try { Rect tmpRect = new Rect(); Drawable icon = null; - if (info.icon != 0) { + if (info.icon > 0) { icon = packageManager.getDrawable(packageName, info.icon, null); } else { icon = resources.getDrawable(R.drawable.ic_launcher_application); } background.getPadding(tmpRect); - final int iconSize = Math.min( - Math.min(icon.getIntrinsicWidth(), width - tmpRect.left - tmpRect.right), - Math.min(icon.getIntrinsicHeight(), height - tmpRect.top - tmpRect.bottom)); - final int left = (width / 2) - (iconSize / 2); - final int top = (height / 2) - (iconSize / 2); - icon.setBounds(new Rect(left, top, left + iconSize, top + iconSize)); + final int iconSize = minDim / 2; + final int offset = iconSize / 4; + icon.setBounds(new Rect(offset, offset, offset + iconSize, offset + iconSize)); icon.draw(mCanvas); } catch (Resources.NotFoundException e) { // if we can't find the icon, then just don't draw it @@ -374,62 +386,77 @@ public class CustomizePagedView extends PagedView } private void setupPage(PagedViewCellLayout layout) { - layout.setCellCount(mCellCountX, mCellCountY); + layout.setCellCount(sCellCountX, sCellCountY); layout.setPadding(20, 10, 20, 0); } + private void setupWorkspaceLayout() { + mWorkspaceWidgetLayout.setCellCount(sCellCountX, sCellCountY); + mWorkspaceWidgetLayout.setPadding(20, 10, 20, 0); + + mMaxWidgetWidth = mWorkspaceWidgetLayout.estimateCellWidth(sMaxWidgetCellHSpan); + } + private void syncWidgetPages() { if (mWidgetList == null) return; - // calculate the layout for all the widget pages first and ensure that - // we have the right number of pages + // we need to repopulate with the LinearLayout layout for the widget pages + removeAllViews(); int numPages = relayoutWidgets(); - int curNumPages = getChildCount(); - // remove any extra pages after the "last" page - int extraPageDiff = curNumPages - numPages; - for (int i = 0; i < extraPageDiff; ++i) { - removeViewAt(numPages); - } - // add any necessary pages - for (int i = curNumPages; i < numPages; ++i) { - PagedViewCellLayout layout = new PagedViewCellLayout(getContext()); - setupPage(layout); - addView(layout); + for (int i = 0; i < numPages; ++i) { + LinearLayout layout = new WidgetLayout(getContext()); + layout.setGravity(Gravity.CENTER_HORIZONTAL); + + // Temporary change to prevent the last page from being too small (and items bleeding + // onto it). We can remove this once we properly fix the fading algorithm + if (i < numPages - 1) { + addView(layout, new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.MATCH_PARENT)); + } else { + addView(layout, new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT)); + } } } private void syncWidgetPageItems(int page) { // ensure that we have the right number of items on the pages - PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page); - final ArrayList list = mWidgetPages.get(page); + LinearLayout layout = (LinearLayout) getChildAt(page); + final ArrayList list = mWidgetPages.get(page); final int count = list.size(); layout.removeAllViews(); for (int i = 0; i < count; ++i) { - PagedViewCellLayout.LayoutParams params = list.get(i); - AppWidgetProviderInfo info = (AppWidgetProviderInfo) params.getTag(); - final Drawable icon = getWidgetIcon(params, info); - TextView text = (TextView) mInflater.inflate(R.layout.customize_paged_view_widget, - layout, false); - text.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null); - text.setText(info.label); - text.setTag(info); - text.setOnLongClickListener(this); - - layout.addViewToCellLayout(text, -1, mWidgetList.indexOf(info), params); + AppWidgetProviderInfo info = (AppWidgetProviderInfo) list.get(i); + LinearLayout l = (LinearLayout) mInflater.inflate( + R.layout.customize_paged_view_widget, layout, false); + l.setTag(info); + l.setOnLongClickListener(this); + + final Drawable icon = getWidgetIcon(info); + final int hSpan = mWorkspaceWidgetLayout.estimateCellHSpan(info.minWidth); + final int vSpan = mWorkspaceWidgetLayout.estimateCellHSpan(info.minHeight); + + ImageView image = (ImageView) l.findViewById(R.id.icon); + image.setMaxWidth(mMaxWidgetWidth); + image.setImageDrawable(icon); + TextView name = (TextView) l.findViewById(R.id.name); + name.setText(info.label); + TextView dims = (TextView) l.findViewById(R.id.dims); + dims.setText("" + hSpan + " x " + vSpan); + + layout.addView(l); } } private void syncListPages(List list) { + // we need to repopulate with PagedViewCellLayouts + removeAllViews(); + // ensure that we have the right number of pages - int numPages = (int) Math.ceil((float) list.size() / (mCellCountX * mCellCountY)); - int curNumPages = getChildCount(); - // remove any extra pages after the "last" page - int extraPageDiff = curNumPages - numPages; - for (int i = 0; i < extraPageDiff; ++i) { - removeViewAt(numPages); - } - // add any necessary pages - for (int i = curNumPages; i < numPages; ++i) { + int numPages = (int) Math.ceil((float) list.size() / (sCellCountX * sCellCountY)); + for (int i = 0; i < numPages; ++i) { PagedViewCellLayout layout = new PagedViewCellLayout(getContext()); setupPage(layout); addView(layout); @@ -438,7 +465,7 @@ public class CustomizePagedView extends PagedView private void syncListPageItems(int page, List list) { // ensure that we have the right number of items on the pages - int numCells = mCellCountX * mCellCountY; + int numCells = sCellCountX * sCellCountY; int startIndex = page * numCells; int endIndex = Math.min(startIndex + numCells, list.size()); PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page); @@ -452,24 +479,22 @@ public class CustomizePagedView extends PagedView icon.setOnLongClickListener(this); final int index = i - startIndex; - final int x = index % mCellCountX; - final int y = index / mCellCountX; + final int x = index % sCellCountX; + final int y = index / sCellCountX; + setupPage(layout); layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1)); } } private void syncWallpaperPages() { // NOT CURRENTLY IMPLEMENTED - // ensure that we have the right number of pages - int numPages = 1; - int curNumPages = getChildCount(); - // remove any extra pages after the "last" page - int extraPageDiff = curNumPages - numPages; - for (int i = 0; i < extraPageDiff; ++i) { - removeViewAt(numPages); - } + + // we need to repopulate with PagedViewCellLayouts + removeAllViews(); + // add any necessary pages - for (int i = curNumPages; i < numPages; ++i) { + int numPages = 1; + for (int i = 0; i < numPages; ++i) { PagedViewCellLayout layout = new PagedViewCellLayout(getContext()); setupPage(layout); addView(layout); @@ -485,23 +510,28 @@ public class CustomizePagedView extends PagedView // NOTE: this is just place holder text until MikeJurka implements wallpaper picker text.setText("Wallpaper customization coming soon!"); + setupPage(layout); layout.addViewToCellLayout(text, -1, 0, new PagedViewCellLayout.LayoutParams(0, 0, 3, 1)); } @Override public void syncPages() { + boolean centerPagedViewCellLayouts = false; switch (mCustomizationType) { case WidgetCustomization: syncWidgetPages(); break; case FolderCustomization: syncListPages(mFolderList); + centerPagedViewCellLayouts = true; break; case ShortcutCustomization: syncListPages(mShortcutList); + centerPagedViewCellLayouts = true; break; case WallpaperCustomization: syncWallpaperPages(); + centerPagedViewCellLayouts = true; break; default: removeAllViews(); @@ -511,13 +541,15 @@ public class CustomizePagedView extends PagedView // only try and center the page if there is one page final int childCount = getChildCount(); - if (childCount == 1) { - PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(0); - layout.enableCenteredContent(true); - } else { - for (int i = 0; i < childCount; ++i) { - PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i); - layout.enableCenteredContent(false); + if (centerPagedViewCellLayouts) { + if (childCount == 1) { + PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(0); + layout.enableCenteredContent(true); + } else { + for (int i = 0; i < childCount; ++i) { + PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i); + layout.enableCenteredContent(false); + } } } @@ -542,4 +574,11 @@ public class CustomizePagedView extends PagedView break; } } + + protected int getAssociatedLowerPageBound(int page) { + return 0; + } + protected int getAssociatedUpperPageBound(int page) { + return getChildCount(); + } } diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java index e18470ab2..7fc905bb5 100644 --- a/src/com/android/launcher2/DragController.java +++ b/src/com/android/launcher2/DragController.java @@ -134,7 +134,7 @@ public class DragController { void onDragStart(DragSource source, Object info, int dragAction); /** - * The drag has eneded + * The drag has ended */ void onDragEnd(); } @@ -199,6 +199,35 @@ public class DragController { } } + /** + * Starts a drag. + * + * @param v The view that is being dragged + * @param bmp The bitmap that represents the view being dragged + * @param source An object representing where the drag originated + * @param dragInfo The data associated with the object that is being dragged + * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or + * {@link #DRAG_ACTION_COPY} + * @param dragRegion Coordinates within the bitmap b for the position of item being dragged. + * Makes dragging feel more precise, e.g. you can clip out a transparent border + */ + public void startDrag(View v, Bitmap bmp, DragSource source, Object dragInfo, int dragAction, + Rect dragRegion) { + mOriginator = v; + + int[] loc = mCoordinatesTemp; + v.getLocationOnScreen(loc); + int screenX = loc[0]; + int screenY = loc[1]; + + startDrag(bmp, screenX, screenY, 0, 0, bmp.getWidth(), bmp.getHeight(), + source, dragInfo, dragAction, dragRegion); + + if (dragAction == DRAG_ACTION_MOVE) { + v.setVisibility(View.GONE); + } + } + /** * Starts a drag. * diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index c5450f34e..8eece9604 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -281,7 +281,8 @@ public final class Launcher extends Activity mHomeCustomizationDrawer.setup(); // share the same customization workspace across all the tabs - mCustomizePagedView = new CustomizePagedView(this); + mCustomizePagedView = (CustomizePagedView) mInflater.inflate( + R.layout.customization_drawer, mHomeCustomizationDrawer, false); TabContentFactory contentFactory = new TabContentFactory() { public View createTabContent(String tag) { return mCustomizePagedView; diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java index 1e0dad4ae..0772c0a6c 100644 --- a/src/com/android/launcher2/PagedView.java +++ b/src/com/android/launcher2/PagedView.java @@ -16,7 +16,8 @@ package com.android.launcher2; -import com.android.launcher.R; +import java.util.ArrayList; +import java.util.HashMap; import android.content.Context; import android.graphics.Bitmap; @@ -25,6 +26,7 @@ import android.graphics.Rect; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; +import android.util.Log; import android.view.ActionMode; import android.view.MotionEvent; import android.view.VelocityTracker; @@ -33,13 +35,13 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.animation.Animation; -import android.view.animation.AnimationUtils; import android.view.animation.Animation.AnimationListener; +import android.view.animation.AnimationUtils; import android.widget.Checkable; +import android.widget.LinearLayout; import android.widget.Scroller; -import java.util.ArrayList; -import java.util.HashMap; +import com.android.launcher.R; /** * An abstraction of the original Workspace which supports browsing through a @@ -345,7 +347,7 @@ public abstract class PagedView extends ViewGroup { final int childCount = getChildCount(); int childLeft = 0; if (childCount > 0) { - childLeft = (getMeasuredWidth() - getChildAt(0).getMeasuredWidth()) / 2; + childLeft = getRelativeChildOffset(0); } for (int i = 0; i < childCount; i++) { @@ -360,11 +362,12 @@ public abstract class PagedView extends ViewGroup { } } - @Override - protected void dispatchDraw(Canvas canvas) { + protected void updateAdjacentPagesAlpha() { if (mFadeInAdjacentScreens) { if (mDirtyPageAlpha || (mTouchState == TOUCH_STATE_SCROLLING) || !mScroller.isFinished()) { - int screenCenter = mScrollX + (getMeasuredWidth() / 2); + int halfScreenSize = getMeasuredWidth() / 2; + int screenCenter = mScrollX + halfScreenSize; + final int childCount = getChildCount(); for (int i = 0; i < childCount; ++i) { View layout = (View) getChildAt(i); @@ -389,9 +392,13 @@ public abstract class PagedView extends ViewGroup { mDirtyPageAlpha = false; } } + } - // Find out which screens are visible; as an optimization we only call draw on them + @Override + protected void dispatchDraw(Canvas canvas) { + updateAdjacentPagesAlpha(); + // Find out which screens are visible; as an optimization we only call draw on them // As an optimization, this code assumes that all pages have the same width as the 0th // page. final int pageCount = getChildCount(); @@ -591,11 +598,11 @@ public abstract class PagedView extends ViewGroup { if ((mTouchState != TOUCH_STATE_PREV_PAGE) && (mTouchState != TOUCH_STATE_NEXT_PAGE)) { if (getChildCount() > 0) { - int relativeChildLeft = getChildOffset(0); - int relativeChildRight = relativeChildLeft + getChildAt(0).getMeasuredWidth(); - if (x < relativeChildLeft) { + int width = getMeasuredWidth(); + int offset = getRelativeChildOffset(mCurrentPage); + if (x < offset) { mTouchState = TOUCH_STATE_PREV_PAGE; - } else if (x > relativeChildRight) { + } else if (x > (width - offset)) { mTouchState = TOUCH_STATE_NEXT_PAGE; } } @@ -842,6 +849,19 @@ public abstract class PagedView extends ViewGroup { } } + protected int getChildIndexForRelativeOffset(int relativeOffset) { + final int childCount = getChildCount(); + int left = getRelativeChildOffset(0); + for (int i = 0; i < childCount; ++i) { + final int right = (left + getChildAt(i).getMeasuredWidth()); + if (left <= relativeOffset && relativeOffset <= right) { + return i; + } + left = right; + } + return -1; + } + protected int getRelativeChildOffset(int index) { return (getMeasuredWidth() - getChildAt(index).getMeasuredWidth()) / 2; } @@ -889,7 +909,6 @@ public abstract class PagedView extends ViewGroup { protected void snapToPage(int whichPage, int duration) { whichPage = Math.max(0, Math.min(whichPage, getPageCount() - 1)); - int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage); final int sX = getScrollX(); final int delta = newX - sX; @@ -1015,8 +1034,8 @@ public abstract class PagedView extends ViewGroup { if (mContentIsRefreshable) { final int count = getChildCount(); if (page < count) { - int lowerPageBound = Math.max(0, page - 1); - int upperPageBound = Math.min(page + 1, count - 1); + int lowerPageBound = getAssociatedLowerPageBound(page); + int upperPageBound = getAssociatedUpperPageBound(page); for (int i = 0; i < count; ++i) { final ViewGroup layout = (ViewGroup) getChildAt(i); final int childCount = layout.getChildCount(); @@ -1036,6 +1055,14 @@ public abstract class PagedView extends ViewGroup { } } + protected int getAssociatedLowerPageBound(int page) { + return Math.max(0, page - 1); + } + protected int getAssociatedUpperPageBound(int page) { + final int count = getChildCount(); + return Math.min(page + 1, count - 1); + } + protected void startChoiceMode(int mode, ActionMode.Callback callback) { if (isChoiceMode(CHOICE_MODE_NONE)) { mChoiceMode = mode; diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java index 219a36204..b247a065f 100644 --- a/src/com/android/launcher2/PagedViewCellLayout.java +++ b/src/com/android/launcher2/PagedViewCellLayout.java @@ -252,6 +252,16 @@ public class PagedViewCellLayout extends ViewGroup { requestLayout(); } + public void setCellDimensions(int width, int height) { + mCellWidth = width; + mCellHeight = height; + requestLayout(); + } + + public int getDefaultCellDimensions() { + return sDefaultCellDimensions; + } + private void setChildrenAlpha(float alpha) { final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { @@ -281,37 +291,36 @@ public class PagedViewCellLayout extends ViewGroup { lp.isDragging = true; } + /** + * Estimates the number of cells that the specified width would take up. + */ public int estimateCellHSpan(int width) { + // TODO: we need to take widthGap into effect return (width + mCellWidth) / mCellWidth; } + + /** + * Estimates the number of cells that the specified height would take up. + */ public int estimateCellVSpan(int height) { + // TODO: we need to take heightGap into effect return (height + mCellHeight) / mCellHeight; } - public int[] estimateCellDimensions(int approxWidth, int approxHeight, - int cellHSpan, int cellVSpan) { - // NOTE: we are disabling this until we find a good way to approximate this without fully - // measuring - /* - // we may want to use this before any measuring/layout happens, so we pass in an approximate - // size for the layout - int numWidthGaps = mCellCountX - 1; - int numHeightGaps = mCellCountY - 1; - int hSpaceLeft = approxWidth - mPaddingLeft - - mPaddingRight - (mCellWidth * mCellCountX); - int vSpaceLeft = approxHeight - mPaddingTop - - mPaddingBottom - (mCellHeight * mCellCountY); - int widthGap = hSpaceLeft / numWidthGaps; - int heightGap = vSpaceLeft / numHeightGaps; - int minGap = Math.min(widthGap, heightGap); - return new int[] { - (cellHSpan * mCellWidth) + ((cellHSpan - 1) * minGap), - (cellVSpan * mCellHeight) + ((cellVSpan - 1) * minGap) - }; - */ - return new int[] { - (cellHSpan * mCellWidth), - (cellVSpan * mCellHeight) - }; + + /** + * Estimates the width that the number of vSpan cells will take up. + */ + public int estimateCellWidth(int hSpan) { + // TODO: we need to take widthGap into effect + return hSpan * mCellWidth; + } + + /** + * Estimates the height that the number of vSpan cells will take up. + */ + public int estimateCellHeight(int vSpan) { + // TODO: we need to take heightGap into effect + return vSpan * mCellHeight; } @Override -- cgit v1.2.3