List of usage examples for android.support.v4.util LongSparseArray LongSparseArray
public LongSparseArray(int i)
From source file:nz.ac.otago.psyanlab.common.model.util.LongSparseArrayGsonAdapter.java
@Override public LongSparseArray<T> read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull();//from ww w.j a v a 2 s . co m return null; } LongSparseArray<Object> temp = mGson.fromJson(in, mTypeOfLongSparseArrayOfObject); LongSparseArray<T> result = new LongSparseArray<T>(temp.size()); long key; JsonElement tElement; for (int i = 0; i < temp.size(); i++) { key = temp.keyAt(i); tElement = mGson.toJsonTree(temp.get(key), new TypeToken<T>() { }.getType()); result.put(key, mGson.fromJson(tElement, mTClazz)); } return result; }
From source file:org.sufficientlysecure.keychain.provider.ProviderHelper.java
private LongSparseArray<UncachedPublicKey> getUncachedMasterKeys(Uri queryUri) { Cursor cursor = mContentResolver.query(queryUri, new String[] { KeyRingData.MASTER_KEY_ID, KeyRingData.KEY_RING_DATA }, null, null, null); LongSparseArray<UncachedPublicKey> result = new LongSparseArray<UncachedPublicKey>(cursor.getCount()); try {/*ww w.j av a 2s .co m*/ if (cursor != null && cursor.moveToFirst()) do { long masterKeyId = cursor.getLong(0); byte[] data = cursor.getBlob(1); if (data != null) { try { result.put(masterKeyId, UncachedKeyRing.decodePublicFromData(data).getPublicKey()); } catch (PgpGeneralException e) { Log.e(Constants.TAG, "Error parsing keyring, skipping."); } catch (IOException e) { Log.e(Constants.TAG, "IO error, skipping keyring"); } } } while (cursor.moveToNext()); } finally { if (cursor != null) { cursor.close(); } } return result; }
From source file:org.pixmob.freemobile.netstat.SyncService.java
private void run(Intent intent, final SQLiteDatabase db) throws Exception { final long now = dateAtMidnight(System.currentTimeMillis()); Log.i(TAG, "Initializing statistics before uploading"); final LongSparseArray<DailyStat> stats = new LongSparseArray<DailyStat>(15); final Set<Long> uploadedStats = new HashSet<Long>(15); final long statTimestampStart = now - 7 * DAY_IN_MILLISECONDS; // Get pending uploads. Cursor c = db.query("daily_stat", new String[] { "stat_timestamp", "orange", "free_mobile", "sync" }, "stat_timestamp>=? AND stat_timestamp<?", new String[] { String.valueOf(statTimestampStart), String.valueOf(now) }, null, null, null); try {/* w w w . j a va2 s.co m*/ while (c.moveToNext()) { final long d = c.getLong(0); final int sync = c.getInt(3); if (SYNC_UPLOADED == sync) { uploadedStats.add(d); } else if (SYNC_PENDING == sync) { final DailyStat s = new DailyStat(); s.orange = c.getInt(1); s.freeMobile = c.getInt(2); stats.put(d, s); } } } finally { c.close(); } // Compute missing uploads. final ContentValues cv = new ContentValues(); db.beginTransaction(); try { for (long d = statTimestampStart; d < now; d += DAY_IN_MILLISECONDS) { if (stats.get(d) == null && !uploadedStats.contains(d)) { final DailyStat s = computeDailyStat(d); cv.put("stat_timestamp", d); cv.put("orange", s.orange); cv.put("free_mobile", s.freeMobile); cv.put("sync", SYNC_PENDING); db.insertOrThrow("daily_stat", null, cv); stats.put(d, s); } } db.setTransactionSuccessful(); } finally { db.endTransaction(); } // Delete old statistics. if (DEBUG) { Log.d(TAG, "Cleaning up upload database"); } db.delete("daily_stat", "stat_timestamp<?", new String[] { String.valueOf(statTimestampStart) }); // Check if there are any statistics to upload. final int statsLen = stats.size(); if (statsLen == 0) { Log.i(TAG, "Nothing to upload"); return; } // Check if the remote server is up. final HttpClient client = createHttpClient(); try { client.head(createServerUrl(null)).execute(); } catch (HttpClientException e) { Log.w(TAG, "Remote server is not available: cannot upload statistics", e); return; } // Upload statistics. Log.i(TAG, "Uploading statistics"); final JSONObject json = new JSONObject(); final String deviceId = getDeviceId(); final boolean deviceWasRegistered = intent.getBooleanExtra(EXTRA_DEVICE_REG, false); for (int i = 0; i < statsLen; ++i) { final long d = stats.keyAt(i); final DailyStat s = stats.get(d); try { json.put("timeOnOrange", s.orange); json.put("timeOnFreeMobile", s.freeMobile); } catch (JSONException e) { final IOException ioe = new IOException("Failed to prepare statistics upload"); ioe.initCause(e); throw ioe; } final String url = createServerUrl( "/device/" + deviceId + "/daily/" + DateFormat.format("yyyyMMdd", d)); if (DEBUG) { Log.d(TAG, "Uploading statistics for " + DateUtils.formatDate(d) + " to: " + url); } final byte[] rawJson = json.toString().getBytes("UTF-8"); try { client.post(url).content(rawJson, "application/json") .expect(HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_NOT_FOUND) .to(new HttpResponseHandler() { @Override public void onResponse(HttpResponse response) throws Exception { final int sc = response.getStatusCode(); if (HttpURLConnection.HTTP_NOT_FOUND == sc) { // Check if the device has just been // registered. if (deviceWasRegistered) { throw new IOException("Failed to upload statistics"); } else { // Got 404: the device does not exist. // We need to register this device. registerDevice(deviceId); // Restart this service. startService(new Intent(getApplicationContext(), SyncService.class) .putExtra(EXTRA_DEVICE_REG, true)); } } else if (HttpURLConnection.HTTP_OK == sc) { // Update upload database. cv.clear(); cv.put("sync", SYNC_UPLOADED); db.update("daily_stat", cv, "stat_timestamp=?", new String[] { String.valueOf(d) }); if (DEBUG) { Log.d(TAG, "Upload done for " + DateUtils.formatDate(d)); } } } }).execute(); } catch (HttpClientException e) { final IOException ioe = new IOException("Failed to send request with statistics"); ioe.initCause(e); throw ioe; } } }
From source file:org.thialfihar.android.apg.provider.ProviderHelper.java
public LongSparseArray<PGPKeyRing> getPGPKeyRings(Uri queryUri) { Cursor cursor = mContentResolver.query(queryUri, new String[] { KeyRingData.MASTER_KEY_ID, KeyRingData.KEY_RING_DATA }, null, null, null); LongSparseArray<PGPKeyRing> result = new LongSparseArray<PGPKeyRing>(cursor.getCount()); try {/* w w w.j a v a 2 s . com*/ if (cursor != null && cursor.moveToFirst()) do { long masterKeyId = cursor.getLong(0); byte[] data = cursor.getBlob(1); if (data != null) { result.put(masterKeyId, PgpConversionHelper.BytesToPGPKeyRing(data)); } } while (cursor.moveToNext()); } finally { if (cursor != null) { cursor.close(); } } return result; }
From source file:org.pixmob.freemobile.netstat.SyncServiceTesting.java
private void run(Intent intent, final SQLiteDatabase db) throws Exception { final long now = dateAtMidnight(System.currentTimeMillis()); Log.i(TAG, "Initializing statistics before uploading"); final LongSparseArray<DailyStat> stats = new LongSparseArray<>(15); final Set<Long> uploadedStats = new HashSet<>(15); final long statTimestampStart = now - 7 * DAY_IN_MILLISECONDS; // Get pending uploads. Cursor pendingUploadsCursor = null; try {/*from w w w. j a v a 2s . c om*/ pendingUploadsCursor = db.query("daily_stat_testing", new String[] { "stat_timestamp", "orange", "free_mobile", "free_mobile_3g", "free_mobile_4g", "free_mobile_femtocell", "sync" }, "stat_timestamp>=? AND stat_timestamp<?", new String[] { String.valueOf(statTimestampStart), String.valueOf(now) }, null, null, null); while (pendingUploadsCursor.moveToNext()) { final long d = pendingUploadsCursor.getLong(0); final int sync = pendingUploadsCursor.getInt(6); if (SYNC_UPLOADED == sync) { uploadedStats.add(d); } else if (SYNC_PENDING == sync) { final DailyStat s = new DailyStat(); s.orange = pendingUploadsCursor.getInt(1); s.freeMobile = pendingUploadsCursor.getInt(2); s.freeMobile3G = pendingUploadsCursor.getInt(3); s.freeMobile4G = pendingUploadsCursor.getInt(4); s.freeMobileFemtocell = pendingUploadsCursor.getInt(5); stats.put(d, s); } } } catch (Exception e) { Log.e(TAG, Log.getStackTraceString(e)); } finally { try { if (pendingUploadsCursor != null) pendingUploadsCursor.close(); } catch (Exception e) { Log.e(TAG, Log.getStackTraceString(e)); } } // Compute missing uploads. final ContentValues cv = new ContentValues(); db.beginTransaction(); try { for (long d = statTimestampStart; d < now; d += DAY_IN_MILLISECONDS) { if (stats.get(d) == null && !uploadedStats.contains(d)) { final DailyStat s = computeDailyStat(d); cv.put("stat_timestamp", d); cv.put("orange", s.orange); cv.put("free_mobile", s.freeMobile); cv.put("free_mobile_3g", s.freeMobile3G); cv.put("free_mobile_4g", s.freeMobile4G); cv.put("free_mobile_femtocell", s.freeMobileFemtocell); cv.put("sync", SYNC_PENDING); db.insertOrThrow("daily_stat_testing", null, cv); stats.put(d, s); } } db.setTransactionSuccessful(); } finally { db.endTransaction(); } // Delete old statistics. if (DEBUG) { Log.d(TAG, "Cleaning up upload database"); } db.delete("daily_stat_testing", "stat_timestamp<?", new String[] { String.valueOf(statTimestampStart) }); // Check if there are any statistics to upload. final int statsLen = stats.size(); if (statsLen == 0) { Log.i(TAG, "Nothing to upload"); return; } // Check if the remote server is up. final HttpClient client = createHttpClient(); try { client.head(createServerUrl(null)).execute(); } catch (HttpClientException e) { Log.w(TAG, "Remote server is not available: cannot upload statistics", e); return; } // Upload statistics. Log.i(TAG, "Uploading statistics"); final JSONObject json = new JSONObject(); final String deviceId = getDeviceId(); final boolean deviceWasRegistered = intent.getBooleanExtra(EXTRA_DEVICE_REG, false); for (int i = 0; i < statsLen; ++i) { final long d = stats.keyAt(i); final DailyStat s = stats.get(d); try { json.put("timeOnOrange", s.orange); json.put("timeOnFreeMobile", s.freeMobile); json.put("timeOnFreeMobile3g", s.freeMobile3G); json.put("timeOnFreeMobile4g", s.freeMobile4G); json.put("timeOnFreeMobileFemtocell", s.freeMobileFemtocell); } catch (JSONException e) { final IOException ioe = new IOException("Failed to prepare statistics upload"); ioe.initCause(e); throw ioe; } final String url = createServerUrl( "/device/" + deviceId + "/daily/" + DateFormat.format("yyyyMMdd", d)); if (DEBUG) { Log.d(TAG, "Uploading statistics for " + DateUtils.formatDate(d) + " to: " + url); } final byte[] rawJson = json.toString().getBytes("UTF-8"); try { client.post(url).content(rawJson, "application/json") .expect(HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_NOT_FOUND) .to(new HttpResponseHandler() { @Override public void onResponse(HttpResponse response) throws Exception { final int sc = response.getStatusCode(); if (HttpURLConnection.HTTP_NOT_FOUND == sc) { // Check if the device has just been // registered. if (deviceWasRegistered) { throw new IOException("Failed to upload statistics"); } else { // Got 404: the device does not exist. // We need to register this device. registerDevice(deviceId); // Restart this service. startService(new Intent(getApplicationContext(), SyncServiceTesting.class) .putExtra(EXTRA_DEVICE_REG, true)); } } else if (HttpURLConnection.HTTP_OK == sc) { // Update upload database. cv.clear(); cv.put("sync", SYNC_UPLOADED); db.update("daily_stat_testing", cv, "stat_timestamp=?", new String[] { String.valueOf(d) }); if (DEBUG) { Log.d(TAG, "Upload done for " + DateUtils.formatDate(d)); } } } }).execute(); } catch (HttpClientException e) { final IOException ioe = new IOException("Failed to send request with statistics"); ioe.initCause(e); throw ioe; } } }
From source file:android.support.transition.TransitionPort.java
/** * This method, essentially a wrapper around all calls to createAnimator for all * possible target views, is called with the entire set of start/end * values. The implementation in Transition iterates through these lists * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)} * with each set of start/end values on this transition. The * TransitionSet subclass overrides this method and delegates it to * each of its children in succession.//from ww w . j a v a 2 s . c o m * * @hide */ @RestrictTo(GROUP_ID) protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues, TransitionValuesMaps endValues) { if (DBG) { Log.d(LOG_TAG, "createAnimators() for " + this); } ArrayMap<View, TransitionValues> endCopy = new ArrayMap<>(endValues.viewValues); SparseArray<TransitionValues> endIdCopy = new SparseArray<>(endValues.idValues.size()); for (int i = 0; i < endValues.idValues.size(); ++i) { int id = endValues.idValues.keyAt(i); endIdCopy.put(id, endValues.idValues.valueAt(i)); } LongSparseArray<TransitionValues> endItemIdCopy = new LongSparseArray<>(endValues.itemIdValues.size()); for (int i = 0; i < endValues.itemIdValues.size(); ++i) { long id = endValues.itemIdValues.keyAt(i); endItemIdCopy.put(id, endValues.itemIdValues.valueAt(i)); } // Walk through the start values, playing everything we find // Remove from the end set as we go ArrayList<TransitionValues> startValuesList = new ArrayList<>(); ArrayList<TransitionValues> endValuesList = new ArrayList<>(); for (View view : startValues.viewValues.keySet()) { TransitionValues start; TransitionValues end = null; boolean isInListView = false; if (view.getParent() instanceof ListView) { isInListView = true; } if (!isInListView) { int id = view.getId(); start = startValues.viewValues.get(view) != null ? startValues.viewValues.get(view) : startValues.idValues.get(id); if (endValues.viewValues.get(view) != null) { end = endValues.viewValues.get(view); endCopy.remove(view); } else if (id != View.NO_ID) { end = endValues.idValues.get(id); View removeView = null; for (View viewToRemove : endCopy.keySet()) { if (viewToRemove.getId() == id) { removeView = viewToRemove; } } if (removeView != null) { endCopy.remove(removeView); } } endIdCopy.remove(id); if (isValidTarget(view, id)) { startValuesList.add(start); endValuesList.add(end); } } else { ListView parent = (ListView) view.getParent(); if (parent.getAdapter().hasStableIds()) { int position = parent.getPositionForView(view); long itemId = parent.getItemIdAtPosition(position); start = startValues.itemIdValues.get(itemId); endItemIdCopy.remove(itemId); // TODO: deal with targetIDs for itemIDs for ListView items startValuesList.add(start); endValuesList.add(end); } } } int startItemIdCopySize = startValues.itemIdValues.size(); for (int i = 0; i < startItemIdCopySize; ++i) { long id = startValues.itemIdValues.keyAt(i); if (isValidTarget(null, id)) { TransitionValues start = startValues.itemIdValues.get(id); TransitionValues end = endValues.itemIdValues.get(id); endItemIdCopy.remove(id); startValuesList.add(start); endValuesList.add(end); } } // Now walk through the remains of the end set for (View view : endCopy.keySet()) { int id = view.getId(); if (isValidTarget(view, id)) { TransitionValues start = startValues.viewValues.get(view) != null ? startValues.viewValues.get(view) : startValues.idValues.get(id); TransitionValues end = endCopy.get(view); endIdCopy.remove(id); startValuesList.add(start); endValuesList.add(end); } } int endIdCopySize = endIdCopy.size(); for (int i = 0; i < endIdCopySize; ++i) { int id = endIdCopy.keyAt(i); if (isValidTarget(null, id)) { TransitionValues start = startValues.idValues.get(id); TransitionValues end = endIdCopy.get(id); startValuesList.add(start); endValuesList.add(end); } } int endItemIdCopySize = endItemIdCopy.size(); for (int i = 0; i < endItemIdCopySize; ++i) { long id = endItemIdCopy.keyAt(i); // TODO: Deal with targetIDs and itemIDs TransitionValues start = startValues.itemIdValues.get(id); TransitionValues end = endItemIdCopy.get(id); startValuesList.add(start); endValuesList.add(end); } ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); for (int i = 0; i < startValuesList.size(); ++i) { TransitionValues start = startValuesList.get(i); TransitionValues end = endValuesList.get(i); // Only bother trying to animate with values that differ between start/end if (start != null || end != null) { if (start == null || !start.equals(end)) { if (DBG) { View view = (end != null) ? end.view : start.view; Log.d(LOG_TAG, " differing start/end values for view " + view); if (start == null || end == null) { Log.d(LOG_TAG, " " + ((start == null) ? "start null, end non-null" : "start non-null, end null")); } else { for (String key : start.values.keySet()) { Object startValue = start.values.get(key); Object endValue = end.values.get(key); if (startValue != endValue && !startValue.equals(endValue)) { Log.d(LOG_TAG, " " + key + ": start(" + startValue + "), end(" + endValue + ")"); } } } } // TODO: what to do about targetIds and itemIds? Animator animator = createAnimator(sceneRoot, start, end); if (animator != null) { // Save animation info for future cancellation purposes View view; TransitionValues infoValues = null; if (end != null) { view = end.view; String[] properties = getTransitionProperties(); if (view != null && properties != null && properties.length > 0) { infoValues = new TransitionValues(); infoValues.view = view; TransitionValues newValues = endValues.viewValues.get(view); if (newValues != null) { for (int j = 0; j < properties.length; ++j) { infoValues.values.put(properties[j], newValues.values.get(properties[j])); } } int numExistingAnims = runningAnimators.size(); for (int j = 0; j < numExistingAnims; ++j) { Animator anim = runningAnimators.keyAt(j); AnimationInfo info = runningAnimators.get(anim); if (info.values != null && info.view == view && ((info.name == null && getName() == null) || info.name.equals(getName()))) { if (info.values.equals(infoValues)) { // Favor the old animator animator = null; break; } } } } } else { view = start.view; } if (animator != null) { AnimationInfo info = new AnimationInfo(view, getName(), WindowIdPort.getWindowId(sceneRoot), infoValues); runningAnimators.put(animator, info); mAnimators.add(animator); } } } } } }
From source file:com.sky.drovik.player.media.DiskCache.java
private void loadIndex() { final String indexFilePath = getIndexFilePath(); try {/*from ww w .j a va 2 s . c om*/ // Open the input stream. final FileInputStream fileInput = new FileInputStream(indexFilePath); final BufferedInputStream bufferedInput = new BufferedInputStream(fileInput, 1024); final DataInputStream dataInput = new DataInputStream(bufferedInput); // Read the header. final int magic = dataInput.readInt(); final int version = dataInput.readInt(); boolean valid = true; if (magic != INDEX_HEADER_MAGIC) { Log.e(TAG, "Index file appears to be corrupt (" + magic + " != " + INDEX_HEADER_MAGIC + "), " + indexFilePath); valid = false; } if (valid && version != INDEX_HEADER_VERSION) { // Future versions can implement upgrade in this case. Log.e(TAG, "Index file version " + version + " not supported"); valid = false; } if (valid) { mTailChunk = dataInput.readShort(); } // Read the entries. if (valid) { // Parse the index file body into the in-memory map. final int numEntries = dataInput.readInt(); mIndexMap = new LongSparseArray<Record>(numEntries); synchronized (mIndexMap) { for (int i = 0; i < numEntries; ++i) { final long key = dataInput.readLong(); final int chunk = dataInput.readShort(); final int offset = dataInput.readInt(); final int size = dataInput.readInt(); final int sizeOnDisk = dataInput.readInt(); final long timestamp = dataInput.readLong(); mIndexMap.append(key, new Record(chunk, offset, size, sizeOnDisk, timestamp)); } } } dataInput.close(); if (!valid) { deleteAll(); } } catch (FileNotFoundException e) { // If the file does not exist the cache is empty, so just continue. } catch (IOException e) { Log.e(TAG, "Unable to read the index file " + indexFilePath); } finally { if (mIndexMap == null) { mIndexMap = new LongSparseArray<Record>(); } } }
From source file:com.albedinsky.android.database.model.EntityModelCursorWrapper.java
/** * Returns data of this cursor wrapper in a sparse array of models mapped to theirs id. * * @return Array of models with theirs corresponding data or empty array if this cursor does not * have any data available.//from ww w . j a v a 2 s. c o m * @see #asList() * @see #getCount() */ @NonNull public LongSparseArray<M> asSparseArray() { this.assertNotClosedOrThrow(); final int count = getCount(); if (count > 0 && moveToFirst()) { final LongSparseArray<M> sparseArray = new LongSparseArray<>(count); do { sparseArray.append(getId(), onGetModel()); } while (moveToNext()); return sparseArray; } return new LongSparseArray<>(0); }
From source file:com.vuze.android.remote.SessionInfo.java
private void placeTagListIntoMap(List<?> tagList) { int numUserCategories = 0; long uidUncat = -1; mapTags = new LongSparseArray<>(tagList.size()); for (Object tag : tagList) { if (tag instanceof Map) { Map<?, ?> mapTag = (Map<?, ?>) tag; Long uid = MapUtils.getMapLong(mapTag, "uid", 0); mapTags.put(uid, mapTag);/* w w w . j a va 2 s. c om*/ int type = MapUtils.getMapInt(mapTag, "type", 0); //category if (type == 1) { // USER=0,ALL=1,UNCAT=2 int catType = MapUtils.getMapInt(mapTag, "category-type", -1); if (catType == 0) { numUserCategories++; } else if (catType == 1) { tagAllUID = uid; } else if (catType == 2) { uidUncat = uid; } } } } if (numUserCategories == 0 && uidUncat >= 0) { mapTags.remove(uidUncat); } if (tagListReceivedListeners.size() > 0) { List<Map<?, ?>> tags = getTags(); for (TagListReceivedListener l : tagListReceivedListeners) { l.tagListReceived(tags); } } }
From source file:android.support.transition.Transition.java
/** * This method, essentially a wrapper around all calls to createAnimator for all * possible target views, is called with the entire set of start/end * values. The implementation in Transition iterates through these lists * and calls {@link #createAnimator(android.view.ViewGroup, android.support.transition.TransitionValues, android.support.transition.TransitionValues)} * with each set of start/end values on this transition. The * TransitionSet subclass overrides this method and delegates it to * each of its children in succession./*from ww w . j a v a 2 s .c o m*/ * * @hide */ protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues, TransitionValuesMaps endValues) { if (DBG) { Log.d(LOG_TAG, "createAnimators() for " + this); } ArrayMap<View, TransitionValues> endCopy = new ArrayMap<View, TransitionValues>(endValues.viewValues); SparseArray<TransitionValues> endIdCopy = new SparseArray<TransitionValues>(endValues.idValues.size()); for (int i = 0; i < endValues.idValues.size(); ++i) { int id = endValues.idValues.keyAt(i); endIdCopy.put(id, endValues.idValues.valueAt(i)); } LongSparseArray<TransitionValues> endItemIdCopy = new LongSparseArray<TransitionValues>( endValues.itemIdValues.size()); for (int i = 0; i < endValues.itemIdValues.size(); ++i) { long id = endValues.itemIdValues.keyAt(i); endItemIdCopy.put(id, endValues.itemIdValues.valueAt(i)); } // Walk through the start values, playing everything we find // Remove from the end set as we go ArrayList<TransitionValues> startValuesList = new ArrayList<TransitionValues>(); ArrayList<TransitionValues> endValuesList = new ArrayList<TransitionValues>(); for (View view : startValues.viewValues.keySet()) { TransitionValues start = null; TransitionValues end = null; boolean isInListView = false; if (view.getParent() instanceof ListView) { isInListView = true; } if (!isInListView) { int id = view.getId(); start = startValues.viewValues.get(view) != null ? startValues.viewValues.get(view) : startValues.idValues.get(id); if (endValues.viewValues.get(view) != null) { end = endValues.viewValues.get(view); endCopy.remove(view); } else if (id != View.NO_ID) { end = endValues.idValues.get(id); View removeView = null; for (View viewToRemove : endCopy.keySet()) { if (viewToRemove.getId() == id) { removeView = viewToRemove; } } if (removeView != null) { endCopy.remove(removeView); } } endIdCopy.remove(id); if (isValidTarget(view, id)) { startValuesList.add(start); endValuesList.add(end); } } else { ListView parent = (ListView) view.getParent(); if (parent.getAdapter().hasStableIds()) { int position = parent.getPositionForView(view); long itemId = parent.getItemIdAtPosition(position); start = startValues.itemIdValues.get(itemId); endItemIdCopy.remove(itemId); // TODO: deal with targetIDs for itemIDs for ListView items startValuesList.add(start); endValuesList.add(end); } } } int startItemIdCopySize = startValues.itemIdValues.size(); for (int i = 0; i < startItemIdCopySize; ++i) { long id = startValues.itemIdValues.keyAt(i); if (isValidTarget(null, id)) { TransitionValues start = startValues.itemIdValues.get(id); TransitionValues end = endValues.itemIdValues.get(id); endItemIdCopy.remove(id); startValuesList.add(start); endValuesList.add(end); } } // Now walk through the remains of the end set for (View view : endCopy.keySet()) { int id = view.getId(); if (isValidTarget(view, id)) { TransitionValues start = startValues.viewValues.get(view) != null ? startValues.viewValues.get(view) : startValues.idValues.get(id); TransitionValues end = endCopy.get(view); endIdCopy.remove(id); startValuesList.add(start); endValuesList.add(end); } } int endIdCopySize = endIdCopy.size(); for (int i = 0; i < endIdCopySize; ++i) { int id = endIdCopy.keyAt(i); if (isValidTarget(null, id)) { TransitionValues start = startValues.idValues.get(id); TransitionValues end = endIdCopy.get(id); startValuesList.add(start); endValuesList.add(end); } } int endItemIdCopySize = endItemIdCopy.size(); for (int i = 0; i < endItemIdCopySize; ++i) { long id = endItemIdCopy.keyAt(i); // TODO: Deal with targetIDs and itemIDs TransitionValues start = startValues.itemIdValues.get(id); TransitionValues end = endItemIdCopy.get(id); startValuesList.add(start); endValuesList.add(end); } ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); for (int i = 0; i < startValuesList.size(); ++i) { TransitionValues start = startValuesList.get(i); TransitionValues end = endValuesList.get(i); // Only bother trying to animate with values that differ between start/end if (start != null || end != null) { if (start == null || !start.equals(end)) { if (DBG) { View view = (end != null) ? end.view : start.view; Log.d(LOG_TAG, " differing start/end values for view " + view); if (start == null || end == null) { Log.d(LOG_TAG, " " + ((start == null) ? "start null, end non-null" : "start non-null, end null")); } else { for (String key : start.values.keySet()) { Object startValue = start.values.get(key); Object endValue = end.values.get(key); if (startValue != endValue && !startValue.equals(endValue)) { Log.d(LOG_TAG, " " + key + ": start(" + startValue + "), end(" + endValue + ")"); } } } } // TODO: what to do about targetIds and itemIds? Animator animator = createAnimator(sceneRoot, start, end); if (animator != null) { // Save animation info for future cancellation purposes View view = null; TransitionValues infoValues = null; if (end != null) { view = end.view; String[] properties = getTransitionProperties(); if (view != null && properties != null && properties.length > 0) { infoValues = new TransitionValues(); infoValues.view = view; TransitionValues newValues = endValues.viewValues.get(view); if (newValues != null) { for (int j = 0; j < properties.length; ++j) { infoValues.values.put(properties[j], newValues.values.get(properties[j])); } } int numExistingAnims = runningAnimators.size(); for (int j = 0; j < numExistingAnims; ++j) { Animator anim = runningAnimators.keyAt(j); AnimationInfo info = runningAnimators.get(anim); if (info.values != null && info.view == view && ((info.name == null && getName() == null) || info.name.equals(getName()))) { if (info.values.equals(infoValues)) { // Favor the old animator animator = null; break; } } } } } else { view = (start != null) ? start.view : null; } if (animator != null) { AnimationInfo info = new AnimationInfo(view, getName(), infoValues); runningAnimators.put(animator, info); mAnimators.add(animator); } } } } } }