Switched to tabbed version of AllApps2D on xlarge screens.

- add a temporary new zoom animation for all apps
- modify AllApps2D to allow it to be transparent
- other changes to dismiss the customization drawer when appropriate

Change-Id: I5660ab77f256ded299c1721c589983a1b30d56a4
This commit is contained in:
Patrick Dubroy 2010-07-23 16:48:11 -07:00
parent 401d892f4c
commit 558654c6ec
9 changed files with 373 additions and 85 deletions

View File

@ -0,0 +1,33 @@
<?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.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:shareInterpolator="true">
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0%p"
android:toXDelta="0%p"
android:fromYDelta="-20%p"
android:toYDelta="0%p"
android:duration="500" />
<scale
android:fromXScale="5.0"
android:toXScale="1.0"
android:fromYScale="5.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="100%"
android:duration="500" />
</set>

View File

@ -0,0 +1,33 @@
<?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.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:shareInterpolator="true">
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0%p"
android:toXDelta="0%p"
android:fromYDelta="0%p"
android:toYDelta="-20%p"
android:duration="500" />
<scale
android:fromXScale="1.0"
android:toXScale="5.0"
android:fromYScale="1.0"
android:toYScale="5.0"
android:pivotX="50%"
android:pivotY="100%"
android:duration="500" />
</set>

View File

@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="2dip"
>
android:background="#FF000000">
<GridView android:id="@+id/all_apps_2d_grid"
android:tag="all_apps_2d_grid"

View File

@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="2dip"
>
android:background="#FF000000">
<GridView android:id="@+id/all_apps_2d_grid"
android:tag="all_apps_2d_grid"

View File

@ -0,0 +1,56 @@
<?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.AllAppsTabbed xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.android.launcher2.AllApps2D
android:id="@+id/all_apps_2d"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="2dip">
<GridView android:id="@+id/all_apps_2d_grid"
android:tag="all_apps_2d_grid"
android:scrollbars="none"
android:drawSelectorOnTop="false"
android:listSelector="@drawable/grid_selector"
android:verticalSpacing="10dip"
android:numColumns="4"
android:fadingEdgeLength="0dip"
android:cacheColorHint="#00000000"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/button_bar_height"
android:layout_marginTop="8dip"
android:nextFocusDown="@+id/all_apps_2d_home"
android:nextFocusUp="@null"
android:nextFocusLeft="@null"
android:nextFocusRight="@null" />
</com.android.launcher2.AllApps2D>
</FrameLayout>
</LinearLayout>
</com.android.launcher2.AllAppsTabbed>

View File

@ -22,7 +22,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/all_apps" />
<include
layout="@layout/all_apps_tabbed"
android:id="@+id/all_apps_view"
android:layout_width="match_parent"
android:layout_height="500dip"
android:layout_gravity="top"/>
<!-- The workspace contains 5 screens of cells -->
<com.android.launcher2.Workspace
@ -39,8 +44,6 @@
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
</com.android.launcher2.Workspace>
<RelativeLayout
android:id="@+id/all_apps_button_cluster"
android:layout_width="wrap_content"
@ -86,37 +89,37 @@
android:layout_height="200dip"
android:layout_gravity="bottom"
android:visibility="gone">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:background="#ff000000"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.android.launcher2.WidgetChooser
android:id="@+id/widget_chooser"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.android.launcher2.FolderChooser
android:id="@+id/folder_chooser"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.android.launcher2.ShortcutChooser
android:id="@+id/shortcut_chooser"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/wallpaperstab"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/wallpapers_temp_tab_text" />
</FrameLayout>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:background="#ff000000"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.android.launcher2.WidgetChooser
android:id="@+id/widget_chooser"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.android.launcher2.FolderChooser
android:id="@+id/folder_chooser"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.android.launcher2.ShortcutChooser
android:id="@+id/shortcut_chooser"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/wallpaperstab"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/wallpapers_temp_tab_text" />
</FrameLayout>
</LinearLayout>
</TabHost>
</com.android.launcher2.DragLayer>

View File

@ -16,15 +16,15 @@
package com.android.launcher2;
import java.util.ArrayList;
import java.util.Collections;
import com.android.launcher.R;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
@ -39,7 +39,8 @@ import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.launcher.R;
import java.util.ArrayList;
import java.util.Collections;
public class AllApps2D
extends RelativeLayout
@ -67,6 +68,8 @@ public class AllApps2D
private AppsAdapter mAppsAdapter;
private boolean mIsViewOpaque;
// ------------------------------------------------------------
public static class HomeButton extends ImageButton {
@ -125,24 +128,24 @@ public class AllApps2D
@Override
protected void onFinishInflate() {
setBackgroundColor(Color.BLACK);
mIsViewOpaque = super.isOpaque();
try {
mGrid = (GridView)findViewWithTag("all_apps_2d_grid");
if (mGrid == null) throw new Resources.NotFoundException();
mGrid.setOnItemClickListener(this);
mGrid.setOnItemLongClickListener(this);
mGrid.setBackgroundColor(Color.BLACK);
mGrid.setCacheColorHint(Color.BLACK);
// The home button is optional; some layouts might not use it
ImageButton homeButton = (ImageButton) findViewWithTag("all_apps_2d_home");
if (homeButton == null) throw new Resources.NotFoundException();
homeButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
mLauncher.closeAllApps(true);
}
});
if (homeButton != null) {
homeButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
mLauncher.closeAllApps(true);
}
});
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find necessary layout elements for AllApps2D");
}
@ -251,7 +254,7 @@ public class AllApps2D
@Override
public boolean isOpaque() {
return mZoom > 0.999f;
return mIsViewOpaque && mZoom > 0.999f;
}
public void setApps(ArrayList<ApplicationInfo> list) {

View File

@ -0,0 +1,124 @@
/*
* 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.
*/
package com.android.launcher2;
import com.android.launcher.R;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TabHost;
import java.util.ArrayList;
/**
* Implements a tabbed version of AllApps2D.
*/
public class AllAppsTabbed extends TabHost implements AllAppsView {
private static final String TAG = "Launcher.AllAppsTabbed";
private AllAppsView mAllApps2D;
public AllAppsTabbed(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
try {
mAllApps2D = (AllAppsView)findViewById(R.id.all_apps_2d);
if (mAllApps2D == null) throw new Resources.NotFoundException();
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find necessary layout elements for AllAppsTabbed");
}
setup();
// This lets us share the same view between all tabs
TabContentFactory contentFactory = new TabContentFactory() {
public View createTabContent(String tag) {
return (View)mAllApps2D;
}
};
// TODO: Make these tabs show the appropriate content (they're no-ops for now)
addTab(newTabSpec("apps").setIndicator("All").setContent(contentFactory));
addTab(newTabSpec("apps").setIndicator("Apps").setContent(contentFactory));
addTab(newTabSpec("apps").setIndicator("Games").setContent(contentFactory));
addTab(newTabSpec("apps").setIndicator("Downloaded").setContent(contentFactory));
setCurrentTab(0);
setVisibility(GONE);
}
@Override
public void setLauncher(Launcher launcher) {
mAllApps2D.setLauncher(launcher);
}
@Override
public void setDragController(DragController dragger) {
mAllApps2D.setDragController(dragger);
}
@Override
public void zoom(float zoom, boolean animate) {
// NOTE: animate parameter is ignored for the TabHost itself
setVisibility((zoom == 0.0f) ? View.GONE : View.VISIBLE);
mAllApps2D.zoom(zoom, animate);
bringChildToFront((View)mAllApps2D);
getParent().bringChildToFront(this);
}
@Override
public boolean isVisible() {
return mAllApps2D.isVisible();
}
@Override
public void setApps(ArrayList<ApplicationInfo> list) {
mAllApps2D.setApps(list);
}
@Override
public void addApps(ArrayList<ApplicationInfo> list) {
mAllApps2D.addApps(list);
}
@Override
public void removeApps(ArrayList<ApplicationInfo> list) {
mAllApps2D.removeApps(list);
}
@Override
public void updateApps(ArrayList<ApplicationInfo> list) {
mAllApps2D.updateApps(list);
}
@Override
public void dumpState() {
mAllApps2D.dumpState();
}
@Override
public void surrender() {
mAllApps2D.surrender();
}
}

View File

@ -34,8 +34,8 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Intent.ShortcutIconResource;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@ -68,10 +68,11 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.View.OnLongClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
@ -1027,10 +1028,13 @@ public final class Launcher extends Activity
boolean alreadyOnHome = ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)
!= Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
boolean allAppsVisible = isAllAppsVisible();
// TODO: Figure out the right thing to do in XLarge mode here
if (!mWorkspace.isDefaultScreenShowing()) {
mWorkspace.moveToDefaultScreen(alreadyOnHome && !allAppsVisible);
}
closeAllApps(alreadyOnHome && allAppsVisible);
hideCustomizationDrawer();
final View v = getWindow().peekDecorView();
if (v != null && v.getWindowToken() != null) {
@ -1256,7 +1260,14 @@ public final class Launcher extends Activity
private void addItems() {
closeAllApps(true);
showAddDialog(mMenuAddInfo);
if (LauncherApplication.isScreenXLarge()) {
// Animate the widget chooser up from the bottom of the screen
if (!isCustomizationDrawerVisible()) {
showCustomizationDrawer();
}
} else {
showAddDialog(mMenuAddInfo);
}
}
void addAppWidgetFromDrop(ComponentName appWidgetProvider, CellLayout.CellInfo cellInfo) {
@ -1487,6 +1498,8 @@ public final class Launcher extends Activity
public void onBackPressed() {
if (isAllAppsVisible()) {
closeAllApps(true);
} else if (isCustomizationDrawerVisible()) {
hideCustomizationDrawer();
} else {
closeFolder();
}
@ -1560,26 +1573,10 @@ public final class Launcher extends Activity
}
}
private final class SlideDownFinishedListener implements Animation.AnimationListener {
TabHost mHomeCustomizationDrawer;
SlideDownFinishedListener(TabHost homeCustomizationDrawer) {
mHomeCustomizationDrawer = homeCustomizationDrawer;
}
public void onAnimationEnd(Animation animation) {
mHomeCustomizationDrawer.setVisibility(View.GONE);
}
public void onAnimationRepeat(Animation animation) {}
public void onAnimationStart(Animation animation) {}
}
public boolean onTouch(View v, MotionEvent event) {
// this is being forwarded from mWorkspace;
// clicking anywhere on the workspace causes the drawer to slide down
if (mHomeCustomizationDrawer != null && mHomeCustomizationDrawer.getVisibility() == View.VISIBLE) {
Animation slideDownAnimation = AnimationUtils.loadAnimation(this, R.anim.home_customization_drawer_slide_down);
slideDownAnimation.setAnimationListener(new SlideDownFinishedListener(mHomeCustomizationDrawer));
mHomeCustomizationDrawer.startAnimation(slideDownAnimation);
}
hideCustomizationDrawer();
return false;
}
@ -1590,16 +1587,7 @@ public final class Launcher extends Activity
* @param v The view that was clicked.
*/
public void onClickAddButton(View v) {
// Animate the widget chooser up from the bottom of the screen
if (mHomeCustomizationDrawer != null && mHomeCustomizationDrawer.getVisibility() == View.GONE) {
mHomeCustomizationDrawer.setVisibility(View.VISIBLE);
mHomeCustomizationDrawer.startAnimation(AnimationUtils.loadAnimation(this, R.anim.home_customization_drawer_slide_up));
}
}
public void onClickAllAppsButton(View w) {
showAllApps(true);
addItems();
}
void startActivitySafely(Intent intent, Object tag) {
@ -2036,7 +2024,16 @@ public final class Launcher extends Activity
}
void showAllApps(boolean animated) {
mAllAppsGrid.zoom(1.0f, animated);
hideCustomizationDrawer();
if (LauncherApplication.isScreenXLarge() && animated) {
// Not really a zoom -- this just makes the view visible
mAllAppsGrid.zoom(1.0f, false);
Animation anim = AnimationUtils.loadAnimation(this, R.anim.all_apps_zoom_in);
((View) mAllAppsGrid).startAnimation(anim);
} else {
mAllAppsGrid.zoom(1.0f, animated);
}
((View) mAllAppsGrid).setFocusable(true);
((View) mAllAppsGrid).requestFocus();
@ -2087,7 +2084,19 @@ public final class Launcher extends Activity
void closeAllApps(boolean animated) {
if (mAllAppsGrid.isVisible()) {
mWorkspace.setVisibility(View.VISIBLE);
mAllAppsGrid.zoom(0.0f, animated);
if (LauncherApplication.isScreenXLarge() && animated) {
Animation anim = AnimationUtils.loadAnimation(this, R.anim.all_apps_zoom_out);
anim.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {}
public void onAnimationRepeat(Animation animation) {}
public void onAnimationEnd(Animation animation) {
mAllAppsGrid.zoom(0.0f, false);
}
});
((View)mAllAppsGrid).startAnimation(anim);
} else {
mAllAppsGrid.zoom(0.0f, animated);
}
((View)mAllAppsGrid).setFocusable(false);
mWorkspace.getChildAt(mWorkspace.getCurrentScreen()).requestFocus();
}
@ -2101,6 +2110,33 @@ public final class Launcher extends Activity
// TODO
}
private boolean isCustomizationDrawerVisible() {
return mHomeCustomizationDrawer != null && mHomeCustomizationDrawer.getVisibility() == View.VISIBLE;
}
private void showCustomizationDrawer() {
if (isAllAppsVisible()) {
// TODO: Make a smoother transition here
closeAllApps(false);
}
mHomeCustomizationDrawer.setVisibility(View.VISIBLE);
mHomeCustomizationDrawer.startAnimation(AnimationUtils.loadAnimation(this, R.anim.home_customization_drawer_slide_up));
}
private void hideCustomizationDrawer() {
if (isCustomizationDrawerVisible()) {
Animation slideDownAnimation = AnimationUtils.loadAnimation(this, R.anim.home_customization_drawer_slide_down);
slideDownAnimation.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationEnd(Animation animation) {
mHomeCustomizationDrawer.setVisibility(View.GONE);
}
public void onAnimationRepeat(Animation animation) {}
public void onAnimationStart(Animation animation) {}
});
mHomeCustomizationDrawer.startAnimation(slideDownAnimation);
}
}
/**
* Displays the shortcut creation dialog and launches, if necessary, the
* appropriate activity.