diff options
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java | 255 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java | 7 |
2 files changed, 178 insertions, 84 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java index 86fc49e..ee47339 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java @@ -19,10 +19,8 @@ package com.android.systemui.qs; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.app.ActivityManager; -import android.app.AlertDialog; import android.content.ContentResolver; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; @@ -32,12 +30,10 @@ import android.graphics.Color; import android.graphics.Point; import android.graphics.PointF; import android.graphics.PorterDuff; -import android.graphics.drawable.Animatable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.UserHandle; -import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.ArrayMap; @@ -49,7 +45,6 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; -import android.widget.EditText; import android.widget.ExpandableListView; import android.widget.ImageView; import android.widget.LinearLayout; @@ -59,17 +54,16 @@ import com.android.systemui.FontSizeUtils; import com.android.systemui.R; import com.android.systemui.cm.UserContentObserver; import com.android.systemui.qs.tiles.EditTile; -import com.android.systemui.qs.tiles.IntentTile; import com.android.systemui.settings.BrightnessController; import com.android.systemui.settings.ToggleSlider; import com.android.systemui.statusbar.phone.QSTileHost; -import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.tuner.QsTuner; import com.viewpagerindicator.CirclePageIndicator; import cyanogenmod.app.StatusBarPanelCustomTile; import cyanogenmod.providers.CMSettings; import org.cyanogenmod.internal.logging.CMMetricsLogger; +import org.cyanogenmod.internal.util.QSConstants; import org.cyanogenmod.internal.util.QSUtils; import java.util.ArrayList; @@ -355,7 +349,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On @Override public boolean hasOverlappingRendering() { - return mClipper.isAnimating() || mEditing; + return mClipper.isAnimating() || mEditing || !mCurrentlyAnimating.isEmpty(); } @Override @@ -465,7 +459,6 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On mLastRightShift = -1; mQsPanelTop.onStopDrag(); - requestLayout(); } protected View getDropTarget() { @@ -501,14 +494,16 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On } public void setTiles(final Collection<QSTile<?>> tilesCollection) { - final List<QSTile<?>> tiles = new ArrayList<>(tilesCollection); + // we try to be as efficient as possible here because this can happen while the user + // is in edit mode, or maybe even while tiles are animating + // step 1: stop all animations + // step 2: remove tiles no longer to be used, cache ones that are still valid + // step 3: remove empty viewpager pages + // step 4: generate new tiles, re-add cached ones + if (DEBUG_TILES) { - Log.i(TAG, "setTiles() called with " + "tiles = [" - + tiles + "]"); + Log.i(TAG, "setTiles() called with tiles = [" + tilesCollection + "]"); } - - int currentViewPagerPage = mViewPager.getCurrentItem(); - if (mLastDragRecord != null && mRecords.indexOf(mLastDragRecord) == -1) { // the last removed record might be stored in mLastDragRecord if we just shifted // re-add it to the list so we'll clean it up below @@ -516,25 +511,41 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On mLastDragRecord = null; } - Map<QSTile<?>, DragTileRecord> recordMap = new ArrayMap<>(); + // step kinda-1 + if (mDraggingRecord != null) { + // dragging record might be animating back, force it to finished position + mDraggingRecord.tileView.animate().cancel(); + } + + int currentViewPagerPage = mViewPager.getCurrentItem(); + int removedPages = 0; + + Map<QSTile<?>, DragTileRecord> cachedRecords = new ArrayMap<>(); ListIterator<TileRecord> iterator = mRecords.listIterator(mRecords.size()); int recordsRemoved = 0; // cleanup current records - while (iterator.hasPrevious()) { + while (iterator.hasPrevious()) { // mRecords DragTileRecord dr = (DragTileRecord) iterator.previous(); - if (dr.page >= 0) { - // clean up view - mPages.get(dr.page).removeView(dr.tileView); - } + // step 1 + dr.tileView.animate().cancel(); - if (tiles.contains(dr.tile)) { + // step 2 + if (tilesCollection.contains(dr.tile)) { if (DEBUG_TILES) { Log.i(TAG, "caching tile: " + dr.tile); } - recordMap.put(dr.tile, dr); + cachedRecords.put(dr.tile, dr); } else { + if (dr.page >= 0) { + if (DEBUG_TILES) { + Log.w(TAG, "removed dr.tileView: " + dr.tileView + " from page: " + + dr.page + " (dest page: " + dr.destinationPage + ")"); + } + + removeTileView(dr.tileView); + } if (DEBUG_TILES) { Log.i(TAG, "removing tile: " + dr.tile); } @@ -543,74 +554,92 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On iterator.remove(); recordsRemoved++; - if (dr.page >= getCurrentMaxPageCount() - 1) { - final int childCount = mPages.get(dr.page).getChildCount(); - - if (childCount == 0) { - final int currentIndex = mViewPager.getCurrentItem(); - if (currentIndex > 0 && currentViewPagerPage == currentIndex) { - // if we are about to remove the page we are currently on, move back - currentViewPagerPage--; - } - final int pageIndex = dr.page + (mEditing ? 1 : 0); - mPagerAdapter.startUpdate(mViewPager); - mPagerAdapter.destroyItem(mViewPager, pageIndex, mPages.get(dr.page)); - mPagerAdapter.finishUpdate(mViewPager); - mPagerAdapter.notifyDataSetChanged(); - } - } + dr.page = -1; + dr.destinationPage = -1; } - dr.page = -1; - dr.destinationPage = -1; } - // at this point recordMap should have all retained tiles, no new or old tiles - int delta = tiles.size() - recordMap.size() - recordsRemoved; + // at this point cachedRecords should have all retained tiles, no new or old tiles + int delta = tilesCollection.size() - cachedRecords.size() - recordsRemoved; if (DEBUG_TILES) { Log.i(TAG, "record map delta: " + delta); } - mRecords.ensureCapacity(tiles.size()); - mPagerAdapter.notifyDataSetChanged(); + // step 3 + final Iterator<QSPage> pageIterator = mPages.iterator(); + while (pageIterator.hasNext()) { + final QSPage page = pageIterator.next(); + final int viewpagerIndex = page.getPageIndex() + (mEditing ? 1 : 0); + final int childCount = page.getChildCount(); - // even though we explicitly destroy old pages, without this call, - // the viewpager doesn't seem to want to pick up the fact that we have less pages - // and allows "empty" scrolls to the right where there is no page. - mViewPager.setAdapter(mPagerAdapter); + if (DEBUG_TILES) { + Log.d(TAG, "page " + viewpagerIndex + " has " + childCount); + } + if (page.getPageIndex() >= getCurrentMaxPageCount() - 1) { + if (DEBUG_TILES) { + Log.d(TAG, "page : " + page + " has " + childCount + " children"); + } + if (childCount == 0) { + removedPages++; + + page.removeAllViews(); + mPagerAdapter.startUpdate(mViewPager); + mPagerAdapter.destroyItem(mViewPager, viewpagerIndex, page); + mPagerAdapter.finishUpdate(mViewPager); + mPagerAdapter.notifyDataSetChanged(); + } + } + } + + if (removedPages > 0) { + // even though we explicitly destroy old pages, without this call, + // the viewpager doesn't seem to want to pick up the fact that we have less pages + // and allows "empty" scrolls to the right where there is no page. + if (DEBUG_TILES) { + Log.d(TAG, "re-setting adapter, page: " + currentViewPagerPage); + } + mViewPager.setAdapter(mPagerAdapter); + mViewPager.setCurrentItem(Math.min(currentViewPagerPage, mPagerAdapter.getCount()), + false); + mPagerAdapter.notifyDataSetChanged(); + } + + // step 4 + mRecords.ensureCapacity(tilesCollection.size()); + int runningCount = 0; - // add new tiles - for (int i = 0; i < tiles.size(); i++) { - QSTile<?> tile = tiles.get(i); - final int tileDestPage = getPagesForCount(i + 1) - 1; + final Iterator<QSTile<?>> newTileIterator = tilesCollection.iterator(); + while (newTileIterator.hasNext()) { + QSTile<?> tile = newTileIterator.next(); + final int tileDestPage = getPagesForCount(runningCount + 1) - 1; if (DEBUG_TILES) { - Log.d(TAG, "tile at : " + i + ": " + tile + " to dest page: " + tileDestPage); + Log.d(TAG, "tile at : " + runningCount + ": " + tile + + " to dest page: " + tileDestPage); } DragTileRecord record; - if (!recordMap.containsKey(tile)) { + if (!cachedRecords.containsKey(tile)) { if (DEBUG_TILES) { - Log.d(TAG, "tile at: " + i + " not cached, adding it to records"); + Log.d(TAG, "tile at: " + runningCount + " not cached, adding it to records"); } record = makeRecord(tile); record.destinationPage = tileDestPage; - recordMap.put(tile, record); - mRecords.add(i, record); + mRecords.add(runningCount, record); mPagerAdapter.notifyDataSetChanged(); } else { - record = recordMap.get(tile); + record = cachedRecords.get(tile); if (DEBUG_TILES) { - Log.d(TAG, "tile at : " + i + ": cached, restoring: " + record); + Log.d(TAG, "tile at : " + runningCount + ": cached, restoring: " + record); } - int indexOf = mRecords.indexOf(record); - if (indexOf != i) { - if (DEBUG_TILES) { - Log.w(TAG, "moving index of " + record + " from " - + indexOf + " to " + i); - } - Collections.swap(mRecords, indexOf, i); - } + mPages.get(record.page).removeView(record.tileView); + + record.page = -1; record.destinationPage = tileDestPage; + + mRecords.remove(record); + mRecords.add(runningCount, record); + mPagerAdapter.notifyDataSetChanged(); } if (record.page == -1) { // add the view @@ -620,11 +649,9 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On Log.d(TAG, "added view " + record); } } + runningCount++; } - // restore the visible page - mViewPager.setCurrentItem(currentViewPagerPage, false); - if (isShowingDetail()) { mDetail.bringToFront(); } @@ -718,10 +745,18 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On return r; } + private void removeTileView(QSTileView v) { + for (QSPage page : mPages) { + page.removeView(v); + page.removeTransientView(v); + } + + } + private void removeDraggingRecord() { // what spec is this tile? String spec = mHost.getSpec(mDraggingRecord.tile); - if (DEBUG_DRAG) { + if (DEBUG_TILES) { Log.w(TAG, "removing tile: " + mDraggingRecord + " with spec: " + spec); } onStopDrag(); @@ -1014,7 +1049,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On } if (originatingTileEvent && !event.getResult()) { // view pager probably ate the event - restoreDraggingTilePosition(v); + restoreDraggingTilePosition(v, null); } break; @@ -1032,15 +1067,27 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On Log.d(TAG, "dropping on delete target!!"); } if (mDraggingRecord.tile instanceof EditTile) { + final QSTileView editTileView = mDraggingRecord.tileView; + mQsPanelTop.toast(R.string.quick_settings_cannot_delete_edit_tile); - restoreDraggingTilePosition(v); + restoreDraggingTilePosition(v, new Runnable() { + @Override + public void run() { + // move edit tile to the back + final TileRecord editTile = getRecord(editTileView); + if (mRecords.remove(editTile)) { + // we depend on mHost.setTiles() placing it on the end + persistRecords(); + } + } + }); break; } else { mRestored = true; removeDraggingRecord(); } } else { - restoreDraggingTilePosition(v); + restoreDraggingTilePosition(v, null); } break; @@ -1171,7 +1218,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On return false; } - private void restoreDraggingTilePosition(View v) { + private void restoreDraggingTilePosition(View v, final Runnable onAnimationFinishedRunnable) { if (mRestored) { return; } @@ -1251,6 +1298,20 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On } @Override + public void onAnimationCancel(Animator animation) { + mViewPager.requestDisallowInterceptTouchEvent(false); + removeTransientView(mDraggingRecord.tileView); + mCurrentlyAnimating.remove(mDraggingRecord); + mRestoring = false; + mPagerAdapter.notifyDataSetChanged(); + onStopDrag(); + + if (onAnimationFinishedRunnable != null) { + postOnAnimation(onAnimationFinishedRunnable); + } + } + + @Override public void onAnimationEnd(Animator animation) { mViewPager.requestDisallowInterceptTouchEvent(false); @@ -1265,8 +1326,8 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On Log.i(TAG, "drag record was attached"); } } - mDraggingRecord.page = mDraggingRecord.destinationPage; targetP.addView(mDraggingRecord.tileView); + mDraggingRecord.page = mDraggingRecord.destinationPage; mDraggingRecord.tileView.setX(mDraggingRecord.destination.x); // reset this to be in the coords of the page, not viewpager anymore @@ -1281,6 +1342,12 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On mPagerAdapter.notifyDataSetChanged(); } onStopDrag(); + + if (onAnimationFinishedRunnable != null) { + postOnAnimation(onAnimationFinishedRunnable); + } else { + requestLayout(); + } } }); } @@ -1497,10 +1564,16 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On .y(ti.destination.y) .setListener(new AnimatorListenerAdapter() { @Override + public void onAnimationCancel(Animator animation) { + tilePageSource.removeTransientView(ti.tileView); + mCurrentlyAnimating.remove(ti); + } + + @Override public void onAnimationEnd(Animator animation) { tilePageSource.removeTransientView(ti.tileView); - ti.page = tilePageTarget.getPageIndex(); tilePageTarget.addView(ti.tileView); + ti.page = tilePageTarget.getPageIndex(); ti.tileView.setX(ti.destination.x); ti.tileView.setY(ti.destination.y); @@ -1516,6 +1589,11 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On .y(ti.destination.y) .setListener(new AnimatorListenerAdapter() { @Override + public void onAnimationCancel(Animator animation) { + mCurrentlyAnimating.remove(ti); + } + + @Override public void onAnimationEnd(Animator animation) { mCurrentlyAnimating.remove(ti); final boolean dual = getPage(ti.destinationPage).dualRecord(ti); @@ -1551,10 +1629,16 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On .y(last.destination.y) .setListener(new AnimatorListenerAdapter() { @Override + public void onAnimationCancel(Animator animation) { + tilePageSource.removeTransientView(last.tileView); + mCurrentlyAnimating.remove(last); + } + + @Override public void onAnimationEnd(Animator animation) { tilePageSource.removeTransientView(last.tileView); - last.page = tilePageTarget.getPageIndex(); tilePageTarget.addView(last.tileView); + last.page = tilePageTarget.getPageIndex(); last.tileView.setX(last.destination.x); last.tileView.setY(last.destination.y); @@ -1573,6 +1657,11 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On .y(last.destination.y) .setListener(new AnimatorListenerAdapter() { @Override + public void onAnimationCancel(Animator animation) { + mCurrentlyAnimating.remove(last); + } + + @Override public void onAnimationEnd(Animator animation) { if (DEBUG_DRAG) { Log.i(TAG, "shift finished: " + last); @@ -1654,10 +1743,16 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On } @Override + public void onAnimationCancel(Animator animation) { + page.removeTransientView(ti.tileView); + mCurrentlyAnimating.remove(ti); + } + + @Override public void onAnimationEnd(Animator animation) { page.removeTransientView(ti.tileView); - ti.page = page.getPageIndex(); page.addView(ti.tileView); + ti.page = page.getPageIndex(); mCurrentlyAnimating.remove(ti); requestLayout(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java index b190edc..2c68c62 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java @@ -399,11 +399,10 @@ public class QSTileHost implements QSTile.Host, Tunable { tiles.add(tile); } } - // ensure edit tile is present - if (tiles.size() < TILES_PER_PAGE && !tiles.contains("edit")) { + // ensure edit tile is present, default placement should be handled in the default + // tile list. + if (!tiles.contains("edit")) { tiles.add("edit"); - } else if (tiles.size() > TILES_PER_PAGE && !tiles.contains("edit")) { - tiles.add((TILES_PER_PAGE - 1), "edit"); } return tiles; } |