OSDN Git Service

Adding ability to delete previously saved wallpapers
authorMichael Jurka <mikejurka@google.com>
Tue, 10 Sep 2013 11:39:59 +0000 (13:39 +0200)
committerMichael Jurka <mikejurka@google.com>
Thu, 12 Sep 2013 18:49:17 +0000 (20:49 +0200)
- Also preserving temporarily picked wallpapers on
rotation

Change-Id: I35361e2a5619cd986bd8b66268ce9e94b9a0027e

res/drawable/wallpaper_gallery_item.xml
res/layout/wallpaper_picker_gallery_item.xml
res/layout/wallpaper_picker_item.xml
res/menu/cab_delete_wallpapers.xml [new file with mode: 0644]
res/values/strings.xml
src/com/android/launcher3/CheckableFrameLayout.java [new file with mode: 0644]
src/com/android/launcher3/WallpaperPickerActivity.java

index b7052bd..9ac931b 100644 (file)
@@ -15,6 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:drawable="@drawable/grid_pressed" />
     <item android:state_focused="true" android:drawable="@drawable/grid_focused" />
     <item android:state_pressed="true" android:drawable="@drawable/grid_pressed" />
     <item android:state_selected="true" android:drawable="@drawable/grid_selected" />
index b42b98a..7f30f80 100644 (file)
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.CheckableFrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/wallpaperThumbnailWidth"
     android:layout_height="@dimen/wallpaperThumbnailHeight"
     android:focusable="true"
@@ -33,4 +34,4 @@
         android:layout_height="wrap_content"
         android:layout_gravity="center"
         android:textColor="#FFFFFFFF"/>
-</FrameLayout>
+</com.android.launcher3.CheckableFrameLayout>
index c73bd73..06f01c9 100644 (file)
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.CheckableFrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/wallpaperThumbnailWidth"
     android:layout_height="@dimen/wallpaperThumbnailHeight"
     android:focusable="true"
@@ -26,4 +27,4 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:scaleType="fitXY" />
-</FrameLayout>
+</com.android.launcher3.CheckableFrameLayout>
diff --git a/res/menu/cab_delete_wallpapers.xml b/res/menu/cab_delete_wallpapers.xml
new file mode 100644 (file)
index 0000000..38ac5c4
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, 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.
+*/
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+  <item
+     android:id="@+id/menu_delete"
+     android:title="@string/wallpaper_delete"
+     android:showAsAction="always"
+     android:icon="@android:drawable/ic_menu_delete" />
+</menu>
index aeae48b..bd803c6 100644 (file)
     <string name="folder_name"></string>
     <!-- Button label on Wallpaper picker screen; user selects this button to set a specific wallpaper -->
     <string name="wallpaper_instructions">Set wallpaper</string>
+    <!-- Shown when wallpapers are selected in Wallpaper picker -->
+    <!-- String indicating how many media item(s) is(are) selected
+            eg. 1 selected [CHAR LIMIT=30] -->
+    <plurals name="number_of_items_selected">
+        <item quantity="zero">%1$d selected</item>
+        <item quantity="one">%1$d selected</item>
+        <item quantity="other">%1$d selected</item>
+    </plurals>
+
+    <!-- Label on button to delete wallpaper(s) -->
+    <string name="wallpaper_delete">Delete</string>
     <!-- Label on button in Wallpaper Picker that launches Gallery app -->
     <string name="gallery">Gallery</string>
     <!-- Option in "Select wallpaper from" dialog box -->
diff --git a/src/com/android/launcher3/CheckableFrameLayout.java b/src/com/android/launcher3/CheckableFrameLayout.java
new file mode 100644 (file)
index 0000000..5b7d824
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013 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.launcher3;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Checkable;
+import android.widget.FrameLayout;
+
+public class CheckableFrameLayout extends FrameLayout implements Checkable {
+    private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };
+    boolean mChecked;
+
+    public CheckableFrameLayout(Context context) {
+        super(context);
+    }
+
+    public CheckableFrameLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public CheckableFrameLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    public boolean isChecked() {
+        return mChecked;
+    }
+
+    public void setChecked(boolean checked) {
+        if (checked != mChecked) {
+            mChecked = checked;
+            refreshDrawableState();
+        }
+    }
+
+    public void toggle() {
+        setChecked(!mChecked);
+    }
+
+    @Override
+    protected int[] onCreateDrawableState(int extraSpace) {
+        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+        if (isChecked()) {
+            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
+        }
+        return drawableState;
+    }
+}
index 59318d9..a0b9e6e 100644 (file)
@@ -33,10 +33,13 @@ import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LevelListDrawable;
 import android.net.Uri;
+import android.os.Bundle;
 import android.util.Log;
 import android.util.Pair;
+import android.view.ActionMode;
 import android.view.LayoutInflater;
 import android.view.Menu;
+import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.SubMenu;
 import android.view.View;
@@ -62,6 +65,7 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
 
     private static final int IMAGE_PICK = 5;
     private static final int PICK_WALLPAPER_THIRD_PARTY_ACTIVITY = 6;
+    private static final String TEMP_WALLPAPER_TILES = "TEMP_WALLPAPER_TILES";
 
     private ArrayList<Drawable> mBundledWallpaperThumbs;
     private ArrayList<Integer> mBundledWallpaperResIds;
@@ -72,6 +76,10 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
     private OnClickListener mThumbnailOnClickListener;
 
     private LinearLayout mWallpapersView;
+
+    private ActionMode.Callback mActionModeCallback;
+    private ActionMode mActionMode;
+
     private View.OnLongClickListener mLongClickListener;
 
     ArrayList<Uri> mTempWallpaperTiles = new ArrayList<Uri>();
@@ -120,6 +128,13 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
 
         mThumbnailOnClickListener = new OnClickListener() {
             public void onClick(View v) {
+                if (mActionMode != null) {
+                    // When CAB is up, clicking toggles the item instead
+                    if (v.isLongClickable()) {
+                        mLongClickListener.onLongClick(v);
+                    }
+                    return;
+                }
                 if (mSelectedThumb != null) {
                     mSelectedThumb.setSelected(false);
                 }
@@ -161,6 +176,25 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
                 }
             }
         };
+        mLongClickListener = new View.OnLongClickListener() {
+            // Called when the user long-clicks on someView
+            public boolean onLongClick(View view) {
+                CheckableFrameLayout c = (CheckableFrameLayout) view;
+                c.toggle();
+
+                if (mActionMode != null) {
+                    mActionMode.invalidate();
+                } else {
+                    // Start the CAB using the ActionMode.Callback defined below
+                    mActionMode = startActionMode(mActionModeCallback);
+                    int childCount = mWallpapersView.getChildCount();
+                    for (int i = 0; i < childCount; i++) {
+                        mWallpapersView.getChildAt(i).setSelected(false);
+                    }
+                }
+                return true;
+            }
+        };
 
         // Populate the built-in wallpapers
         findBundledWallpapers();
@@ -191,6 +225,13 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
         galleryThumbnail.setTag(meta);
         galleryThumbnail.setOnClickListener(mThumbnailOnClickListener);
 
+        // Create smooth layout transitions for when items are deleted
+        final LayoutTransition transitioner = new LayoutTransition();
+        transitioner.setDuration(200);
+        transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
+        transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
+        mWallpapersView.setLayoutTransition(transitioner);
+
         // Action bar
         // Show the custom action bar view
         final ActionBar actionBar = getActionBar();
@@ -223,12 +264,95 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
                         }
                     }
                 });
-    }
 
+        // CAB for deleting items
+        mActionModeCallback = new ActionMode.Callback() {
+            // Called when the action mode is created; startActionMode() was called
+            @Override
+            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+                // Inflate a menu resource providing context menu items
+                MenuInflater inflater = mode.getMenuInflater();
+                inflater.inflate(R.menu.cab_delete_wallpapers, menu);
+                return true;
+            }
 
+            private int numCheckedItems() {
+                int childCount = mWallpapersView.getChildCount();
+                int numCheckedItems = 0;
+                for (int i = 0; i < childCount; i++) {
+                    CheckableFrameLayout c = (CheckableFrameLayout) mWallpapersView.getChildAt(i);
+                    if (c.isChecked()) {
+                        numCheckedItems++;
+                    }
+                }
+                return numCheckedItems;
+            }
 
+            // Called each time the action mode is shown. Always called after onCreateActionMode,
+            // but may be called multiple times if the mode is invalidated.
+            @Override
+            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+                int numCheckedItems = numCheckedItems();
+                if (numCheckedItems == 0) {
+                    mode.finish();
+                    return true;
+                } else {
+                    mode.setTitle(getResources().getQuantityString(
+                            R.plurals.number_of_items_selected, numCheckedItems, numCheckedItems));
+                    return true;
+                }
+            }
 
+            // Called when the user selects a contextual menu item
+            @Override
+            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+                switch (item.getItemId()) {
+                    case R.id.menu_delete:
+                        int childCount = mWallpapersView.getChildCount();
+                        ArrayList<View> viewsToRemove = new ArrayList<View>();
+                        for (int i = 0; i < childCount; i++) {
+                            CheckableFrameLayout c =
+                                    (CheckableFrameLayout) mWallpapersView.getChildAt(i);
+                            if (c.isChecked()) {
+                                ThumbnailMetaData meta = (ThumbnailMetaData) c.getTag();
+                                mSavedImages.deleteImage(meta.mSavedWallpaperDbId);
+                                viewsToRemove.add(c);
+                            }
+                        }
+                        for (View v : viewsToRemove) {
+                            mWallpapersView.removeView(v);
+                        }
+                        ///xxxxx DESTROYING
+                        mode.finish(); // Action picked, so close the CAB
+                        return true;
+                    default:
+                        return false;
+                }
+            }
+
+            // Called when the user exits the action mode
+            @Override
+            public void onDestroyActionMode(ActionMode mode) {
+                int childCount = mWallpapersView.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    CheckableFrameLayout c = (CheckableFrameLayout) mWallpapersView.getChildAt(i);
+                    c.setChecked(false);
+                }
+                mSelectedThumb.setSelected(true);
+                mActionMode = null;
+            }
+        };
+    }
+    protected void onSaveInstanceState(Bundle outState) {
+        outState.putParcelableArrayList(TEMP_WALLPAPER_TILES, mTempWallpaperTiles);
+    }
 
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        ArrayList<Uri> uris = savedInstanceState.getParcelableArrayList(TEMP_WALLPAPER_TILES);
+        for (Uri uri : uris) {
+            addTemporaryWallpaperTile(uri);
+        }
+    }
 
     private void populateWallpapersFromAdapter(ViewGroup parent, ImageAdapter ia,
             ArrayList<Integer> imageIds, boolean imagesAreResources, boolean addLongPressHandler) {