Adding ability to delete previously saved wallpapers

- Also preserving temporarily picked wallpapers on
rotation

Change-Id: I35361e2a5619cd986bd8b66268ce9e94b9a0027e
This commit is contained in:
Michael Jurka 2013-09-10 13:39:59 +02:00
parent be2f8ddd80
commit d6dc6043ad
7 changed files with 236 additions and 8 deletions

View 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" />

View 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>

View 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>

View File

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

View File

@ -30,6 +30,17 @@
<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 -->

View File

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

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