List of usage examples for android.view View getRight
@ViewDebug.CapturedViewProperty public final int getRight()
From source file:me.ububble.speakall.fragment.ConversationChatFragment.java
@Override public boolean onTouch(View v, MotionEvent event) { int action = event.getActionMasked(); switch (v.getId()) { case R.id.record_audio: switch (action) { case MotionEvent.ACTION_DOWN: textRecordingPress.setVisibility(View.INVISIBLE); rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); fechaAudioMillis = Calendar.getInstance().getTimeInMillis(); File directory = new File( Environment.getExternalStorageDirectory().getAbsolutePath() + "/SpeakOn/Audio/Sent"); directory.mkdirs();/*w w w. ja va 2 s . c om*/ ficheroAudio = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SpeakOn/Audio/Sent/" + fechaAudioMillis + ".mp4"; mediaRecorder = new MediaRecorder(); mediaRecorder.setOutputFile(ficheroAudio); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); try { mediaRecorder.prepare(); } catch (IOException e) { } mediaRecorder.start(); handler.post(new Runnable() { @Override public void run() { finalTime += 1000; int seconds = (int) (finalTime / 1000) % 60; int minutes = (int) ((finalTime / (1000 * 60)) % 60); int hours = (int) ((finalTime / (1000 * 60 * 60)) % 24); timeFinal = String.format("%02d", minutes) + ":" + String.format("%02d", seconds); timerAudio.setText(timeFinal); if (!saveAudio) { textRecording.setText(timeFinal); } handler.postDelayed(this, 1000); } }); scaleAnimX = ObjectAnimator.ofFloat(recordAudioButton, "scaleX", 1, 1.2f); scaleAnimX.setDuration(800); scaleAnimX.setRepeatCount(ValueAnimator.INFINITE); scaleAnimX.setRepeatMode(ValueAnimator.REVERSE); scaleAnimY = ObjectAnimator.ofFloat(recordAudioButton, "scaleY", 1, 1.2f); scaleAnimY.setDuration(800); scaleAnimY.setRepeatCount(ValueAnimator.INFINITE); scaleAnimY.setRepeatMode(ValueAnimator.REVERSE); scaleAnimY.start(); scaleAnimX.start(); scaleRedBackgroundX = ObjectAnimator.ofFloat(audioRecordBackground, "scaleX", 1, 100f); scaleRedBackgroundX.setDuration(200); scaleRedBackgroundY = ObjectAnimator.ofFloat(audioRecordBackground, "scaleY", 1, 100f); scaleRedBackgroundY.setDuration(200); saveAudio = true; break; case MotionEvent.ACTION_MOVE: if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) { recordAudioButton.setBackgroundResource(R.drawable.rounded_record_audio_white); timerAudio.setVisibility(View.GONE); textRecording.setTextColor(getResources().getColor(R.color.speak_all_red)); if (!animatorBackground) { textRecording.setText(timeFinal); if (scaleRedBackgroundX.isRunning()) scaleRedBackgroundX.end(); if (scaleRedBackgroundY.isRunning()) scaleRedBackgroundY.end(); scaleRedBackgroundY.start(); scaleRedBackgroundX.start(); animatorBackground = true; } saveAudio = false; } else { recordAudioButton.setBackgroundResource(R.drawable.rounded_record_audio_red); textRecording.setTextColor(getResources().getColor(R.color.speak_all_white)); textRecording.setText(getString(R.string.audio_record)); timerAudio.setVisibility(View.VISIBLE); if (animatorBackground) { if (scaleRedBackgroundX.isRunning()) scaleRedBackgroundX.end(); if (scaleRedBackgroundY.isRunning()) scaleRedBackgroundY.end(); ViewHelper.setScaleX(audioRecordBackground, 1); ViewHelper.setScaleY(audioRecordBackground, 1); animatorBackground = false; } saveAudio = true; } break; case MotionEvent.ACTION_UP: textRecordingPress.setVisibility(View.VISIBLE); animatorBackground = false; if (scaleAnimY.isRunning()) scaleAnimY.end(); if (scaleAnimX.isRunning()) scaleAnimX.end(); if (scaleRedBackgroundX.isRunning()) scaleRedBackgroundX.end(); if (scaleRedBackgroundY.isRunning()) scaleRedBackgroundY.end(); ViewHelper.setScaleX(audioRecordBackground, 1); ViewHelper.setScaleY(audioRecordBackground, 1); ViewHelper.setScaleX(recordAudioButton, 1); ViewHelper.setScaleY(recordAudioButton, 1); handler.removeCallbacksAndMessages(null); timerAudio.setText("00:00"); timerAudio.setVisibility(View.VISIBLE); textRecording.setTextColor(getResources().getColor(R.color.speak_all_white)); textRecording.setText(getString(R.string.audio_record)); recordAudioButton.setBackgroundResource(R.drawable.rounded_record_audio_red); if (finalTime > 1000) { mediaRecorder.stop(); mediaRecorder.release(); } else { saveAudio = false; mediaRecorder.release(); } finalTime = 0; timeFinal = ""; if (saveAudio) { try { hideKeyBoard(); final Message msjAudio = new Message(); String id = u.id + contact.idContacto + fechaAudioMillis + Settings.Secure .getString(activity.getContentResolver(), Settings.Secure.ANDROID_ID); msjAudio.mensajeId = id; msjAudio.emisor = u.id; msjAudio.receptor = contact.idContacto; msjAudio.emisorEmail = u.email; msjAudio.receptorEmail = contact.email; msjAudio.emisorLang = u.lang; msjAudio.receptorLang = contact.lang; msjAudio.emitedAt = fechaAudioMillis; msjAudio.tipo = Integer.parseInt(getString(R.string.MSG_TYPE_AUDIO)); if (SpeakSocket.mSocket != null) if (SpeakSocket.mSocket.connected()) { msjAudio.status = 1; } else { msjAudio.status = -1; } msjAudio.fileUploaded = false; msjAudio.audioName = ficheroAudio; msjAudio.save(); Chats chat = new Select().from(Chats.class).where("idContacto = ?", msjAudio.receptor) .executeSingle(); if (chat == null) { Contact contact = new Select().from(Contact.class) .where("id_contact = ?", msjAudio.receptor).executeSingle(); Chats newChat = new Chats(); newChat.mensajeId = msjAudio.mensajeId; newChat.idContacto = msjAudio.receptor; newChat.isLockedConversation = false; newChat.lastStatus = msjAudio.status; newChat.email = msjAudio.receptorEmail; if (contact != null) { newChat.photo = contact.photo; newChat.fullName = contact.fullName; newChat.lang = contact.lang; newChat.screenName = contact.screenName; newChat.photoload = true; newChat.phone = contact.phone; } else { newChat.photo = null; newChat.photoload = false; newChat.fullName = msjAudio.receptorEmail; newChat.lang = msjAudio.receptorLang; newChat.screenName = msjAudio.receptorEmail; newChat.phone = null; } newChat.emitedAt = msjAudio.emitedAt; newChat.notRead = 0; newChat.lastMessage = "send Audio"; newChat.show = true; newChat.save(); } else { if (!chat.photoload) { Contact contact = new Select().from(Contact.class) .where("id_contact = ?", msjAudio.emisor).executeSingle(); if (contact != null) { chat.photo = contact.photo; chat.photoload = true; } else { chat.photo = null; chat.photoload = false; } } chat.mensajeId = msjAudio.mensajeId; chat.lastStatus = msjAudio.status; chat.emitedAt = msjAudio.emitedAt; chat.notRead = 0; chat.lastMessage = "send Audio"; chat.save(); } showNewMessage(msjAudio); } catch (Exception e) { // TODO: handle exception } } else { new File(ficheroAudio).delete(); } break; } break; } return true; }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
/** * Do an arrow scroll based on focus searching. If a new view is * given focus, return the selection delta and amount to scroll via * an {@link ArrowScrollFocusResult}, otherwise, return null. * * @param direction either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} or * {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT} depending on the * current view orientation.//from w w w.ja v a 2s . c om * * @return The result if focus has changed, or <code>null</code>. */ private ArrowScrollFocusResult arrowScrollFocused(final int direction) { forceValidFocusDirection(direction); final View selectedView = getSelectedView(); final View newFocus; final int searchPoint; if (selectedView != null && selectedView.hasFocus()) { View oldFocus = selectedView.findFocus(); newFocus = FocusFinder.getInstance().findNextFocus(this, oldFocus, direction); } else { if (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT) { final int start = (mIsVertical ? getPaddingTop() : getPaddingLeft()); final int selectedStart; if (selectedView != null) { selectedStart = (mIsVertical ? selectedView.getTop() : selectedView.getLeft()); } else { selectedStart = start; } searchPoint = Math.max(selectedStart, start); } else { final int end = (mIsVertical ? getHeight() - getPaddingBottom() : getWidth() - getPaddingRight()); final int selectedEnd; if (selectedView != null) { selectedEnd = (mIsVertical ? selectedView.getBottom() : selectedView.getRight()); } else { selectedEnd = end; } searchPoint = Math.min(selectedEnd, end); } final int x = (mIsVertical ? 0 : searchPoint); final int y = (mIsVertical ? searchPoint : 0); mTempRect.set(x, y, x, y); newFocus = FocusFinder.getInstance().findNextFocusFromRect(this, mTempRect, direction); } if (newFocus != null) { final int positionOfNewFocus = positionOfNewFocus(newFocus); // If the focus change is in a different new position, make sure // we aren't jumping over another selectable position. if (mSelectedPosition != INVALID_POSITION && positionOfNewFocus != mSelectedPosition) { final int selectablePosition = lookForSelectablePositionOnScreen(direction); final boolean movingForward = (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT); final boolean movingBackward = (direction == View.FOCUS_UP || direction == View.FOCUS_LEFT); if (selectablePosition != INVALID_POSITION && ((movingForward && selectablePosition < positionOfNewFocus) || (movingBackward && selectablePosition > positionOfNewFocus))) { return null; } } int focusScroll = amountToScrollToNewFocus(direction, newFocus, positionOfNewFocus); final int maxScrollAmount = getMaxScrollAmount(); if (focusScroll < maxScrollAmount) { // Not moving too far, safe to give next view focus newFocus.requestFocus(direction); mArrowScrollFocusResult.populate(positionOfNewFocus, focusScroll); return mArrowScrollFocusResult; } else if (distanceToView(newFocus) < maxScrollAmount) { // Case to consider: // Too far to get entire next focusable on screen, but by going // max scroll amount, we are getting it at least partially in view, // so give it focus and scroll the max amount. newFocus.requestFocus(direction); mArrowScrollFocusResult.populate(positionOfNewFocus, maxScrollAmount); return mArrowScrollFocusResult; } } return null; }
From source file:com.artifex.mupdf.view.ThumbnailViews.java
/** * Do an arrow scroll based on focus searching. If a new view is given * focus, return the selection delta and amount to scroll via an * {@link ArrowScrollFocusResult}, otherwise, return null. * // w w w. ja v a2 s . c o m * @param direction * either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} or * {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT} depending * on the current view orientation. * * @return The result if focus has changed, or <code>null</code>. */ private ArrowScrollFocusResult arrowScrollFocused(final int direction) { forceValidFocusDirection(direction); final View selectedView = getSelectedView(); final View newFocus; final int searchPoint; if (selectedView != null && selectedView.hasFocus()) { View oldFocus = selectedView.findFocus(); newFocus = FocusFinder.getInstance().findNextFocus(this, oldFocus, direction); } else { if (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT) { final int start = (mIsVertical ? getPaddingTop() : getPaddingLeft()); final int selectedStart; if (selectedView != null) { selectedStart = (mIsVertical ? selectedView.getTop() : selectedView.getLeft()); } else { selectedStart = start; } searchPoint = Math.max(selectedStart, start); } else { final int end = (mIsVertical ? getHeight() - getPaddingBottom() : getWidth() - getPaddingRight()); final int selectedEnd; if (selectedView != null) { selectedEnd = (mIsVertical ? selectedView.getBottom() : selectedView.getRight()); } else { selectedEnd = end; } searchPoint = Math.min(selectedEnd, end); } final int x = (mIsVertical ? 0 : searchPoint); final int y = (mIsVertical ? searchPoint : 0); mTempRect.set(x, y, x, y); newFocus = FocusFinder.getInstance().findNextFocusFromRect(this, mTempRect, direction); } if (newFocus != null) { final int positionOfNewFocus = positionOfNewFocus(newFocus); // If the focus change is in a different new position, make sure // we aren't jumping over another selectable position. if (mSelectedPosition != INVALID_POSITION && positionOfNewFocus != mSelectedPosition) { final int selectablePosition = lookForSelectablePositionOnScreen(direction); final boolean movingForward = (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT); final boolean movingBackward = (direction == View.FOCUS_UP || direction == View.FOCUS_LEFT); if (selectablePosition != INVALID_POSITION && ((movingForward && selectablePosition < positionOfNewFocus) || (movingBackward && selectablePosition > positionOfNewFocus))) { return null; } } int focusScroll = amountToScrollToNewFocus(direction, newFocus, positionOfNewFocus); final int maxScrollAmount = getMaxScrollAmount(); if (focusScroll < maxScrollAmount) { // Not moving too far, safe to give next view focus newFocus.requestFocus(direction); mArrowScrollFocusResult.populate(positionOfNewFocus, focusScroll); return mArrowScrollFocusResult; } else if (distanceToView(newFocus) < maxScrollAmount) { // Case to consider: // Too far to get entire next focusable on screen, but by going // max scroll amount, we are getting it at least partially in // view, // so give it focus and scroll the max amount. newFocus.requestFocus(direction); mArrowScrollFocusResult.populate(positionOfNewFocus, maxScrollAmount); return mArrowScrollFocusResult; } } return null; }
From source file:android.support.v7.widget.RecyclerViewEx.java
/** * Find the topmost view under the given point. * * @param x Horizontal position in pixels to search * @param y Vertical position in pixels to search * @return The child view under (x, y) or null if no matching child is found *//*from w w w.j a va 2s. com*/ public View findChildViewUnder(float x, float y) { final int count = mChildHelper.getChildCount(); for (int i = count - 1; i >= 0; i--) { final View child = mChildHelper.getChildAt(i); final float translationX = ViewCompat.getTranslationX(child); final float translationY = ViewCompat.getTranslationY(child); if (x >= child.getLeft() + translationX && x <= child.getRight() + translationX && y >= child.getTop() + translationY && y <= child.getBottom() + translationY) { return child; } } return null; }
From source file:android.support.v7.widget.RecyclerViewEx.java
/** * Wrapper around layoutChildren() that handles animating changes caused by layout. * Animations work on the assumption that there are five different kinds of items * in play:/*from w w w . j ava 2 s . c o m*/ * PERSISTENT: items are visible before and after layout * REMOVED: items were visible before layout and were removed by the app * ADDED: items did not exist before layout and were added by the app * DISAPPEARING: items exist in the data set before/after, but changed from * visible to non-visible in the process of layout (they were moved off * screen as a side-effect of other changes) * APPEARING: items exist in the data set before/after, but changed from * non-visible to visible in the process of layout (they were moved on * screen as a side-effect of other changes) * The overall approach figures out what items exist before/after layout and * infers one of the five above states for each of the items. Then the animations * are set up accordingly: * PERSISTENT views are moved ({@link android.support.v7.widget.RecyclerViewEx.ItemAnimator#animateMove(android.support.v7.widget.RecyclerViewEx.ViewHolder, int, int, int, int)}) * REMOVED views are removed ({@link android.support.v7.widget.RecyclerViewEx.ItemAnimator#animateRemove(android.support.v7.widget.RecyclerViewEx.ViewHolder)}) * ADDED views are added ({@link android.support.v7.widget.RecyclerViewEx.ItemAnimator#animateAdd(android.support.v7.widget.RecyclerViewEx.ViewHolder)}) * DISAPPEARING views are moved off screen * APPEARING views are moved on screen */ void dispatchLayout() { if (mAdapter == null) { Log.e(TAG, "No adapter attached; skipping layout"); return; } mDisappearingViewsInLayoutPass.clear(); eatRequestLayout(); mRunningLayoutOrScroll = true; processAdapterUpdatesAndSetAnimationFlags(); mState.mOldChangedHolders = mState.mRunSimpleAnimations && mItemsChanged && supportsChangeAnimations() ? new ArrayMap<Long, ViewHolder>() : null; mItemsAddedOrRemoved = mItemsChanged = false; ArrayMap<View, Rect> appearingViewInitialBounds = null; mState.mInPreLayout = mState.mRunPredictiveAnimations; mState.mItemCount = mAdapter.getItemCount(); if (mState.mRunSimpleAnimations) { // Step 0: Find out where all non-removed items are, pre-layout mState.mPreLayoutHolderMap.clear(); mState.mPostLayoutHolderMap.clear(); int count = mChildHelper.getChildCount(); for (int i = 0; i < count; ++i) { final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i)); if (holder.shouldIgnore() || (holder.isInvalid() && !mAdapter.hasStableIds())) { continue; } final View view = holder.itemView; mState.mPreLayoutHolderMap.put(holder, new ItemHolderInfo(holder, view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); } } if (mState.mRunPredictiveAnimations) { // Step 1: run prelayout: This will use the old positions of items. The layout manager // is expected to layout everything, even removed items (though not to add removed // items back to the container). This gives the pre-layout position of APPEARING views // which come into existence as part of the real layout. // Save old positions so that LayoutManager can run its mapping logic. saveOldPositions(); // processAdapterUpdatesAndSetAnimationFlags already run pre-layout animations. if (mState.mOldChangedHolders != null) { int count = mChildHelper.getChildCount(); for (int i = 0; i < count; ++i) { final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i)); if (holder.isChanged() && !holder.isRemoved() && !holder.shouldIgnore()) { long key = getChangedHolderKey(holder); mState.mOldChangedHolders.put(key, holder); mState.mPreLayoutHolderMap.remove(holder); } } } final boolean didStructureChange = mState.mStructureChanged; mState.mStructureChanged = false; // temporarily disable flag because we are asking for previous layout mLayout.onLayoutChildren(mRecycler, mState); mState.mStructureChanged = didStructureChange; appearingViewInitialBounds = new ArrayMap<View, Rect>(); for (int i = 0; i < mChildHelper.getChildCount(); ++i) { boolean found = false; View child = mChildHelper.getChildAt(i); if (getChildViewHolderInt(child).shouldIgnore()) { continue; } for (int j = 0; j < mState.mPreLayoutHolderMap.size(); ++j) { ViewHolder holder = mState.mPreLayoutHolderMap.keyAt(j); if (holder.itemView == child) { found = true; break; } } if (!found) { appearingViewInitialBounds.put(child, new Rect(child.getLeft(), child.getTop(), child.getRight(), child.getBottom())); } } // we don't process disappearing list because they may re-appear in post layout pass. clearOldPositions(); mAdapterHelper.consumePostponedUpdates(); } else { clearOldPositions(); // in case pre layout did run but we decided not to run predictive animations. mAdapterHelper.consumeUpdatesInOnePass(); if (mState.mOldChangedHolders != null) { int count = mChildHelper.getChildCount(); for (int i = 0; i < count; ++i) { final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i)); if (holder.isChanged() && !holder.isRemoved() && !holder.shouldIgnore()) { long key = getChangedHolderKey(holder); mState.mOldChangedHolders.put(key, holder); mState.mPreLayoutHolderMap.remove(holder); } } } } mState.mItemCount = mAdapter.getItemCount(); mState.mDeletedInvisibleItemCountSincePreviousLayout = 0; // Step 2: Run layout mState.mInPreLayout = false; mLayout.onLayoutChildren(mRecycler, mState); mState.mStructureChanged = false; mPendingSavedState = null; // onLayoutChildren may have caused client code to disable item animations; re-check mState.mRunSimpleAnimations = mState.mRunSimpleAnimations && mItemAnimator != null; if (mState.mRunSimpleAnimations) { // Step 3: Find out where things are now, post-layout ArrayMap<Long, ViewHolder> newChangedHolders = mState.mOldChangedHolders != null ? new ArrayMap<Long, ViewHolder>() : null; int count = mChildHelper.getChildCount(); for (int i = 0; i < count; ++i) { ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i)); if (holder.shouldIgnore()) { continue; } final View view = holder.itemView; long key = getChangedHolderKey(holder); if (newChangedHolders != null && mState.mOldChangedHolders.get(key) != null) { newChangedHolders.put(key, holder); } else { mState.mPostLayoutHolderMap.put(holder, new ItemHolderInfo(holder, view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); } } processDisappearingList(appearingViewInitialBounds); // Step 4: Animate DISAPPEARING and REMOVED items int preLayoutCount = mState.mPreLayoutHolderMap.size(); for (int i = preLayoutCount - 1; i >= 0; i--) { ViewHolder itemHolder = mState.mPreLayoutHolderMap.keyAt(i); if (!mState.mPostLayoutHolderMap.containsKey(itemHolder)) { ItemHolderInfo disappearingItem = mState.mPreLayoutHolderMap.valueAt(i); mState.mPreLayoutHolderMap.removeAt(i); View disappearingItemView = disappearingItem.holder.itemView; mRecycler.unscrapView(disappearingItem.holder); animateDisappearance(disappearingItem); } } // Step 5: Animate APPEARING and ADDED items int postLayoutCount = mState.mPostLayoutHolderMap.size(); if (postLayoutCount > 0) { for (int i = postLayoutCount - 1; i >= 0; i--) { ViewHolder itemHolder = mState.mPostLayoutHolderMap.keyAt(i); ItemHolderInfo info = mState.mPostLayoutHolderMap.valueAt(i); if ((mState.mPreLayoutHolderMap.isEmpty() || !mState.mPreLayoutHolderMap.containsKey(itemHolder))) { mState.mPostLayoutHolderMap.removeAt(i); Rect initialBounds = (appearingViewInitialBounds != null) ? appearingViewInitialBounds.get(itemHolder.itemView) : null; animateAppearance(itemHolder, initialBounds, info.left, info.top); } } } // Step 6: Animate PERSISTENT items count = mState.mPostLayoutHolderMap.size(); for (int i = 0; i < count; ++i) { ViewHolder postHolder = mState.mPostLayoutHolderMap.keyAt(i); ItemHolderInfo postInfo = mState.mPostLayoutHolderMap.valueAt(i); ItemHolderInfo preInfo = mState.mPreLayoutHolderMap.get(postHolder); if (preInfo != null && postInfo != null) { if (preInfo.left != postInfo.left || preInfo.top != postInfo.top) { postHolder.setIsRecyclable(false); if (DEBUG) { Log.d(TAG, "PERSISTENT: " + postHolder + " with view " + postHolder.itemView); } if (mItemAnimator.animateMove(postHolder, preInfo.left, preInfo.top, postInfo.left, postInfo.top)) { postAnimationRunner(); } } } } // Step 7: Animate CHANGING items count = mState.mOldChangedHolders != null ? mState.mOldChangedHolders.size() : 0; // traverse reverse in case view gets recycled while we are traversing the list. for (int i = count - 1; i >= 0; i--) { long key = mState.mOldChangedHolders.keyAt(i); ViewHolder oldHolder = mState.mOldChangedHolders.get(key); View oldView = oldHolder.itemView; if (oldHolder.shouldIgnore()) { continue; } // We probably don't need this check anymore since these views are removed from // the list if they are recycled. if (mRecycler.mChangedScrap != null && mRecycler.mChangedScrap.contains(oldHolder)) { animateChange(oldHolder, newChangedHolders.get(key)); } else if (DEBUG) { Log.e(TAG, "cannot find old changed holder in changed scrap :/" + oldHolder); } } } resumeRequestLayout(false); mLayout.removeAndRecycleScrapInt(mRecycler); mState.mPreviousLayoutItemCount = mState.mItemCount; mDataSetHasChangedAfterLayout = false; mState.mRunSimpleAnimations = false; mState.mRunPredictiveAnimations = false; mRunningLayoutOrScroll = false; mLayout.mRequestedSimpleAnimations = false; if (mRecycler.mChangedScrap != null) { mRecycler.mChangedScrap.clear(); } mState.mOldChangedHolders = null; }
From source file:android.support.v7.widget.RecyclerViewEx.java
/** * A LayoutManager may want to layout a view just to animate disappearance. * This method handles those views and triggers remove animation on them. *///w w w . j a va2 s . c o m private void processDisappearingList(ArrayMap<View, Rect> appearingViews) { final int count = mDisappearingViewsInLayoutPass.size(); for (int i = 0; i < count; i++) { View view = mDisappearingViewsInLayoutPass.get(i); ViewHolder vh = getChildViewHolderInt(view); final ItemHolderInfo info = mState.mPreLayoutHolderMap.remove(vh); if (!mState.isPreLayout()) { mState.mPostLayoutHolderMap.remove(vh); } if (appearingViews.remove(view) != null) { mLayout.removeAndRecycleView(view, mRecycler); continue; } if (info != null) { animateDisappearance(info); } else { // let it disappear from the position it becomes visible animateDisappearance( new ItemHolderInfo(vh, view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); } } mDisappearingViewsInLayoutPass.clear(); }
From source file:com.goftagram.telegram.messenger.support.widget.RecyclerView.java
/** * Wrapper around layoutChildren() that handles animating changes caused by layout. * Animations work on the assumption that there are five different kinds of items * in play:// w ww . j av a 2 s . c om * PERSISTENT: items are visible before and after layout * REMOVED: items were visible before layout and were removed by the app * ADDED: items did not exist before layout and were added by the app * DISAPPEARING: items exist in the data set before/after, but changed from * visible to non-visible in the process of layout (they were moved off * screen as a side-effect of other changes) * APPEARING: items exist in the data set before/after, but changed from * non-visible to visible in the process of layout (they were moved on * screen as a side-effect of other changes) * The overall approach figures out what items exist before/after layout and * infers one of the five above states for each of the items. Then the animations * are set up accordingly: * PERSISTENT views are moved ({@link ItemAnimator#animateMove(ViewHolder, int, int, int, int)}) * REMOVED views are removed ({@link ItemAnimator#animateRemove(ViewHolder)}) * ADDED views are added ({@link ItemAnimator#animateAdd(ViewHolder)}) * DISAPPEARING views are moved off screen * APPEARING views are moved on screen */ void dispatchLayout() { if (mAdapter == null) { Log.e(TAG, "No adapter attached; skipping layout"); return; } if (mLayout == null) { Log.e(TAG, "No layout manager attached; skipping layout"); return; } mState.mDisappearingViewsInLayoutPass.clear(); eatRequestLayout(); onEnterLayoutOrScroll(); processAdapterUpdatesAndSetAnimationFlags(); mState.mOldChangedHolders = mState.mRunSimpleAnimations && mItemsChanged && supportsChangeAnimations() ? new ArrayMap<Long, ViewHolder>() : null; mItemsAddedOrRemoved = mItemsChanged = false; ArrayMap<View, Rect> appearingViewInitialBounds = null; mState.mInPreLayout = mState.mRunPredictiveAnimations; mState.mItemCount = mAdapter.getItemCount(); findMinMaxChildLayoutPositions(mMinMaxLayoutPositions); if (mState.mRunSimpleAnimations) { // Step 0: Find out where all non-removed items are, pre-layout mState.mPreLayoutHolderMap.clear(); mState.mPostLayoutHolderMap.clear(); int count = mChildHelper.getChildCount(); for (int i = 0; i < count; ++i) { final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i)); if (holder.shouldIgnore() || (holder.isInvalid() && !mAdapter.hasStableIds())) { continue; } final View view = holder.itemView; mState.mPreLayoutHolderMap.put(holder, new ItemHolderInfo(holder, view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); } } if (mState.mRunPredictiveAnimations) { // Step 1: run prelayout: This will use the old positions of items. The layout manager // is expected to layout everything, even removed items (though not to add removed // items back to the container). This gives the pre-layout position of APPEARING views // which come into existence as part of the real layout. // Save old positions so that LayoutManager can run its mapping logic. saveOldPositions(); // processAdapterUpdatesAndSetAnimationFlags already run pre-layout animations. if (mState.mOldChangedHolders != null) { int count = mChildHelper.getChildCount(); for (int i = 0; i < count; ++i) { final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i)); if (holder.isChanged() && !holder.isRemoved() && !holder.shouldIgnore()) { long key = getChangedHolderKey(holder); mState.mOldChangedHolders.put(key, holder); mState.mPreLayoutHolderMap.remove(holder); } } } final boolean didStructureChange = mState.mStructureChanged; mState.mStructureChanged = false; // temporarily disable flag because we are asking for previous layout mLayout.onLayoutChildren(mRecycler, mState); mState.mStructureChanged = didStructureChange; appearingViewInitialBounds = new ArrayMap<View, Rect>(); for (int i = 0; i < mChildHelper.getChildCount(); ++i) { boolean found = false; View child = mChildHelper.getChildAt(i); if (getChildViewHolderInt(child).shouldIgnore()) { continue; } for (int j = 0; j < mState.mPreLayoutHolderMap.size(); ++j) { ViewHolder holder = mState.mPreLayoutHolderMap.keyAt(j); if (holder.itemView == child) { found = true; break; } } if (!found) { appearingViewInitialBounds.put(child, new Rect(child.getLeft(), child.getTop(), child.getRight(), child.getBottom())); } } // we don't process disappearing list because they may re-appear in post layout pass. clearOldPositions(); mAdapterHelper.consumePostponedUpdates(); } else { clearOldPositions(); // in case pre layout did run but we decided not to run predictive animations. mAdapterHelper.consumeUpdatesInOnePass(); if (mState.mOldChangedHolders != null) { int count = mChildHelper.getChildCount(); for (int i = 0; i < count; ++i) { final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i)); if (holder.isChanged() && !holder.isRemoved() && !holder.shouldIgnore()) { long key = getChangedHolderKey(holder); mState.mOldChangedHolders.put(key, holder); mState.mPreLayoutHolderMap.remove(holder); } } } } mState.mItemCount = mAdapter.getItemCount(); mState.mDeletedInvisibleItemCountSincePreviousLayout = 0; // Step 2: Run layout mState.mInPreLayout = false; mLayout.onLayoutChildren(mRecycler, mState); mState.mStructureChanged = false; mPendingSavedState = null; // onLayoutChildren may have caused client code to disable item animations; re-check mState.mRunSimpleAnimations = mState.mRunSimpleAnimations && mItemAnimator != null; if (mState.mRunSimpleAnimations) { // Step 3: Find out where things are now, post-layout ArrayMap<Long, ViewHolder> newChangedHolders = mState.mOldChangedHolders != null ? new ArrayMap<Long, ViewHolder>() : null; int count = mChildHelper.getChildCount(); for (int i = 0; i < count; ++i) { ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i)); if (holder.shouldIgnore()) { continue; } final View view = holder.itemView; long key = getChangedHolderKey(holder); if (newChangedHolders != null && mState.mOldChangedHolders.get(key) != null) { newChangedHolders.put(key, holder); } else { mState.mPostLayoutHolderMap.put(holder, new ItemHolderInfo(holder, view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); } } processDisappearingList(appearingViewInitialBounds); // Step 4: Animate DISAPPEARING and REMOVED items int preLayoutCount = mState.mPreLayoutHolderMap.size(); for (int i = preLayoutCount - 1; i >= 0; i--) { ViewHolder itemHolder = mState.mPreLayoutHolderMap.keyAt(i); if (!mState.mPostLayoutHolderMap.containsKey(itemHolder)) { ItemHolderInfo disappearingItem = mState.mPreLayoutHolderMap.valueAt(i); mState.mPreLayoutHolderMap.removeAt(i); View disappearingItemView = disappearingItem.holder.itemView; mRecycler.unscrapView(disappearingItem.holder); animateDisappearance(disappearingItem); } } // Step 5: Animate APPEARING and ADDED items int postLayoutCount = mState.mPostLayoutHolderMap.size(); if (postLayoutCount > 0) { for (int i = postLayoutCount - 1; i >= 0; i--) { ViewHolder itemHolder = mState.mPostLayoutHolderMap.keyAt(i); ItemHolderInfo info = mState.mPostLayoutHolderMap.valueAt(i); if ((mState.mPreLayoutHolderMap.isEmpty() || !mState.mPreLayoutHolderMap.containsKey(itemHolder))) { mState.mPostLayoutHolderMap.removeAt(i); Rect initialBounds = (appearingViewInitialBounds != null) ? appearingViewInitialBounds.get(itemHolder.itemView) : null; animateAppearance(itemHolder, initialBounds, info.left, info.top); } } } // Step 6: Animate PERSISTENT items count = mState.mPostLayoutHolderMap.size(); for (int i = 0; i < count; ++i) { ViewHolder postHolder = mState.mPostLayoutHolderMap.keyAt(i); ItemHolderInfo postInfo = mState.mPostLayoutHolderMap.valueAt(i); ItemHolderInfo preInfo = mState.mPreLayoutHolderMap.get(postHolder); if (preInfo != null && postInfo != null) { if (preInfo.left != postInfo.left || preInfo.top != postInfo.top) { postHolder.setIsRecyclable(false); if (DEBUG) { Log.d(TAG, "PERSISTENT: " + postHolder + " with view " + postHolder.itemView); } if (mItemAnimator.animateMove(postHolder, preInfo.left, preInfo.top, postInfo.left, postInfo.top)) { postAnimationRunner(); } } } } // Step 7: Animate CHANGING items count = mState.mOldChangedHolders != null ? mState.mOldChangedHolders.size() : 0; // traverse reverse in case view gets recycled while we are traversing the list. for (int i = count - 1; i >= 0; i--) { long key = mState.mOldChangedHolders.keyAt(i); ViewHolder oldHolder = mState.mOldChangedHolders.get(key); View oldView = oldHolder.itemView; if (oldHolder.shouldIgnore()) { continue; } // We probably don't need this check anymore since these views are removed from // the list if they are recycled. if (mRecycler.mChangedScrap != null && mRecycler.mChangedScrap.contains(oldHolder)) { animateChange(oldHolder, newChangedHolders.get(key)); } else if (DEBUG) { Log.e(TAG, "cannot find old changed holder in changed scrap :/" + oldHolder); } } } resumeRequestLayout(false); mLayout.removeAndRecycleScrapInt(mRecycler); mState.mPreviousLayoutItemCount = mState.mItemCount; mDataSetHasChangedAfterLayout = false; mState.mRunSimpleAnimations = false; mState.mRunPredictiveAnimations = false; onExitLayoutOrScroll(); mLayout.mRequestedSimpleAnimations = false; if (mRecycler.mChangedScrap != null) { mRecycler.mChangedScrap.clear(); } mState.mOldChangedHolders = null; if (didChildRangeChange(mMinMaxLayoutPositions[0], mMinMaxLayoutPositions[1])) { dispatchOnScrolled(0, 0); } }
From source file:com.goftagram.telegram.messenger.support.widget.RecyclerView.java
/** * A LayoutManager may want to layout a view just to animate disappearance. * This method handles those views and triggers remove animation on them. *//*w w w . j a va 2 s .co m*/ private void processDisappearingList(ArrayMap<View, Rect> appearingViews) { final List<View> disappearingList = mState.mDisappearingViewsInLayoutPass; for (int i = disappearingList.size() - 1; i >= 0; i--) { View view = disappearingList.get(i); ViewHolder vh = getChildViewHolderInt(view); final ItemHolderInfo info = mState.mPreLayoutHolderMap.remove(vh); if (!mState.isPreLayout()) { mState.mPostLayoutHolderMap.remove(vh); } if (appearingViews.remove(view) != null) { mLayout.removeAndRecycleView(view, mRecycler); continue; } if (info != null) { animateDisappearance(info); } else { // let it disappear from the position it becomes visible animateDisappearance( new ItemHolderInfo(vh, view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); } } disappearingList.clear(); }
From source file:com.ferdi2005.secondgram.support.widget.RecyclerView.java
static void getDecoratedBoundsWithMarginsInt(View view, Rect outBounds) { final LayoutParams lp = (LayoutParams) view.getLayoutParams(); final Rect insets = lp.mDecorInsets; outBounds.set(view.getLeft() - insets.left - lp.leftMargin, view.getTop() - insets.top - lp.topMargin, view.getRight() + insets.right + lp.rightMargin, view.getBottom() + insets.bottom + lp.bottomMargin); }