Merge "Initital changes for new customization drawer/widget tab design."

This commit is contained in:
Winson Chung
2010-09-15 14:45:43 -07:00
committed by Android (Google) Code Review
13 changed files with 414 additions and 216 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.launcher2.CustomizePagedView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
launcher:widgetCellCountX="16" />
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.launcher2.CustomizePagedView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
launcher:widgetCellCountX="12" />
@@ -13,20 +13,62 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/name"
android:layout_width="match_parent"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:paddingTop="2dip"
android:paddingLeft="12.5dp"
android:paddingRight="12.5dp"
android:paddingTop="40dp"
android:paddingBottom="50dp"
android:gravity="top"
android:orientation="vertical">
android:textColor="#FFFFFFFF"
android:textSize="14sp"
android:shadowColor="#FF000000"
android:shadowDx="0.0"
android:shadowDy="1.0"
android:shadowRadius="1.0"
<!-- The icon of the widget. -->
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:scaleType="fitStart" />
android:maxLines="2"
android:fadingEdge="horizontal" />
<!-- The divider image. -->
<ImageView
android:id="@+id/divider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:src="@drawable/widget_divider" />
<!-- The name of the widget. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
android:shadowColor="#FF000000"
android:shadowDx="0.0"
android:shadowDy="1.0"
android:shadowRadius="1.0"
android:maxLines="2"
android:fadingEdge="horizontal" />
<!-- The original dimensions of the widget (can't be the same text as above due to different
style. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dims"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:textColor="#FF999999"
android:textSize="14sp"
android:shadowColor="#99000000"
android:shadowDx="0.0"
android:shadowDy="1.0"
android:shadowRadius="1.0" />
</LinearLayout>
+1 -1
View File
@@ -128,7 +128,7 @@
<TabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="550dip"
android:layout_height="500dip"
android:layout_gravity="bottom">
<LinearLayout
android:orientation="vertical"
+1 -1
View File
@@ -23,7 +23,7 @@
<dimen name="smallScreenExtraSpacing">0dip</dimen>
<!-- vertical spacing between edge of screen and mini screen thumbnails -->
<dimen name="smallScreenVerticalMargin">20dip</dimen>
<dimen name="smallScreenVerticalMargin">60dip</dimen>
<dimen name="toolbar_padding">10dip</dimen>
+7
View File
@@ -64,6 +64,13 @@
<attr name="cellCountY" />
</declare-styleable>
<!-- CustomizePagedView specific attributes. These attributes are used to customize
a CustomizePagedView view in XML files. -->
<declare-styleable name="CustomizePagedView">
<!-- The number of horizontal cells for the widget tab -->
<attr name="widgetCellCountX" format="integer" />
</declare-styleable>
<!-- DeleteZone specific attributes. These attributes are used to customize
a DeleteZone view in XML files. -->
<declare-styleable name="DeleteZone">
+196 -157
View File
@@ -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<ArrayList<PagedViewCellLayout.LayoutParams>> 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<ArrayList<AppWidgetProviderInfo>> 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<AppWidgetProviderInfo> mWidgetList;
private List<ResolveInfo> mFolderList;
private List<ResolveInfo> 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<ArrayList<PagedViewCellLayout.LayoutParams>>();
mTmpWidgetLayout = new PagedViewCellLayout(context);
mWidgetPages = new ArrayList<ArrayList<AppWidgetProviderInfo>>();
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<AppWidgetProviderInfo> newPage = new ArrayList<AppWidgetProviderInfo>();
mWidgetPages.clear();
ArrayList<PagedViewCellLayout.LayoutParams> page =
new ArrayList<PagedViewCellLayout.LayoutParams>();
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
mWidgetPages.add(newPage);
// 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) {
AppWidgetProviderInfo info = mWidgetList.get(i);
PagedViewCellLayout.LayoutParams params;
final AppWidgetProviderInfo info = mWidgetList.get(i);
final int cellSpanX = mTmpWidgetLayout.estimateCellHSpan(info.minWidth);
final int cellSpanY = mTmpWidgetLayout.estimateCellVSpan(info.minHeight);
// determine the size of the current widget
int cellSpanX = Math.max(sMinWidgetCellHSpan, Math.min(sMaxWidgetCellHSpan,
mWorkspaceWidgetLayout.estimateCellHSpan(info.minWidth)));
if (((rowOffsetX + cellSpanX) <= mCellCountX) &&
((rowOffsetY + cellSpanY) <= mCellCountY)) {
// just add to end of current row
params = new PagedViewCellLayout.LayoutParams(rowOffsetX, rowOffsetY,
cellSpanX, cellSpanY);
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<PagedViewCellLayout.LayoutParams>();
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);
rowOffsetX = cellSpanX;
rowOffsetY += curRowHeight;
curRowHeight = cellSpanY;
}
// create a new page if necessary
if ((numCellsInRow + cellSpanX) > maxNumCellsPerRow) {
numCellsInRow = 0;
newPage = new ArrayList<AppWidgetProviderInfo>();
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<PagedViewCellLayout.LayoutParams> list = mWidgetPages.get(page);
LinearLayout layout = (LinearLayout) getChildAt(page);
final ArrayList<AppWidgetProviderInfo> 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);
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);
layout.addViewToCellLayout(text, -1, mWidgetList.indexOf(info), params);
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<ResolveInfo> 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<ResolveInfo> 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();
}
}
+30 -1
View File
@@ -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.
*
+2 -1
View File
@@ -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;
+43 -16
View File
@@ -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;
}
}
}
@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;
@@ -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