Source code
package android.support.v7.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.Observable;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;
import android.os.SystemClock;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.os.TraceCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.ScrollingView;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat;
import android.support.v4.view.accessibility.AccessibilityRecordCompat;
import android.support.v4.widget.EdgeEffectCompat;
import android.support.v4.widget.ScrollerCompat;
import android.support.v7.recyclerview.R;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.FocusFinder;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.BaseSavedState;
import android.view.View.MeasureSpec;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild {
private static final boolean DEBUG = false;
private static final boolean DISPATCH_TEMP_DETACH = false;
private static final boolean FORCE_INVALIDATE_DISPLAY_LIST;
public static final int HORIZONTAL = 0;
private static final int INVALID_POINTER = -1;
public static final int INVALID_TYPE = -1;
private static final Class<?>[] LAYOUT_MANAGER_CONSTRUCTOR_SIGNATURE = new Class[]{Context.class, AttributeSet.class, Integer.TYPE, Integer.TYPE};
private static final int MAX_SCROLL_DURATION = 2000;
public static final long NO_ID = -1;
public static final int NO_POSITION = -1;
public static final int SCROLL_STATE_DRAGGING = 1;
public static final int SCROLL_STATE_IDLE = 0;
public static final int SCROLL_STATE_SETTLING = 2;
private static final String TAG = "RecyclerView";
public static final int TOUCH_SLOP_DEFAULT = 0;
public static final int TOUCH_SLOP_PAGING = 1;
private static final String TRACE_BIND_VIEW_TAG = "RV OnBindView";
private static final String TRACE_CREATE_VIEW_TAG = "RV CreateView";
private static final String TRACE_HANDLE_ADAPTER_UPDATES_TAG = "RV PartialInvalidate";
private static final String TRACE_ON_DATA_SET_CHANGE_LAYOUT_TAG = "RV FullInvalidate";
private static final String TRACE_ON_LAYOUT_TAG = "RV OnLayout";
private static final String TRACE_SCROLL_TAG = "RV Scroll";
public static final int VERTICAL = 1;
private static final Interpolator sQuinticInterpolator = new Interpolator() {
public float getInterpolation(float t) {
t -= 1.0f;
return ((((t * t) * t) * t) * t) + 1.0f;
}
};
private RecyclerViewAccessibilityDelegate mAccessibilityDelegate;
private final AccessibilityManager mAccessibilityManager;
private OnItemTouchListener mActiveOnItemTouchListener;
private Adapter mAdapter;
AdapterHelper mAdapterHelper;
private boolean mAdapterUpdateDuringMeasure;
private EdgeEffectCompat mBottomGlow;
private ChildDrawingOrderCallback mChildDrawingOrderCallback;
ChildHelper mChildHelper;
private boolean mClipToPadding;
private boolean mDataSetHasChangedAfterLayout;
private boolean mEatRequestLayout;
private int mEatenAccessibilityChangeFlags;
private boolean mFirstLayoutComplete;
private boolean mHasFixedSize;
private boolean mIgnoreMotionEventTillDown;
private int mInitialTouchX;
private int mInitialTouchY;
private boolean mIsAttached;
ItemAnimator mItemAnimator;
private ItemAnimatorListener mItemAnimatorListener;
private Runnable mItemAnimatorRunner;
private final ArrayList<ItemDecoration> mItemDecorations;
boolean mItemsAddedOrRemoved;
boolean mItemsChanged;
private int mLastTouchX;
private int mLastTouchY;
private LayoutManager mLayout;
private boolean mLayoutFrozen;
private int mLayoutOrScrollCounter;
private boolean mLayoutRequestEaten;
private EdgeEffectCompat mLeftGlow;
private final int mMaxFlingVelocity;
private final int mMinFlingVelocity;
private final int[] mMinMaxLayoutPositions;
private final int[] mNestedOffsets;
private final RecyclerViewDataObserver mObserver;
private List<OnChildAttachStateChangeListener> mOnChildAttachStateListeners;
private final ArrayList<OnItemTouchListener> mOnItemTouchListeners;
private SavedState mPendingSavedState;
private final boolean mPostUpdatesOnAnimation;
private boolean mPostedAnimatorRunner;
final Recycler mRecycler;
private RecyclerListener mRecyclerListener;
private EdgeEffectCompat mRightGlow;
private final int[] mScrollConsumed;
private float mScrollFactor;
private OnScrollListener mScrollListener;
private List<OnScrollListener> mScrollListeners;
private final int[] mScrollOffset;
private int mScrollPointerId;
private int mScrollState;
private final NestedScrollingChildHelper mScrollingChildHelper;
final State mState;
private final Rect mTempRect;
private EdgeEffectCompat mTopGlow;
private int mTouchSlop;
private final Runnable mUpdateChildViewsRunnable;
private VelocityTracker mVelocityTracker;
private final ViewFlinger mViewFlinger;
private final ProcessCallback mViewInfoProcessCallback;
final ViewInfoStore mViewInfoStore;
public static abstract class Adapter<VH extends ViewHolder> {
private boolean mHasStableIds = false;
private final AdapterDataObservable mObservable = new AdapterDataObservable();
public abstract int getItemCount();
public abstract void onBindViewHolder(VH vh, int i);
public abstract VH onCreateViewHolder(ViewGroup viewGroup, int i);
public void onBindViewHolder(VH holder, int position, List<Object> list) {
onBindViewHolder(holder, position);
}
public final VH createViewHolder(ViewGroup parent, int viewType) {
TraceCompat.beginSection(RecyclerView.TRACE_CREATE_VIEW_TAG);
VH holder = onCreateViewHolder(parent, viewType);
holder.mItemViewType = viewType;
TraceCompat.endSection();
return holder;
}
public final void bindViewHolder(VH holder, int position) {
holder.mPosition = position;
if (hasStableIds()) {
holder.mItemId = getItemId(position);
}
holder.setFlags(1, 519);
TraceCompat.beginSection(RecyclerView.TRACE_BIND_VIEW_TAG);
onBindViewHolder(holder, position, holder.getUnmodifiedPayloads());
holder.clearPayload();
TraceCompat.endSection();
}
public int getItemViewType(int position) {
return 0;
}
public void setHasStableIds(boolean hasStableIds) {
if (hasObservers()) {
throw new IllegalStateException("Cannot change whether this adapter has stable IDs while the adapter has registered observers.");
}
this.mHasStableIds = hasStableIds;
}
public long getItemId(int position) {
return -1;
}
public final boolean hasStableIds() {
return this.mHasStableIds;
}
public void onViewRecycled(VH vh) {
}
public boolean onFailedToRecycleView(VH vh) {
return false;
}
public void onViewAttachedToWindow(VH vh) {
}
public void onViewDetachedFromWindow(VH vh) {
}
public final boolean hasObservers() {
return this.mObservable.hasObservers();
}
public void registerAdapterDataObserver(AdapterDataObserver observer) {
this.mObservable.registerObserver(observer);
}
public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
this.mObservable.unregisterObserver(observer);
}
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
}
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
}
public final void notifyDataSetChanged() {
this.mObservable.notifyChanged();
}
public final void notifyItemChanged(int position) {
this.mObservable.notifyItemRangeChanged(position, 1);
}
public final void notifyItemChanged(int position, Object payload) {
this.mObservable.notifyItemRangeChanged(position, 1, payload);
}
public final void notifyItemRangeChanged(int positionStart, int itemCount) {
this.mObservable.notifyItemRangeChanged(positionStart, itemCount);
}
public final void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) {
this.mObservable.notifyItemRangeChanged(positionStart, itemCount, payload);
}
public final void notifyItemInserted(int position) {
this.mObservable.notifyItemRangeInserted(position, 1);
}
public final void notifyItemMoved(int fromPosition, int toPosition) {
this.mObservable.notifyItemMoved(fromPosition, toPosition);
}
public final void notifyItemRangeInserted(int positionStart, int itemCount) {
this.mObservable.notifyItemRangeInserted(positionStart, itemCount);
}
public final void notifyItemRemoved(int position) {
this.mObservable.notifyItemRangeRemoved(position, 1);
}
public final void notifyItemRangeRemoved(int positionStart, int itemCount) {
this.mObservable.notifyItemRangeRemoved(positionStart, itemCount);
}
}
static class AdapterDataObservable extends Observable<AdapterDataObserver> {
AdapterDataObservable() {
}
public boolean hasObservers() {
return !this.mObservers.isEmpty();
}
public void notifyChanged() {
for (int i = this.mObservers.size() - 1; i >= 0; i--) {
((AdapterDataObserver) this.mObservers.get(i)).onChanged();
}
}
public void notifyItemRangeChanged(int positionStart, int itemCount) {
notifyItemRangeChanged(positionStart, itemCount, null);
}
public void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) {
for (int i = this.mObservers.size() - 1; i >= 0; i--) {
((AdapterDataObserver) this.mObservers.get(i)).onItemRangeChanged(positionStart, itemCount, payload);
}
}
public void notifyItemRangeInserted(int positionStart, int itemCount) {
for (int i = this.mObservers.size() - 1; i >= 0; i--) {
((AdapterDataObserver) this.mObservers.get(i)).onItemRangeInserted(positionStart, itemCount);
}
}
public void notifyItemRangeRemoved(int positionStart, int itemCount) {
for (int i = this.mObservers.size() - 1; i >= 0; i--) {
((AdapterDataObserver) this.mObservers.get(i)).onItemRangeRemoved(positionStart, itemCount);
}
}
public void notifyItemMoved(int fromPosition, int toPosition) {
for (int i = this.mObservers.size() - 1; i >= 0; i--) {
((AdapterDataObserver) this.mObservers.get(i)).onItemRangeMoved(fromPosition, toPosition, 1);
}
}
}
public static abstract class AdapterDataObserver {
public void onChanged() {
}
public void onItemRangeChanged(int positionStart, int itemCount) {
}
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
onItemRangeChanged(positionStart, itemCount);
}
public void onItemRangeInserted(int positionStart, int itemCount) {
}
public void onItemRangeRemoved(int positionStart, int itemCount) {
}
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
}
}
public interface ChildDrawingOrderCallback {
int onGetChildDrawingOrder(int i, int i2);
}
public static abstract class ItemAnimator {
public static final int FLAG_APPEARED_IN_PRE_LAYOUT = 4096;
public static final int FLAG_CHANGED = 2;
public static final int FLAG_INVALIDATED = 4;
public static final int FLAG_MOVED = 2048;
public static final int FLAG_REMOVED = 8;
private long mAddDuration = 120;
private long mChangeDuration = 250;
private ArrayList<ItemAnimatorFinishedListener> mFinishedListeners = new ArrayList();
private ItemAnimatorListener mListener = null;
private long mMoveDuration = 250;
private long mRemoveDuration = 120;
@Retention(RetentionPolicy.SOURCE)
public @interface AdapterChanges {
}
public interface ItemAnimatorFinishedListener {
void onAnimationsFinished();
}
interface ItemAnimatorListener {
void onAnimationFinished(ViewHolder viewHolder);
}
public static class ItemHolderInfo {
public int bottom;
public int changeFlags;
public int left;
public int right;
public int top;
public ItemHolderInfo setFrom(ViewHolder holder) {
return setFrom(holder, 0);
}
public ItemHolderInfo setFrom(ViewHolder holder, int flags) {
View view = holder.itemView;
this.left = view.getLeft();
this.top = view.getTop();
this.right = view.getRight();
this.bottom = view.getBottom();
return this;
}
}
public abstract boolean animateAppearance(@NonNull ViewHolder viewHolder, @Nullable ItemHolderInfo itemHolderInfo, @NonNull ItemHolderInfo itemHolderInfo2);
public abstract boolean animateChange(@NonNull ViewHolder viewHolder, @NonNull ViewHolder viewHolder2, @NonNull ItemHolderInfo itemHolderInfo, @NonNull ItemHolderInfo itemHolderInfo2);
public abstract boolean animateDisappearance(@NonNull ViewHolder viewHolder, @NonNull ItemHolderInfo itemHolderInfo, @Nullable ItemHolderInfo itemHolderInfo2);
public abstract boolean animatePersistence(@NonNull ViewHolder viewHolder, @NonNull ItemHolderInfo itemHolderInfo, @NonNull ItemHolderInfo itemHolderInfo2);
public abstract void endAnimation(ViewHolder viewHolder);
public abstract void endAnimations();
public abstract boolean isRunning();
public abstract void runPendingAnimations();
public long getMoveDuration() {
return this.mMoveDuration;
}
public void setMoveDuration(long moveDuration) {
this.mMoveDuration = moveDuration;
}
public long getAddDuration() {
return this.mAddDuration;
}
public void setAddDuration(long addDuration) {
this.mAddDuration = addDuration;
}
public long getRemoveDuration() {
return this.mRemoveDuration;
}
public void setRemoveDuration(long removeDuration) {
this.mRemoveDuration = removeDuration;
}
public long getChangeDuration() {
return this.mChangeDuration;
}
public void setChangeDuration(long changeDuration) {
this.mChangeDuration = changeDuration;
}
void setListener(ItemAnimatorListener listener) {
this.mListener = listener;
}
@NonNull
public ItemHolderInfo recordPreLayoutInformation(@NonNull State state, @NonNull ViewHolder viewHolder, int changeFlags, @NonNull List<Object> list) {
return obtainHolderInfo().setFrom(viewHolder);
}
@NonNull
public ItemHolderInfo recordPostLayoutInformation(@NonNull State state, @NonNull ViewHolder viewHolder) {
return obtainHolderInfo().setFrom(viewHolder);
}
static int buildAdapterChangeFlagsForAnimations(ViewHolder viewHolder) {
int flags = viewHolder.mFlags & 14;
if (viewHolder.isInvalid()) {
return 4;
}
if ((flags & 4) == 0) {
int oldPos = viewHolder.getOldPosition();
int pos = viewHolder.getAdapterPosition();
if (!(oldPos == -1 || pos == -1 || oldPos == pos)) {
flags |= 2048;
}
}
return flags;
}
public final void dispatchAnimationFinished(ViewHolder viewHolder) {
onAnimationFinished(viewHolder);
if (this.mListener != null) {
this.mListener.onAnimationFinished(viewHolder);
}
}
public void onAnimationFinished(ViewHolder viewHolder) {
}
public final void dispatchAnimationStarted(ViewHolder viewHolder) {
onAnimationStarted(viewHolder);
}
public void onAnimationStarted(ViewHolder viewHolder) {
}
public final boolean isRunning(ItemAnimatorFinishedListener listener) {
boolean running = isRunning();
if (listener != null) {
if (running) {
this.mFinishedListeners.add(listener);
} else {
listener.onAnimationsFinished();
}
}
return running;
}
public boolean canReuseUpdatedViewHolder(ViewHolder viewHolder) {
return true;
}
public final void dispatchAnimationsFinished() {
int count = this.mFinishedListeners.size();
for (int i = 0; i < count; i++) {
((ItemAnimatorFinishedListener) this.mFinishedListeners.get(i)).onAnimationsFinished();
}
this.mFinishedListeners.clear();
}
public ItemHolderInfo obtainHolderInfo() {
return new ItemHolderInfo();
}
}
public static abstract class ItemDecoration {
public void onDraw(Canvas c, RecyclerView parent, State state) {
onDraw(c, parent);
}
@Deprecated
public void onDraw(Canvas c, RecyclerView parent) {
}
public void onDrawOver(Canvas c, RecyclerView parent, State state) {
onDrawOver(c, parent);
}
@Deprecated
public void onDrawOver(Canvas c, RecyclerView parent) {
}
@Deprecated
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
outRect.set(0, 0, 0, 0);
}
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(), parent);
}
}
public static abstract class LayoutManager {
ChildHelper mChildHelper;
private boolean mIsAttachedToWindow = false;
RecyclerView mRecyclerView;
private boolean mRequestedSimpleAnimations = false;
@Nullable
SmoothScroller mSmoothScroller;
public static class Properties {
public int orientation;
public boolean reverseLayout;
public int spanCount;
public boolean stackFromEnd;
}
public abstract LayoutParams generateDefaultLayoutParams();
void setRecyclerView(RecyclerView recyclerView) {
if (recyclerView == null) {
this.mRecyclerView = null;
this.mChildHelper = null;
return;
}
this.mRecyclerView = recyclerView;
this.mChildHelper = recyclerView.mChildHelper;
}
public void requestLayout() {
if (this.mRecyclerView != null) {
this.mRecyclerView.requestLayout();
}
}
public void assertInLayoutOrScroll(String message) {
if (this.mRecyclerView != null) {
this.mRecyclerView.assertInLayoutOrScroll(message);
}
}
public void assertNotInLayoutOrScroll(String message) {
if (this.mRecyclerView != null) {
this.mRecyclerView.assertNotInLayoutOrScroll(message);
}
}
public boolean supportsPredictiveItemAnimations() {
return false;
}
void dispatchAttachedToWindow(RecyclerView view) {
this.mIsAttachedToWindow = true;
onAttachedToWindow(view);
}
void dispatchDetachedFromWindow(RecyclerView view, Recycler recycler) {
this.mIsAttachedToWindow = false;
onDetachedFromWindow(view, recycler);
}
public boolean isAttachedToWindow() {
return this.mIsAttachedToWindow;
}
public void postOnAnimation(Runnable action) {
if (this.mRecyclerView != null) {
ViewCompat.postOnAnimation(this.mRecyclerView, action);
}
}
public boolean removeCallbacks(Runnable action) {
if (this.mRecyclerView != null) {
return this.mRecyclerView.removeCallbacks(action);
}
return false;
}
@CallSuper
public void onAttachedToWindow(RecyclerView view) {
}
@Deprecated
public void onDetachedFromWindow(RecyclerView view) {
}
@CallSuper
public void onDetachedFromWindow(RecyclerView view, Recycler recycler) {
onDetachedFromWindow(view);
}
public boolean getClipToPadding() {
return this.mRecyclerView != null && this.mRecyclerView.mClipToPadding;
}
public void onLayoutChildren(Recycler recycler, State state) {
Log.e(RecyclerView.TAG, "You must override onLayoutChildren(Recycler recycler, State state) ");
}
public boolean checkLayoutParams(LayoutParams lp) {
return lp != null;
}
public LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams lp) {
if (lp instanceof LayoutParams) {
return new LayoutParams((LayoutParams) lp);
}
if (lp instanceof MarginLayoutParams) {
return new LayoutParams((MarginLayoutParams) lp);
}
return new LayoutParams(lp);
}
public LayoutParams generateLayoutParams(Context c, AttributeSet attrs) {
return new LayoutParams(c, attrs);
}
public int scrollHorizontallyBy(int dx, Recycler recycler, State state) {
return 0;
}
public int scrollVerticallyBy(int dy, Recycler recycler, State state) {
return 0;
}
public boolean canScrollHorizontally() {
return false;
}
public boolean canScrollVertically() {
return false;
}
public void scrollToPosition(int position) {
}
public void smoothScrollToPosition(RecyclerView recyclerView, State state, int position) {
Log.e(RecyclerView.TAG, "You must override smoothScrollToPosition to support smooth scrolling");
}
public void startSmoothScroll(SmoothScroller smoothScroller) {
if (!(this.mSmoothScroller == null || smoothScroller == this.mSmoothScroller || !this.mSmoothScroller.isRunning())) {
this.mSmoothScroller.stop();
}
this.mSmoothScroller = smoothScroller;
this.mSmoothScroller.start(this.mRecyclerView, this);
}
public boolean isSmoothScrolling() {
return this.mSmoothScroller != null && this.mSmoothScroller.isRunning();
}
public int getLayoutDirection() {
return ViewCompat.getLayoutDirection(this.mRecyclerView);
}
public void endAnimation(View view) {
if (this.mRecyclerView.mItemAnimator != null) {
this.mRecyclerView.mItemAnimator.endAnimation(RecyclerView.getChildViewHolderInt(view));
}
}
public void addDisappearingView(View child) {
addDisappearingView(child, -1);
}
public void addDisappearingView(View child, int index) {
addViewInt(child, index, true);
}
public void addView(View child) {
addView(child, -1);
}
public void addView(View child, int index) {
addViewInt(child, index, false);
}
private void addViewInt(View child, int index, boolean disappearing) {
ViewHolder holder = RecyclerView.getChildViewHolderInt(child);
if (disappearing || holder.isRemoved()) {
this.mRecyclerView.mViewInfoStore.addToDisappearedInLayout(holder);
} else {
this.mRecyclerView.mViewInfoStore.removeFromDisappearedInLayout(holder);
}
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (holder.wasReturnedFromScrap() || holder.isScrap()) {
if (holder.isScrap()) {
holder.unScrap();
} else {
holder.clearReturnedFromScrapFlag();
}
this.mChildHelper.attachViewToParent(child, index, child.getLayoutParams(), false);
} else if (child.getParent() == this.mRecyclerView) {
int currentIndex = this.mChildHelper.indexOfChild(child);
if (index == -1) {
index = this.mChildHelper.getChildCount();
}
if (currentIndex == -1) {
throw new IllegalStateException("Added View has RecyclerView as parent but view is not a real child. Unfiltered index:" + this.mRecyclerView.indexOfChild(child));
} else if (currentIndex != index) {
this.mRecyclerView.mLayout.moveView(currentIndex, index);
}
} else {
this.mChildHelper.addView(child, index, false);
lp.mInsetsDirty = true;
if (this.mSmoothScroller != null && this.mSmoothScroller.isRunning()) {
this.mSmoothScroller.onChildAttachedToWindow(child);
}
}
if (lp.mPendingInvalidate) {
holder.itemView.invalidate();
lp.mPendingInvalidate = false;
}
}
public void removeView(View child) {
this.mChildHelper.removeView(child);
}
public void removeViewAt(int index) {
if (getChildAt(index) != null) {
this.mChildHelper.removeViewAt(index);
}
}
public void removeAllViews() {
for (int i = getChildCount() - 1; i >= 0; i--) {
this.mChildHelper.removeViewAt(i);
}
}
public int getBaseline() {
return -1;
}
public int getPosition(View view) {
return ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
}
public int getItemViewType(View view) {
return RecyclerView.getChildViewHolderInt(view).getItemViewType();
}
public View findViewByPosition(int position) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
ViewHolder vh = RecyclerView.getChildViewHolderInt(child);
if (vh != null && vh.getLayoutPosition() == position && !vh.shouldIgnore() && (this.mRecyclerView.mState.isPreLayout() || !vh.isRemoved())) {
return child;
}
}
return null;
}
public void detachView(View child) {
int ind = this.mChildHelper.indexOfChild(child);
if (ind >= 0) {
detachViewInternal(ind, child);
}
}
public void detachViewAt(int index) {
detachViewInternal(index, getChildAt(index));
}
private void detachViewInternal(int index, View view) {
this.mChildHelper.detachViewFromParent(index);
}
public void attachView(View child, int index, LayoutParams lp) {
ViewHolder vh = RecyclerView.getChildViewHolderInt(child);
if (vh.isRemoved()) {
this.mRecyclerView.mViewInfoStore.addToDisappearedInLayout(vh);
} else {
this.mRecyclerView.mViewInfoStore.removeFromDisappearedInLayout(vh);
}
this.mChildHelper.attachViewToParent(child, index, lp, vh.isRemoved());
}
public void attachView(View child, int index) {
attachView(child, index, (LayoutParams) child.getLayoutParams());
}
public void attachView(View child) {
attachView(child, -1);
}
public void removeDetachedView(View child) {
this.mRecyclerView.removeDetachedView(child, false);
}
public void moveView(int fromIndex, int toIndex) {
View view = getChildAt(fromIndex);
if (view == null) {
throw new IllegalArgumentException("Cannot move a child from non-existing index:" + fromIndex);
}
detachViewAt(fromIndex);
attachView(view, toIndex);
}
public void detachAndScrapView(View child, Recycler recycler) {
scrapOrRecycleView(recycler, this.mChildHelper.indexOfChild(child), child);
}
public void detachAndScrapViewAt(int index, Recycler recycler) {
scrapOrRecycleView(recycler, index, getChildAt(index));
}
public void removeAndRecycleView(View child, Recycler recycler) {
removeView(child);
recycler.recycleView(child);
}
public void removeAndRecycleViewAt(int index, Recycler recycler) {
View view = getChildAt(index);
removeViewAt(index);
recycler.recycleView(view);
}
public int getChildCount() {
return this.mChildHelper != null ? this.mChildHelper.getChildCount() : 0;
}
public View getChildAt(int index) {
return this.mChildHelper != null ? this.mChildHelper.getChildAt(index) : null;
}
public int getWidth() {
return this.mRecyclerView != null ? this.mRecyclerView.getWidth() : 0;
}
public int getHeight() {
return this.mRecyclerView != null ? this.mRecyclerView.getHeight() : 0;
}
public int getPaddingLeft() {
return this.mRecyclerView != null ? this.mRecyclerView.getPaddingLeft() : 0;
}
public int getPaddingTop() {
return this.mRecyclerView != null ? this.mRecyclerView.getPaddingTop() : 0;
}
public int getPaddingRight() {
return this.mRecyclerView != null ? this.mRecyclerView.getPaddingRight() : 0;
}
public int getPaddingBottom() {
return this.mRecyclerView != null ? this.mRecyclerView.getPaddingBottom() : 0;
}
public int getPaddingStart() {
return this.mRecyclerView != null ? ViewCompat.getPaddingStart(this.mRecyclerView) : 0;
}
public int getPaddingEnd() {
return this.mRecyclerView != null ? ViewCompat.getPaddingEnd(this.mRecyclerView) : 0;
}
public boolean isFocused() {
return this.mRecyclerView != null && this.mRecyclerView.isFocused();
}
public boolean hasFocus() {
return this.mRecyclerView != null && this.mRecyclerView.hasFocus();
}
public View getFocusedChild() {
if (this.mRecyclerView == null) {
return null;
}
View focused = this.mRecyclerView.getFocusedChild();
if (focused == null || this.mChildHelper.isHidden(focused)) {
return null;
}
return focused;
}
public int getItemCount() {
Adapter a = this.mRecyclerView != null ? this.mRecyclerView.getAdapter() : null;
return a != null ? a.getItemCount() : 0;
}
public void offsetChildrenHorizontal(int dx) {
if (this.mRecyclerView != null) {
this.mRecyclerView.offsetChildrenHorizontal(dx);
}
}
public void offsetChildrenVertical(int dy) {
if (this.mRecyclerView != null) {
this.mRecyclerView.offsetChildrenVertical(dy);
}
}
public void ignoreView(View view) {
if (view.getParent() != this.mRecyclerView || this.mRecyclerView.indexOfChild(view) == -1) {
throw new IllegalArgumentException("View should be fully attached to be ignored");
}
ViewHolder vh = RecyclerView.getChildViewHolderInt(view);
vh.addFlags(128);
this.mRecyclerView.mViewInfoStore.removeViewHolder(vh);
}
public void stopIgnoringView(View view) {
ViewHolder vh = RecyclerView.getChildViewHolderInt(view);
vh.stopIgnoring();
vh.resetInternal();
vh.addFlags(4);
}
public void detachAndScrapAttachedViews(Recycler recycler) {
for (int i = getChildCount() - 1; i >= 0; i--) {
scrapOrRecycleView(recycler, i, getChildAt(i));
}
}
private void scrapOrRecycleView(Recycler recycler, int index, View view) {
ViewHolder viewHolder = RecyclerView.getChildViewHolderInt(view);
if (!viewHolder.shouldIgnore()) {
if (!viewHolder.isInvalid() || viewHolder.isRemoved() || this.mRecyclerView.mAdapter.hasStableIds()) {
detachViewAt(index);
recycler.scrapView(view);
return;
}
removeViewAt(index);
recycler.recycleViewHolderInternal(viewHolder);
}
}
void removeAndRecycleScrapInt(Recycler recycler) {
int scrapCount = recycler.getScrapCount();
for (int i = scrapCount - 1; i >= 0; i--) {
View scrap = recycler.getScrapViewAt(i);
ViewHolder vh = RecyclerView.getChildViewHolderInt(scrap);
if (!vh.shouldIgnore()) {
vh.setIsRecyclable(false);
if (vh.isTmpDetached()) {
this.mRecyclerView.removeDetachedView(scrap, false);
}
if (this.mRecyclerView.mItemAnimator != null) {
this.mRecyclerView.mItemAnimator.endAnimation(vh);
}
vh.setIsRecyclable(true);
recycler.quickRecycleScrapView(scrap);
}
}
recycler.clearScrap();
if (scrapCount > 0) {
this.mRecyclerView.invalidate();
}
}
public void measureChild(View child, int widthUsed, int heightUsed) {
LayoutParams lp = (LayoutParams) child.getLayoutParams();
Rect insets = this.mRecyclerView.getItemDecorInsetsForChild(child);
child.measure(getChildMeasureSpec(getWidth(), (getPaddingLeft() + getPaddingRight()) + (widthUsed + (insets.left + insets.right)), lp.width, canScrollHorizontally()), getChildMeasureSpec(getHeight(), (getPaddingTop() + getPaddingBottom()) + (heightUsed + (insets.top + insets.bottom)), lp.height, canScrollVertically()));
}
public void measureChildWithMargins(View child, int widthUsed, int heightUsed) {
LayoutParams lp = (LayoutParams) child.getLayoutParams();
Rect insets = this.mRecyclerView.getItemDecorInsetsForChild(child);
child.measure(getChildMeasureSpec(getWidth(), (((getPaddingLeft() + getPaddingRight()) + lp.leftMargin) + lp.rightMargin) + (widthUsed + (insets.left + insets.right)), lp.width, canScrollHorizontally()), getChildMeasureSpec(getHeight(), (((getPaddingTop() + getPaddingBottom()) + lp.topMargin) + lp.bottomMargin) + (heightUsed + (insets.top + insets.bottom)), lp.height, canScrollVertically()));
}
public static int getChildMeasureSpec(int parentSize, int padding, int childDimension, boolean canScroll) {
int size = Math.max(0, parentSize - padding);
int resultSize = 0;
int resultMode = 0;
if (canScroll) {
if (childDimension >= 0) {
resultSize = childDimension;
resultMode = 1073741824;
} else {
resultSize = 0;
resultMode = 0;
}
} else if (childDimension >= 0) {
resultSize = childDimension;
resultMode = 1073741824;
} else if (childDimension == -1) {
resultSize = size;
resultMode = 1073741824;
} else if (childDimension == -2) {
resultSize = size;
resultMode = Integer.MIN_VALUE;
}
return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
}
public int getDecoratedMeasuredWidth(View child) {
Rect insets = ((LayoutParams) child.getLayoutParams()).mDecorInsets;
return (child.getMeasuredWidth() + insets.left) + insets.right;
}
public int getDecoratedMeasuredHeight(View child) {
Rect insets = ((LayoutParams) child.getLayoutParams()).mDecorInsets;
return (child.getMeasuredHeight() + insets.top) + insets.bottom;
}
public void layoutDecorated(View child, int left, int top, int right, int bottom) {
Rect insets = ((LayoutParams) child.getLayoutParams()).mDecorInsets;
child.layout(insets.left + left, insets.top + top, right - insets.right, bottom - insets.bottom);
}
public int getDecoratedLeft(View child) {
return child.getLeft() - getLeftDecorationWidth(child);
}
public int getDecoratedTop(View child) {
return child.getTop() - getTopDecorationHeight(child);
}
public int getDecoratedRight(View child) {
return child.getRight() + getRightDecorationWidth(child);
}
public int getDecoratedBottom(View child) {
return child.getBottom() + getBottomDecorationHeight(child);
}
public void calculateItemDecorationsForChild(View child, Rect outRect) {
if (this.mRecyclerView == null) {
outRect.set(0, 0, 0, 0);
} else {
outRect.set(this.mRecyclerView.getItemDecorInsetsForChild(child));
}
}
public int getTopDecorationHeight(View child) {
return ((LayoutParams) child.getLayoutParams()).mDecorInsets.top;
}
public int getBottomDecorationHeight(View child) {
return ((LayoutParams) child.getLayoutParams()).mDecorInsets.bottom;
}
public int getLeftDecorationWidth(View child) {
return ((LayoutParams) child.getLayoutParams()).mDecorInsets.left;
}
public int getRightDecorationWidth(View child) {
return ((LayoutParams) child.getLayoutParams()).mDecorInsets.right;
}
@Nullable
public View onFocusSearchFailed(View focused, int direction, Recycler recycler, State state) {
return null;
}
public View onInterceptFocusSearch(View focused, int direction) {
return null;
}
public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect, boolean immediate) {
int parentLeft = getPaddingLeft();
int parentTop = getPaddingTop();
int parentRight = getWidth() - getPaddingRight();
int parentBottom = getHeight() - getPaddingBottom();
int childLeft = child.getLeft() + rect.left;
int childTop = child.getTop() + rect.top;
int childRight = childLeft + rect.width();
int childBottom = childTop + rect.height();
int offScreenLeft = Math.min(0, childLeft - parentLeft);
int offScreenTop = Math.min(0, childTop - parentTop);
int offScreenRight = Math.max(0, childRight - parentRight);
int offScreenBottom = Math.max(0, childBottom - parentBottom);
int dx = getLayoutDirection() == 1 ? offScreenRight != 0 ? offScreenRight : Math.max(offScreenLeft, childRight - parentRight) : offScreenLeft != 0 ? offScreenLeft : Math.min(childLeft - parentLeft, offScreenRight);
int dy = offScreenTop != 0 ? offScreenTop : Math.min(childTop - parentTop, offScreenBottom);
if (dx == 0 && dy == 0) {
return false;
}
if (immediate) {
parent.scrollBy(dx, dy);
} else {
parent.smoothScrollBy(dx, dy);
}
return true;
}
@Deprecated
public boolean onRequestChildFocus(RecyclerView parent, View child, View focused) {
return isSmoothScrolling() || parent.isComputingLayout();
}
public boolean onRequestChildFocus(RecyclerView parent, State state, View child, View focused) {
return onRequestChildFocus(parent, child, focused);
}
public void onAdapterChanged(Adapter oldAdapter, Adapter newAdapter) {
}
public boolean onAddFocusables(RecyclerView recyclerView, ArrayList<View> arrayList, int direction, int focusableMode) {
return false;
}
public void onItemsChanged(RecyclerView recyclerView) {
}
public void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount) {
}
public void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount) {
}
public void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount) {
}
public void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount, Object payload) {
onItemsUpdated(recyclerView, positionStart, itemCount);
}
public void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCount) {
}
public int computeHorizontalScrollExtent(State state) {
return 0;
}
public int computeHorizontalScrollOffset(State state) {
return 0;
}
public int computeHorizontalScrollRange(State state) {
return 0;
}
public int computeVerticalScrollExtent(State state) {
return 0;
}
public int computeVerticalScrollOffset(State state) {
return 0;
}
public int computeVerticalScrollRange(State state) {
return 0;
}
public void onMeasure(Recycler recycler, State state, int widthSpec, int heightSpec) {
this.mRecyclerView.defaultOnMeasure(widthSpec, heightSpec);
}
public void setMeasuredDimension(int widthSize, int heightSize) {
this.mRecyclerView.setMeasuredDimension(widthSize, heightSize);
}
public int getMinimumWidth() {
return ViewCompat.getMinimumWidth(this.mRecyclerView);
}
public int getMinimumHeight() {
return ViewCompat.getMinimumHeight(this.mRecyclerView);
}
public Parcelable onSaveInstanceState() {
return null;
}
public void onRestoreInstanceState(Parcelable state) {
}
void stopSmoothScroller() {
if (this.mSmoothScroller != null) {
this.mSmoothScroller.stop();
}
}
private void onSmoothScrollerStopped(SmoothScroller smoothScroller) {
if (this.mSmoothScroller == smoothScroller) {
this.mSmoothScroller = null;
}
}
public void onScrollStateChanged(int state) {
}
public void removeAndRecycleAllViews(Recycler recycler) {
for (int i = getChildCount() - 1; i >= 0; i--) {
if (!RecyclerView.getChildViewHolderInt(getChildAt(i)).shouldIgnore()) {
removeAndRecycleViewAt(i, recycler);
}
}
}
void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfoCompat info) {
onInitializeAccessibilityNodeInfo(this.mRecyclerView.mRecycler, this.mRecyclerView.mState, info);
}
public void onInitializeAccessibilityNodeInfo(Recycler recycler, State state, AccessibilityNodeInfoCompat info) {
if (ViewCompat.canScrollVertically(this.mRecyclerView, -1) || ViewCompat.canScrollHorizontally(this.mRecyclerView, -1)) {
info.addAction(8192);
info.setScrollable(true);
}
if (ViewCompat.canScrollVertically(this.mRecyclerView, 1) || ViewCompat.canScrollHorizontally(this.mRecyclerView, 1)) {
info.addAction(4096);
info.setScrollable(true);
}
info.setCollectionInfo(CollectionInfoCompat.obtain(getRowCountForAccessibility(recycler, state), getColumnCountForAccessibility(recycler, state), isLayoutHierarchical(recycler, state), getSelectionModeForAccessibility(recycler, state)));
}
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
onInitializeAccessibilityEvent(this.mRecyclerView.mRecycler, this.mRecyclerView.mState, event);
}
public void onInitializeAccessibilityEvent(Recycler recycler, State state, AccessibilityEvent event) {
boolean z = true;
AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
if (this.mRecyclerView != null && record != null) {
if (!(ViewCompat.canScrollVertically(this.mRecyclerView, 1) || ViewCompat.canScrollVertically(this.mRecyclerView, -1) || ViewCompat.canScrollHorizontally(this.mRecyclerView, -1) || ViewCompat.canScrollHorizontally(this.mRecyclerView, 1))) {
z = false;
}
record.setScrollable(z);
if (this.mRecyclerView.mAdapter != null) {
record.setItemCount(this.mRecyclerView.mAdapter.getItemCount());
}
}
}
void onInitializeAccessibilityNodeInfoForItem(View host, AccessibilityNodeInfoCompat info) {
ViewHolder vh = RecyclerView.getChildViewHolderInt(host);
if (vh != null && !vh.isRemoved() && !this.mChildHelper.isHidden(vh.itemView)) {
onInitializeAccessibilityNodeInfoForItem(this.mRecyclerView.mRecycler, this.mRecyclerView.mState, host, info);
}
}
public void onInitializeAccessibilityNodeInfoForItem(Recycler recycler, State state, View host, AccessibilityNodeInfoCompat info) {
int rowIndexGuess;
int columnIndexGuess;
if (canScrollVertically()) {
rowIndexGuess = getPosition(host);
} else {
rowIndexGuess = 0;
}
if (canScrollHorizontally()) {
columnIndexGuess = getPosition(host);
} else {
columnIndexGuess = 0;
}
info.setCollectionItemInfo(CollectionItemInfoCompat.obtain(rowIndexGuess, 1, columnIndexGuess, 1, false, false));
}
public void requestSimpleAnimationsInNextLayout() {
this.mRequestedSimpleAnimations = true;
}
public int getSelectionModeForAccessibility(Recycler recycler, State state) {
return 0;
}
public int getRowCountForAccessibility(Recycler recycler, State state) {
if (this.mRecyclerView == null || this.mRecyclerView.mAdapter == null || !canScrollVertically()) {
return 1;
}
return this.mRecyclerView.mAdapter.getItemCount();
}
public int getColumnCountForAccessibility(Recycler recycler, State state) {
if (this.mRecyclerView == null || this.mRecyclerView.mAdapter == null || !canScrollHorizontally()) {
return 1;
}
return this.mRecyclerView.mAdapter.getItemCount();
}
public boolean isLayoutHierarchical(Recycler recycler, State state) {
return false;
}
boolean performAccessibilityAction(int action, Bundle args) {
return performAccessibilityAction(this.mRecyclerView.mRecycler, this.mRecyclerView.mState, action, args);
}
public boolean performAccessibilityAction(Recycler recycler, State state, int action, Bundle args) {
if (this.mRecyclerView == null) {
return false;
}
int vScroll = 0;
int hScroll = 0;
switch (action) {
case 4096:
if (ViewCompat.canScrollVertically(this.mRecyclerView, 1)) {
vScroll = (getHeight() - getPaddingTop()) - getPaddingBottom();
}
if (ViewCompat.canScrollHorizontally(this.mRecyclerView, 1)) {
hScroll = (getWidth() - getPaddingLeft()) - getPaddingRight();
break;
}
break;
case 8192:
if (ViewCompat.canScrollVertically(this.mRecyclerView, -1)) {
vScroll = -((getHeight() - getPaddingTop()) - getPaddingBottom());
}
if (ViewCompat.canScrollHorizontally(this.mRecyclerView, -1)) {
hScroll = -((getWidth() - getPaddingLeft()) - getPaddingRight());
break;
}
break;
}
if (vScroll == 0 && hScroll == 0) {
return false;
}
this.mRecyclerView.scrollBy(hScroll, vScroll);
return true;
}
boolean performAccessibilityActionForItem(View view, int action, Bundle args) {
return performAccessibilityActionForItem(this.mRecyclerView.mRecycler, this.mRecyclerView.mState, view, action, args);
}
public boolean performAccessibilityActionForItem(Recycler recycler, State state, View view, int action, Bundle args) {
return false;
}
public static Properties getProperties(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
Properties properties = new Properties();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerView, defStyleAttr, defStyleRes);
properties.orientation = a.getInt(R.styleable.RecyclerView_android_orientation, 1);
properties.spanCount = a.getInt(R.styleable.RecyclerView_spanCount, 1);
properties.reverseLayout = a.getBoolean(R.styleable.RecyclerView_reverseLayout, false);
properties.stackFromEnd = a.getBoolean(R.styleable.RecyclerView_stackFromEnd, false);
a.recycle();
return properties;
}
}
public static class LayoutParams extends MarginLayoutParams {
final Rect mDecorInsets = new Rect();
boolean mInsetsDirty = true;
boolean mPendingInvalidate = false;
ViewHolder mViewHolder;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
public LayoutParams(android.view.ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(LayoutParams source) {
super(source);
}
public boolean viewNeedsUpdate() {
return this.mViewHolder.needsUpdate();
}
public boolean isViewInvalid() {
return this.mViewHolder.isInvalid();
}
public boolean isItemRemoved() {
return this.mViewHolder.isRemoved();
}
public boolean isItemChanged() {
return this.mViewHolder.isUpdated();
}
public int getViewPosition() {
return this.mViewHolder.getPosition();
}
public int getViewLayoutPosition() {
return this.mViewHolder.getLayoutPosition();
}
public int getViewAdapterPosition() {
return this.mViewHolder.getAdapterPosition();
}
}
public interface OnChildAttachStateChangeListener {
void onChildViewAttachedToWindow(View view);
void onChildViewDetachedFromWindow(View view);
}
public interface OnItemTouchListener {
boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent);
void onRequestDisallowInterceptTouchEvent(boolean z);
void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent);
}
public static abstract class OnScrollListener {
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
}
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
}
}
public static class RecycledViewPool {
private static final int DEFAULT_MAX_SCRAP = 5;
private int mAttachCount = 0;
private SparseIntArray mMaxScrap = new SparseIntArray();
private SparseArray<ArrayList<ViewHolder>> mScrap = new SparseArray();
public void clear() {
this.mScrap.clear();
}
public void setMaxRecycledViews(int viewType, int max) {
this.mMaxScrap.put(viewType, max);
ArrayList<ViewHolder> scrapHeap = (ArrayList) this.mScrap.get(viewType);
if (scrapHeap != null) {
while (scrapHeap.size() > max) {
scrapHeap.remove(scrapHeap.size() - 1);
}
}
}
public ViewHolder getRecycledView(int viewType) {
ArrayList<ViewHolder> scrapHeap = (ArrayList) this.mScrap.get(viewType);
if (scrapHeap == null || scrapHeap.isEmpty()) {
return null;
}
int index = scrapHeap.size() - 1;
ViewHolder scrap = (ViewHolder) scrapHeap.get(index);
scrapHeap.remove(index);
return scrap;
}
int size() {
int count = 0;
for (int i = 0; i < this.mScrap.size(); i++) {
ArrayList<ViewHolder> viewHolders = (ArrayList) this.mScrap.valueAt(i);
if (viewHolders != null) {
count += viewHolders.size();
}
}
return count;
}
public void putRecycledView(ViewHolder scrap) {
int viewType = scrap.getItemViewType();
ArrayList scrapHeap = getScrapHeapForType(viewType);
if (this.mMaxScrap.get(viewType) > scrapHeap.size()) {
scrap.resetInternal();
scrapHeap.add(scrap);
}
}
void attach(Adapter adapter) {
this.mAttachCount++;
}
void detach() {
this.mAttachCount--;
}
void onAdapterChanged(Adapter oldAdapter, Adapter newAdapter, boolean compatibleWithPrevious) {
if (oldAdapter != null) {
detach();
}
if (!compatibleWithPrevious && this.mAttachCount == 0) {
clear();
}
if (newAdapter != null) {
attach(newAdapter);
}
}
private ArrayList<ViewHolder> getScrapHeapForType(int viewType) {
ArrayList<ViewHolder> scrap = (ArrayList) this.mScrap.get(viewType);
if (scrap == null) {
scrap = new ArrayList();
this.mScrap.put(viewType, scrap);
if (this.mMaxScrap.indexOfKey(viewType) < 0) {
this.mMaxScrap.put(viewType, 5);
}
}
return scrap;
}
}
public final class Recycler {
private static final int DEFAULT_CACHE_SIZE = 2;
final ArrayList<ViewHolder> mAttachedScrap = new ArrayList();
final ArrayList<ViewHolder> mCachedViews = new ArrayList();
private ArrayList<ViewHolder> mChangedScrap = null;
private RecycledViewPool mRecyclerPool;
private final List<ViewHolder> mUnmodifiableAttachedScrap = Collections.unmodifiableList(this.mAttachedScrap);
private ViewCacheExtension mViewCacheExtension;
private int mViewCacheMax = 2;
public void clear() {
this.mAttachedScrap.clear();
recycleAndClearCachedViews();
}
public void setViewCacheSize(int viewCount) {
this.mViewCacheMax = viewCount;
for (int i = this.mCachedViews.size() - 1; i >= 0 && this.mCachedViews.size() > viewCount; i--) {
recycleCachedViewAt(i);
}
}
public List<ViewHolder> getScrapList() {
return this.mUnmodifiableAttachedScrap;
}
boolean validateViewHolderForOffsetPosition(ViewHolder holder) {
if (holder.isRemoved()) {
return true;
}
if (holder.mPosition < 0 || holder.mPosition >= RecyclerView.this.mAdapter.getItemCount()) {
throw new IndexOutOfBoundsException("Inconsistency detected. Invalid view holder adapter position" + holder);
} else if (!RecyclerView.this.mState.isPreLayout() && RecyclerView.this.mAdapter.getItemViewType(holder.mPosition) != holder.getItemViewType()) {
return false;
} else {
if (!RecyclerView.this.mAdapter.hasStableIds() || holder.getItemId() == RecyclerView.this.mAdapter.getItemId(holder.mPosition)) {
return true;
}
return false;
}
}
public void bindViewToPosition(View view, int position) {
boolean z = true;
ViewHolder holder = RecyclerView.getChildViewHolderInt(view);
if (holder == null) {
throw new IllegalArgumentException("The view does not have a ViewHolder. You cannot pass arbitrary views to this method, they should be created by the Adapter");
}
int offsetPosition = RecyclerView.this.mAdapterHelper.findPositionOffset(position);
if (offsetPosition < 0 || offsetPosition >= RecyclerView.this.mAdapter.getItemCount()) {
throw new IndexOutOfBoundsException("Inconsistency detected. Invalid item position " + position + "(offset:" + offsetPosition + ")." + "state:" + RecyclerView.this.mState.getItemCount());
}
LayoutParams rvLayoutParams;
holder.mOwnerRecyclerView = RecyclerView.this;
RecyclerView.this.mAdapter.bindViewHolder(holder, offsetPosition);
attachAccessibilityDelegate(view);
if (RecyclerView.this.mState.isPreLayout()) {
holder.mPreLayoutPosition = position;
}
android.view.ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if (lp == null) {
rvLayoutParams = (LayoutParams) RecyclerView.this.generateDefaultLayoutParams();
holder.itemView.setLayoutParams(rvLayoutParams);
} else if (RecyclerView.this.checkLayoutParams(lp)) {
rvLayoutParams = (LayoutParams) lp;
} else {
rvLayoutParams = (LayoutParams) RecyclerView.this.generateLayoutParams(lp);
holder.itemView.setLayoutParams(rvLayoutParams);
}
rvLayoutParams.mInsetsDirty = true;
rvLayoutParams.mViewHolder = holder;
if (holder.itemView.getParent() != null) {
z = false;
}
rvLayoutParams.mPendingInvalidate = z;
}
public int convertPreLayoutPositionToPostLayout(int position) {
if (position >= 0 && position < RecyclerView.this.mState.getItemCount()) {
return !RecyclerView.this.mState.isPreLayout() ? position : RecyclerView.this.mAdapterHelper.findPositionOffset(position);
} else {
throw new IndexOutOfBoundsException("invalid position " + position + ". State " + "item count is " + RecyclerView.this.mState.getItemCount());
}
}
public View getViewForPosition(int position) {
return getViewForPosition(position, false);
}
View getViewForPosition(int position, boolean dryRun) {
if (position < 0 || position >= RecyclerView.this.mState.getItemCount()) {
throw new IndexOutOfBoundsException("Invalid item position " + position + "(" + position + "). Item count:" + RecyclerView.this.mState.getItemCount());
}
int offsetPosition;
LayoutParams rvLayoutParams;
boolean fromScrap = false;
ViewHolder holder = null;
if (RecyclerView.this.mState.isPreLayout()) {
holder = getChangedScrapViewForPosition(position);
fromScrap = holder != null;
}
if (holder == null) {
holder = getScrapViewForPosition(position, -1, dryRun);
if (holder != null) {
if (validateViewHolderForOffsetPosition(holder)) {
fromScrap = true;
} else {
if (!dryRun) {
holder.addFlags(4);
if (holder.isScrap()) {
RecyclerView.this.removeDetachedView(holder.itemView, false);
holder.unScrap();
} else if (holder.wasReturnedFromScrap()) {
holder.clearReturnedFromScrapFlag();
}
recycleViewHolderInternal(holder);
}
holder = null;
}
}
}
if (holder == null) {
offsetPosition = RecyclerView.this.mAdapterHelper.findPositionOffset(position);
if (offsetPosition < 0 || offsetPosition >= RecyclerView.this.mAdapter.getItemCount()) {
throw new IndexOutOfBoundsException("Inconsistency detected. Invalid item position " + position + "(offset:" + offsetPosition + ")." + "state:" + RecyclerView.this.mState.getItemCount());
}
int type = RecyclerView.this.mAdapter.getItemViewType(offsetPosition);
if (RecyclerView.this.mAdapter.hasStableIds()) {
holder = getScrapViewForId(RecyclerView.this.mAdapter.getItemId(offsetPosition), type, dryRun);
if (holder != null) {
holder.mPosition = offsetPosition;
fromScrap = true;
}
}
if (holder == null && this.mViewCacheExtension != null) {
View view = this.mViewCacheExtension.getViewForPositionAndType(this, position, type);
if (view != null) {
holder = RecyclerView.this.getChildViewHolder(view);
if (holder == null) {
throw new IllegalArgumentException("getViewForPositionAndType returned a view which does not have a ViewHolder");
} else if (holder.shouldIgnore()) {
throw new IllegalArgumentException("getViewForPositionAndType returned a view that is ignored. You must call stopIgnoring before returning this view.");
}
}
}
if (holder == null) {
holder = getRecycledViewPool().getRecycledView(type);
if (holder != null) {
holder.resetInternal();
if (RecyclerView.FORCE_INVALIDATE_DISPLAY_LIST) {
invalidateDisplayListInt(holder);
}
}
}
if (holder == null) {
holder = RecyclerView.this.mAdapter.createViewHolder(RecyclerView.this, type);
}
}
if (fromScrap && !RecyclerView.this.mState.isPreLayout() && holder.hasAnyOfTheFlags(8192)) {
holder.setFlags(0, 8192);
if (RecyclerView.this.mState.mRunSimpleAnimations) {
RecyclerView.this.recordAnimationInfoIfBouncedHiddenView(holder, RecyclerView.this.mItemAnimator.recordPreLayoutInformation(RecyclerView.this.mState, holder, ItemAnimator.buildAdapterChangeFlagsForAnimations(holder) | 4096, holder.getUnmodifiedPayloads()));
}
}
boolean bound = false;
if (RecyclerView.this.mState.isPreLayout() && holder.isBound()) {
holder.mPreLayoutPosition = position;
} else if (!holder.isBound() || holder.needsUpdate() || holder.isInvalid()) {
offsetPosition = RecyclerView.this.mAdapterHelper.findPositionOffset(position);
holder.mOwnerRecyclerView = RecyclerView.this;
RecyclerView.this.mAdapter.bindViewHolder(holder, offsetPosition);
attachAccessibilityDelegate(holder.itemView);
bound = true;
if (RecyclerView.this.mState.isPreLayout()) {
holder.mPreLayoutPosition = position;
}
}
android.view.ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if (lp == null) {
rvLayoutParams = (LayoutParams) RecyclerView.this.generateDefaultLayoutParams();
holder.itemView.setLayoutParams(rvLayoutParams);
} else if (RecyclerView.this.checkLayoutParams(lp)) {
rvLayoutParams = (LayoutParams) lp;
} else {
rvLayoutParams = (LayoutParams) RecyclerView.this.generateLayoutParams(lp);
holder.itemView.setLayoutParams(rvLayoutParams);
}
rvLayoutParams.mViewHolder = holder;
boolean z = fromScrap && bound;
rvLayoutParams.mPendingInvalidate = z;
return holder.itemView;
}
private void attachAccessibilityDelegate(View itemView) {
if (RecyclerView.this.isAccessibilityEnabled()) {
if (ViewCompat.getImportantForAccessibility(itemView) == 0) {
ViewCompat.setImportantForAccessibility(itemView, 1);
}
if (!ViewCompat.hasAccessibilityDelegate(itemView)) {
ViewCompat.setAccessibilityDelegate(itemView, RecyclerView.this.mAccessibilityDelegate.getItemDelegate());
}
}
}
private void invalidateDisplayListInt(ViewHolder holder) {
if (holder.itemView instanceof ViewGroup) {
invalidateDisplayListInt((ViewGroup) holder.itemView, false);
}
}
private void invalidateDisplayListInt(ViewGroup viewGroup, boolean invalidateThis) {
for (int i = viewGroup.getChildCount() - 1; i >= 0; i--) {
View view = viewGroup.getChildAt(i);
if (view instanceof ViewGroup) {
invalidateDisplayListInt((ViewGroup) view, true);
}
}
if (!invalidateThis) {
return;
}
if (viewGroup.getVisibility() == 4) {
viewGroup.setVisibility(0);
viewGroup.setVisibility(4);
return;
}
int visibility = viewGroup.getVisibility();
viewGroup.setVisibility(4);
viewGroup.setVisibility(visibility);
}
public void recycleView(View view) {
ViewHolder holder = RecyclerView.getChildViewHolderInt(view);
if (holder.isTmpDetached()) {
RecyclerView.this.removeDetachedView(view, false);
}
if (holder.isScrap()) {
holder.unScrap();
} else if (holder.wasReturnedFromScrap()) {
holder.clearReturnedFromScrapFlag();
}
recycleViewHolderInternal(holder);
}
void recycleViewInternal(View view) {
recycleViewHolderInternal(RecyclerView.getChildViewHolderInt(view));
}
void recycleAndClearCachedViews() {
for (int i = this.mCachedViews.size() - 1; i >= 0; i--) {
recycleCachedViewAt(i);
}
this.mCachedViews.clear();
}
void recycleCachedViewAt(int cachedViewIndex) {
addViewHolderToRecycledViewPool((ViewHolder) this.mCachedViews.get(cachedViewIndex));
this.mCachedViews.remove(cachedViewIndex);
}
void recycleViewHolderInternal(ViewHolder holder) {
boolean z = true;
if (holder.isScrap() || holder.itemView.getParent() != null) {
StringBuilder append = new StringBuilder().append("Scrapped or attached views may not be recycled. isScrap:").append(holder.isScrap()).append(" isAttached:");
if (holder.itemView.getParent() == null) {
z = false;
}
throw new IllegalArgumentException(append.append(z).toString());
} else if (holder.isTmpDetached()) {
throw new IllegalArgumentException("Tmp detached view should be removed from RecyclerView before it can be recycled: " + holder);
} else if (holder.shouldIgnore()) {
throw new IllegalArgumentException("Trying to recycle an ignored view holder. You should first call stopIgnoringView(view) before calling recycle.");
} else {
boolean forceRecycle;
boolean transientStatePreventsRecycling = holder.doesTransientStatePreventRecycling();
if (RecyclerView.this.mAdapter != null && transientStatePreventsRecycling && RecyclerView.this.mAdapter.onFailedToRecycleView(holder)) {
forceRecycle = true;
} else {
forceRecycle = false;
}
boolean cached = false;
boolean recycled = false;
if (forceRecycle || holder.isRecyclable()) {
if (!holder.hasAnyOfTheFlags(14)) {
int cachedViewSize = this.mCachedViews.size();
if (cachedViewSize == this.mViewCacheMax && cachedViewSize > 0) {
recycleCachedViewAt(0);
}
if (cachedViewSize < this.mViewCacheMax) {
this.mCachedViews.add(holder);
cached = true;
}
}
if (!cached) {
addViewHolderToRecycledViewPool(holder);
recycled = true;
}
}
RecyclerView.this.mViewInfoStore.removeViewHolder(holder);
if (!cached && !recycled && transientStatePreventsRecycling) {
holder.mOwnerRecyclerView = null;
}
}
}
void addViewHolderToRecycledViewPool(ViewHolder holder) {
ViewCompat.setAccessibilityDelegate(holder.itemView, null);
dispatchViewRecycled(holder);
holder.mOwnerRecyclerView = null;
getRecycledViewPool().putRecycledView(holder);
}
void quickRecycleScrapView(View view) {
ViewHolder holder = RecyclerView.getChildViewHolderInt(view);
holder.mScrapContainer = null;
holder.mInChangeScrap = false;
holder.clearReturnedFromScrapFlag();
recycleViewHolderInternal(holder);
}
void scrapView(View view) {
ViewHolder holder = RecyclerView.getChildViewHolderInt(view);
if (holder.isUpdated() && !holder.isInvalid() && !RecyclerView.this.canReuseUpdatedViewHolder(holder)) {
if (this.mChangedScrap == null) {
this.mChangedScrap = new ArrayList();
}
holder.setScrapContainer(this, true);
this.mChangedScrap.add(holder);
} else if (!holder.isInvalid() || holder.isRemoved() || RecyclerView.this.mAdapter.hasStableIds()) {
holder.setScrapContainer(this, false);
this.mAttachedScrap.add(holder);
} else {
throw new IllegalArgumentException("Called scrap view with an invalid view. Invalid views cannot be reused from scrap, they should rebound from recycler pool.");
}
}
void unscrapView(ViewHolder holder) {
if (holder.mInChangeScrap) {
this.mChangedScrap.remove(holder);
} else {
this.mAttachedScrap.remove(holder);
}
holder.mScrapContainer = null;
holder.mInChangeScrap = false;
holder.clearReturnedFromScrapFlag();
}
int getScrapCount() {
return this.mAttachedScrap.size();
}
View getScrapViewAt(int index) {
return ((ViewHolder) this.mAttachedScrap.get(index)).itemView;
}
void clearScrap() {
this.mAttachedScrap.clear();
if (this.mChangedScrap != null) {
this.mChangedScrap.clear();
}
}
ViewHolder getChangedScrapViewForPosition(int position) {
if (this.mChangedScrap != null) {
int changedScrapSize = this.mChangedScrap.size();
if (changedScrapSize != 0) {
ViewHolder holder;
int i = 0;
while (i < changedScrapSize) {
holder = (ViewHolder) this.mChangedScrap.get(i);
if (holder.wasReturnedFromScrap() || holder.getLayoutPosition() != position) {
i++;
} else {
holder.addFlags(32);
return holder;
}
}
if (RecyclerView.this.mAdapter.hasStableIds()) {
int offsetPosition = RecyclerView.this.mAdapterHelper.findPositionOffset(position);
if (offsetPosition > 0 && offsetPosition < RecyclerView.this.mAdapter.getItemCount()) {
long id = RecyclerView.this.mAdapter.getItemId(offsetPosition);
i = 0;
while (i < changedScrapSize) {
holder = (ViewHolder) this.mChangedScrap.get(i);
if (holder.wasReturnedFromScrap() || holder.getItemId() != id) {
i++;
} else {
holder.addFlags(32);
return holder;
}
}
}
}
return null;
}
}
return null;
}
ViewHolder getScrapViewForPosition(int position, int type, boolean dryRun) {
int cacheSize;
int scrapCount = this.mAttachedScrap.size();
int i = 0;
while (i < scrapCount) {
View view;
ViewHolder vh;
int layoutIndex;
ViewHolder holder = (ViewHolder) this.mAttachedScrap.get(i);
if (holder.wasReturnedFromScrap() || holder.getLayoutPosition() != position || holder.isInvalid() || (!RecyclerView.this.mState.mInPreLayout && holder.isRemoved())) {
i++;
} else if (type == -1 || holder.getItemViewType() == type) {
holder.addFlags(32);
return holder;
} else {
Log.e(RecyclerView.TAG, "Scrap view for position " + position + " isn't dirty but has" + " wrong view type! (found " + holder.getItemViewType() + " but expected " + type + ")");
if (!dryRun) {
view = RecyclerView.this.mChildHelper.findHiddenNonRemovedView(position, type);
if (view != null) {
vh = RecyclerView.getChildViewHolderInt(view);
RecyclerView.this.mChildHelper.unhide(view);
layoutIndex = RecyclerView.this.mChildHelper.indexOfChild(view);
if (layoutIndex != -1) {
throw new IllegalStateException("layout index should not be -1 after unhiding a view:" + vh);
}
RecyclerView.this.mChildHelper.detachViewFromParent(layoutIndex);
scrapView(view);
vh.addFlags(8224);
return vh;
}
}
cacheSize = this.mCachedViews.size();
i = 0;
while (i < cacheSize) {
holder = (ViewHolder) this.mCachedViews.get(i);
if (holder.isInvalid() || holder.getLayoutPosition() != position) {
i++;
} else if (dryRun) {
return holder;
} else {
this.mCachedViews.remove(i);
return holder;
}
}
return null;
}
}
if (dryRun) {
view = RecyclerView.this.mChildHelper.findHiddenNonRemovedView(position, type);
if (view != null) {
vh = RecyclerView.getChildViewHolderInt(view);
RecyclerView.this.mChildHelper.unhide(view);
layoutIndex = RecyclerView.this.mChildHelper.indexOfChild(view);
if (layoutIndex != -1) {
RecyclerView.this.mChildHelper.detachViewFromParent(layoutIndex);
scrapView(view);
vh.addFlags(8224);
return vh;
}
throw new IllegalStateException("layout index should not be -1 after unhiding a view:" + vh);
}
}
cacheSize = this.mCachedViews.size();
i = 0;
while (i < cacheSize) {
holder = (ViewHolder) this.mCachedViews.get(i);
if (holder.isInvalid()) {
}
i++;
}
return null;
}
ViewHolder getScrapViewForId(long id, int type, boolean dryRun) {
int i;
for (i = this.mAttachedScrap.size() - 1; i >= 0; i--) {
ViewHolder holder = (ViewHolder) this.mAttachedScrap.get(i);
if (holder.getItemId() == id && !holder.wasReturnedFromScrap()) {
if (type == holder.getItemViewType()) {
holder.addFlags(32);
if (!holder.isRemoved() || RecyclerView.this.mState.isPreLayout()) {
return holder;
}
holder.setFlags(2, 14);
return holder;
} else if (!dryRun) {
this.mAttachedScrap.remove(i);
RecyclerView.this.removeDetachedView(holder.itemView, false);
quickRecycleScrapView(holder.itemView);
}
}
}
for (i = this.mCachedViews.size() - 1; i >= 0; i--) {
holder = (ViewHolder) this.mCachedViews.get(i);
if (holder.getItemId() == id) {
if (type == holder.getItemViewType()) {
if (dryRun) {
return holder;
}
this.mCachedViews.remove(i);
return holder;
} else if (!dryRun) {
recycleCachedViewAt(i);
}
}
}
return null;
}
void dispatchViewRecycled(ViewHolder holder) {
if (RecyclerView.this.mRecyclerListener != null) {
RecyclerView.this.mRecyclerListener.onViewRecycled(holder);
}
if (RecyclerView.this.mAdapter != null) {
RecyclerView.this.mAdapter.onViewRecycled(holder);
}
if (RecyclerView.this.mState != null) {
RecyclerView.this.mViewInfoStore.removeViewHolder(holder);
}
}
void onAdapterChanged(Adapter oldAdapter, Adapter newAdapter, boolean compatibleWithPrevious) {
clear();
getRecycledViewPool().onAdapterChanged(oldAdapter, newAdapter, compatibleWithPrevious);
}
void offsetPositionRecordsForMove(int from, int to) {
int inBetweenOffset;
int start;
int end;
if (from < to) {
start = from;
end = to;
inBetweenOffset = -1;
} else {
start = to;
end = from;
inBetweenOffset = 1;
}
int cachedCount = this.mCachedViews.size();
for (int i = 0; i < cachedCount; i++) {
ViewHolder holder = (ViewHolder) this.mCachedViews.get(i);
if (holder != null && holder.mPosition >= start && holder.mPosition <= end) {
if (holder.mPosition == from) {
holder.offsetPosition(to - from, false);
} else {
holder.offsetPosition(inBetweenOffset, false);
}
}
}
}
void offsetPositionRecordsForInsert(int insertedAt, int count) {
int cachedCount = this.mCachedViews.size();
for (int i = 0; i < cachedCount; i++) {
ViewHolder holder = (ViewHolder) this.mCachedViews.get(i);
if (holder != null && holder.getLayoutPosition() >= insertedAt) {
holder.offsetPosition(count, true);
}
}
}
void offsetPositionRecordsForRemove(int removedFrom, int count, boolean applyToPreLayout) {
int removedEnd = removedFrom + count;
for (int i = this.mCachedViews.size() - 1; i >= 0; i--) {
ViewHolder holder = (ViewHolder) this.mCachedViews.get(i);
if (holder != null) {
if (holder.getLayoutPosition() >= removedEnd) {
holder.offsetPosition(-count, applyToPreLayout);
} else if (holder.getLayoutPosition() >= removedFrom) {
holder.addFlags(8);
recycleCachedViewAt(i);
}
}
}
}
void setViewCacheExtension(ViewCacheExtension extension) {
this.mViewCacheExtension = extension;
}
void setRecycledViewPool(RecycledViewPool pool) {
if (this.mRecyclerPool != null) {
this.mRecyclerPool.detach();
}
this.mRecyclerPool = pool;
if (pool != null) {
this.mRecyclerPool.attach(RecyclerView.this.getAdapter());
}
}
RecycledViewPool getRecycledViewPool() {
if (this.mRecyclerPool == null) {
this.mRecyclerPool = new RecycledViewPool();
}
return this.mRecyclerPool;
}
void viewRangeUpdate(int positionStart, int itemCount) {
int positionEnd = positionStart + itemCount;
for (int i = this.mCachedViews.size() - 1; i >= 0; i--) {
ViewHolder holder = (ViewHolder) this.mCachedViews.get(i);
if (holder != null) {
int pos = holder.getLayoutPosition();
if (pos >= positionStart && pos < positionEnd) {
holder.addFlags(2);
recycleCachedViewAt(i);
}
}
}
}
void setAdapterPositionsAsUnknown() {
int cachedCount = this.mCachedViews.size();
for (int i = 0; i < cachedCount; i++) {
ViewHolder holder = (ViewHolder) this.mCachedViews.get(i);
if (holder != null) {
holder.addFlags(512);
}
}
}
void markKnownViewsInvalid() {
if (RecyclerView.this.mAdapter == null || !RecyclerView.this.mAdapter.hasStableIds()) {
recycleAndClearCachedViews();
return;
}
int cachedCount = this.mCachedViews.size();
for (int i = 0; i < cachedCount; i++) {
ViewHolder holder = (ViewHolder) this.mCachedViews.get(i);
if (holder != null) {
holder.addFlags(6);
holder.addChangePayload(null);
}
}
}
void clearOldPositions() {
int i;
int cachedCount = this.mCachedViews.size();
for (i = 0; i < cachedCount; i++) {
((ViewHolder) this.mCachedViews.get(i)).clearOldPosition();
}
int scrapCount = this.mAttachedScrap.size();
for (i = 0; i < scrapCount; i++) {
((ViewHolder) this.mAttachedScrap.get(i)).clearOldPosition();
}
if (this.mChangedScrap != null) {
int changedScrapCount = this.mChangedScrap.size();
for (i = 0; i < changedScrapCount; i++) {
((ViewHolder) this.mChangedScrap.get(i)).clearOldPosition();
}
}
}
void markItemDecorInsetsDirty() {
int cachedCount = this.mCachedViews.size();
for (int i = 0; i < cachedCount; i++) {
LayoutParams layoutParams = (LayoutParams) ((ViewHolder) this.mCachedViews.get(i)).itemView.getLayoutParams();
if (layoutParams != null) {
layoutParams.mInsetsDirty = true;
}
}
}
}
public interface RecyclerListener {
void onViewRecycled(ViewHolder viewHolder);
}
public static class SavedState extends BaseSavedState {
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
Parcelable mLayoutState;
SavedState(Parcel in) {
super(in);
this.mLayoutState = in.readParcelable(LayoutManager.class.getClassLoader());
}
SavedState(Parcelable superState) {
super(superState);
}
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeParcelable(this.mLayoutState, 0);
}
private void copyFrom(SavedState other) {
this.mLayoutState = other.mLayoutState;
}
}
public static abstract class SmoothScroller {
private LayoutManager mLayoutManager;
private boolean mPendingInitialRun;
private RecyclerView mRecyclerView;
private final Action mRecyclingAction = new Action(0, 0);
private boolean mRunning;
private int mTargetPosition = -1;
private View mTargetView;
public static class Action {
public static final int UNDEFINED_DURATION = Integer.MIN_VALUE;
private boolean changed;
private int consecutiveUpdates;
private int mDuration;
private int mDx;
private int mDy;
private Interpolator mInterpolator;
private int mJumpToPosition;
public Action(int dx, int dy) {
this(dx, dy, Integer.MIN_VALUE, null);
}
public Action(int dx, int dy, int duration) {
this(dx, dy, duration, null);
}
public Action(int dx, int dy, int duration, Interpolator interpolator) {
this.mJumpToPosition = -1;
this.changed = false;
this.consecutiveUpdates = 0;
this.mDx = dx;
this.mDy = dy;
this.mDuration = duration;
this.mInterpolator = interpolator;
}
public void jumpTo(int targetPosition) {
this.mJumpToPosition = targetPosition;
}
boolean hasJumpTarget() {
return this.mJumpToPosition >= 0;
}
private void runIfNecessary(RecyclerView recyclerView) {
if (this.mJumpToPosition >= 0) {
int position = this.mJumpToPosition;
this.mJumpToPosition = -1;
recyclerView.jumpToPositionForSmoothScroller(position);
this.changed = false;
} else if (this.changed) {
validate();
if (this.mInterpolator != null) {
recyclerView.mViewFlinger.smoothScrollBy(this.mDx, this.mDy, this.mDuration, this.mInterpolator);
} else if (this.mDuration == Integer.MIN_VALUE) {
recyclerView.mViewFlinger.smoothScrollBy(this.mDx, this.mDy);
} else {
recyclerView.mViewFlinger.smoothScrollBy(this.mDx, this.mDy, this.mDuration);
}
this.consecutiveUpdates++;
if (this.consecutiveUpdates > 10) {
Log.e(RecyclerView.TAG, "Smooth Scroll action is being updated too frequently. Make sure you are not changing it unless necessary");
}
this.changed = false;
} else {
this.consecutiveUpdates = 0;
}
}
private void validate() {
if (this.mInterpolator != null && this.mDuration < 1) {
throw new IllegalStateException("If you provide an interpolator, you must set a positive duration");
} else if (this.mDuration < 1) {
throw new IllegalStateException("Scroll duration must be a positive number");
}
}
public int getDx() {
return this.mDx;
}
public void setDx(int dx) {
this.changed = true;
this.mDx = dx;
}
public int getDy() {
return this.mDy;
}
public void setDy(int dy) {
this.changed = true;
this.mDy = dy;
}
public int getDuration() {
return this.mDuration;
}
public void setDuration(int duration) {
this.changed = true;
this.mDuration = duration;
}
public Interpolator getInterpolator() {
return this.mInterpolator;
}
public void setInterpolator(Interpolator interpolator) {
this.changed = true;
this.mInterpolator = interpolator;
}
public void update(int dx, int dy, int duration, Interpolator interpolator) {
this.mDx = dx;
this.mDy = dy;
this.mDuration = duration;
this.mInterpolator = interpolator;
this.changed = true;
}
}
protected abstract void onSeekTargetStep(int i, int i2, State state, Action action);
protected abstract void onStart();
protected abstract void onStop();
protected abstract void onTargetFound(View view, State state, Action action);
void start(RecyclerView recyclerView, LayoutManager layoutManager) {
this.mRecyclerView = recyclerView;
this.mLayoutManager = layoutManager;
if (this.mTargetPosition == -1) {
throw new IllegalArgumentException("Invalid target position");
}
this.mRecyclerView.mState.mTargetPosition = this.mTargetPosition;
this.mRunning = true;
this.mPendingInitialRun = true;
this.mTargetView = findViewByPosition(getTargetPosition());
onStart();
this.mRecyclerView.mViewFlinger.postOnAnimation();
}
public void setTargetPosition(int targetPosition) {
this.mTargetPosition = targetPosition;
}
@Nullable
public LayoutManager getLayoutManager() {
return this.mLayoutManager;
}
protected final void stop() {
if (this.mRunning) {
onStop();
this.mRecyclerView.mState.mTargetPosition = -1;
this.mTargetView = null;
this.mTargetPosition = -1;
this.mPendingInitialRun = false;
this.mRunning = false;
this.mLayoutManager.onSmoothScrollerStopped(this);
this.mLayoutManager = null;
this.mRecyclerView = null;
}
}
public boolean isPendingInitialRun() {
return this.mPendingInitialRun;
}
public boolean isRunning() {
return this.mRunning;
}
public int getTargetPosition() {
return this.mTargetPosition;
}
private void onAnimation(int dx, int dy) {
RecyclerView recyclerView = this.mRecyclerView;
if (!this.mRunning || this.mTargetPosition == -1 || recyclerView == null) {
stop();
}
this.mPendingInitialRun = false;
if (this.mTargetView != null) {
if (getChildPosition(this.mTargetView) == this.mTargetPosition) {
onTargetFound(this.mTargetView, recyclerView.mState, this.mRecyclingAction);
this.mRecyclingAction.runIfNecessary(recyclerView);
stop();
} else {
Log.e(RecyclerView.TAG, "Passed over target position while smooth scrolling.");
this.mTargetView = null;
}
}
if (this.mRunning) {
onSeekTargetStep(dx, dy, recyclerView.mState, this.mRecyclingAction);
boolean hadJumpTarget = this.mRecyclingAction.hasJumpTarget();
this.mRecyclingAction.runIfNecessary(recyclerView);
if (!hadJumpTarget) {
return;
}
if (this.mRunning) {
this.mPendingInitialRun = true;
recyclerView.mViewFlinger.postOnAnimation();
return;
}
stop();
}
}
public int getChildPosition(View view) {
return this.mRecyclerView.getChildLayoutPosition(view);
}
public int getChildCount() {
return this.mRecyclerView.mLayout.getChildCount();
}
public View findViewByPosition(int position) {
return this.mRecyclerView.mLayout.findViewByPosition(position);
}
@Deprecated
public void instantScrollToPosition(int position) {
this.mRecyclerView.scrollToPosition(position);
}
protected void onChildAttachedToWindow(View child) {
if (getChildPosition(child) == getTargetPosition()) {
this.mTargetView = child;
}
}
protected void normalize(PointF scrollVector) {
double magnitute = Math.sqrt((double) ((scrollVector.x * scrollVector.x) + (scrollVector.y * scrollVector.y)));
scrollVector.x = (float) (((double) scrollVector.x) / magnitute);
scrollVector.y = (float) (((double) scrollVector.y) / magnitute);
}
}
public static class State {
private SparseArray<Object> mData;
private int mDeletedInvisibleItemCountSincePreviousLayout = 0;
private boolean mInPreLayout = false;
int mItemCount = 0;
private int mPreviousLayoutItemCount = 0;
private boolean mRunPredictiveAnimations = false;
private boolean mRunSimpleAnimations = false;
private boolean mStructureChanged = false;
private int mTargetPosition = -1;
private boolean mTrackOldChangeHolders = false;
static /* synthetic */ int access$1812(State x0, int x1) {
int i = x0.mDeletedInvisibleItemCountSincePreviousLayout + x1;
x0.mDeletedInvisibleItemCountSincePreviousLayout = i;
return i;
}
State reset() {
this.mTargetPosition = -1;
if (this.mData != null) {
this.mData.clear();
}
this.mItemCount = 0;
this.mStructureChanged = false;
return this;
}
public boolean isPreLayout() {
return this.mInPreLayout;
}
public boolean willRunPredictiveAnimations() {
return this.mRunPredictiveAnimations;
}
public boolean willRunSimpleAnimations() {
return this.mRunSimpleAnimations;
}
public void remove(int resourceId) {
if (this.mData != null) {
this.mData.remove(resourceId);
}
}
public <T> T get(int resourceId) {
if (this.mData == null) {
return null;
}
return this.mData.get(resourceId);
}
public void put(int resourceId, Object data) {
if (this.mData == null) {
this.mData = new SparseArray();
}
this.mData.put(resourceId, data);
}
public int getTargetScrollPosition() {
return this.mTargetPosition;
}
public boolean hasTargetScrollPosition() {
return this.mTargetPosition != -1;
}
public boolean didStructureChange() {
return this.mStructureChanged;
}
public int getItemCount() {
return this.mInPreLayout ? this.mPreviousLayoutItemCount - this.mDeletedInvisibleItemCountSincePreviousLayout : this.mItemCount;
}
public String toString() {
return "State{mTargetPosition=" + this.mTargetPosition + ", mData=" + this.mData + ", mItemCount=" + this.mItemCount + ", mPreviousLayoutItemCount=" + this.mPreviousLayoutItemCount + ", mDeletedInvisibleItemCountSincePreviousLayout=" + this.mDeletedInvisibleItemCountSincePreviousLayout + ", mStructureChanged=" + this.mStructureChanged + ", mInPreLayout=" + this.mInPreLayout + ", mRunSimpleAnimations=" + this.mRunSimpleAnimations + ", mRunPredictiveAnimations=" + this.mRunPredictiveAnimations + '}';
}
}
public static abstract class ViewCacheExtension {
public abstract View getViewForPositionAndType(Recycler recycler, int i, int i2);
}
private class ViewFlinger implements Runnable {
private boolean mEatRunOnAnimationRequest = false;
private Interpolator mInterpolator = RecyclerView.sQuinticInterpolator;
private int mLastFlingX;
private int mLastFlingY;
private boolean mReSchedulePostAnimationCallback = false;
private ScrollerCompat mScroller;
public ViewFlinger() {
this.mScroller = ScrollerCompat.create(RecyclerView.this.getContext(), RecyclerView.sQuinticInterpolator);
}
public void run() {
disableRunOnAnimationRequests();
RecyclerView.this.consumePendingUpdateOperations();
ScrollerCompat scroller = this.mScroller;
SmoothScroller smoothScroller = RecyclerView.this.mLayout.mSmoothScroller;
if (scroller.computeScrollOffset()) {
int x = scroller.getCurrX();
int y = scroller.getCurrY();
int dx = x - this.mLastFlingX;
int dy = y - this.mLastFlingY;
int hresult = 0;
int vresult = 0;
this.mLastFlingX = x;
this.mLastFlingY = y;
int overscrollX = 0;
int overscrollY = 0;
if (RecyclerView.this.mAdapter != null) {
RecyclerView.this.eatRequestLayout();
RecyclerView.this.onEnterLayoutOrScroll();
TraceCompat.beginSection(RecyclerView.TRACE_SCROLL_TAG);
if (dx != 0) {
hresult = RecyclerView.this.mLayout.scrollHorizontallyBy(dx, RecyclerView.this.mRecycler, RecyclerView.this.mState);
overscrollX = dx - hresult;
}
if (dy != 0) {
vresult = RecyclerView.this.mLayout.scrollVerticallyBy(dy, RecyclerView.this.mRecycler, RecyclerView.this.mState);
overscrollY = dy - vresult;
}
TraceCompat.endSection();
RecyclerView.this.repositionShadowingViews();
RecyclerView.this.onExitLayoutOrScroll();
RecyclerView.this.resumeRequestLayout(false);
if (!(smoothScroller == null || smoothScroller.isPendingInitialRun() || !smoothScroller.isRunning())) {
int adapterSize = RecyclerView.this.mState.getItemCount();
if (adapterSize == 0) {
smoothScroller.stop();
} else if (smoothScroller.getTargetPosition() >= adapterSize) {
smoothScroller.setTargetPosition(adapterSize - 1);
smoothScroller.onAnimation(dx - overscrollX, dy - overscrollY);
} else {
smoothScroller.onAnimation(dx - overscrollX, dy - overscrollY);
}
}
}
if (!RecyclerView.this.mItemDecorations.isEmpty()) {
RecyclerView.this.invalidate();
}
if (ViewCompat.getOverScrollMode(RecyclerView.this) != 2) {
RecyclerView.this.considerReleasingGlowsOnScroll(dx, dy);
}
if (!(overscrollX == 0 && overscrollY == 0)) {
int vel = (int) scroller.getCurrVelocity();
int velX = 0;
if (overscrollX != x) {
velX = overscrollX < 0 ? -vel : overscrollX > 0 ? vel : 0;
}
int velY = 0;
if (overscrollY != y) {
velY = overscrollY < 0 ? -vel : overscrollY > 0 ? vel : 0;
}
if (ViewCompat.getOverScrollMode(RecyclerView.this) != 2) {
RecyclerView.this.absorbGlows(velX, velY);
}
if ((velX != 0 || overscrollX == x || scroller.getFinalX() == 0) && (velY != 0 || overscrollY == y || scroller.getFinalY() == 0)) {
scroller.abortAnimation();
}
}
if (!(hresult == 0 && vresult == 0)) {
RecyclerView.this.dispatchOnScrolled(hresult, vresult);
}
if (!RecyclerView.this.awakenScrollBars()) {
RecyclerView.this.invalidate();
}
boolean fullyConsumedVertical = dy != 0 && RecyclerView.this.mLayout.canScrollVertically() && vresult == dy;
boolean fullyConsumedHorizontal = dx != 0 && RecyclerView.this.mLayout.canScrollHorizontally() && hresult == dx;
boolean fullyConsumedAny = (dx == 0 && dy == 0) || fullyConsumedHorizontal || fullyConsumedVertical;
if (scroller.isFinished() || !fullyConsumedAny) {
RecyclerView.this.setScrollState(0);
} else {
postOnAnimation();
}
}
if (smoothScroller != null) {
if (smoothScroller.isPendingInitialRun()) {
smoothScroller.onAnimation(0, 0);
}
if (!this.mReSchedulePostAnimationCallback) {
smoothScroller.stop();
}
}
enableRunOnAnimationRequests();
}
private void disableRunOnAnimationRequests() {
this.mReSchedulePostAnimationCallback = false;
this.mEatRunOnAnimationRequest = true;
}
private void enableRunOnAnimationRequests() {
this.mEatRunOnAnimationRequest = false;
if (this.mReSchedulePostAnimationCallback) {
postOnAnimation();
}
}
void postOnAnimation() {
if (this.mEatRunOnAnimationRequest) {
this.mReSchedulePostAnimationCallback = true;
return;
}
RecyclerView.this.removeCallbacks(this);
ViewCompat.postOnAnimation(RecyclerView.this, this);
}
public void fling(int velocityX, int velocityY) {
RecyclerView.this.setScrollState(2);
this.mLastFlingY = 0;
this.mLastFlingX = 0;
this.mScroller.fling(0, 0, velocityX, velocityY, Integer.MIN_VALUE, ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED, Integer.MIN_VALUE, ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED);
postOnAnimation();
}
public void smoothScrollBy(int dx, int dy) {
smoothScrollBy(dx, dy, 0, 0);
}
public void smoothScrollBy(int dx, int dy, int vx, int vy) {
smoothScrollBy(dx, dy, computeScrollDuration(dx, dy, vx, vy));
}
private float distanceInfluenceForSnapDuration(float f) {
return (float) Math.sin((double) ((float) (((double) (f - 0.5f)) * 0.4712389167638204d)));
}
private int computeScrollDuration(int dx, int dy, int vx, int vy) {
int duration;
int absDx = Math.abs(dx);
int absDy = Math.abs(dy);
boolean horizontal = absDx > absDy;
int velocity = (int) Math.sqrt((double) ((vx * vx) + (vy * vy)));
int delta = (int) Math.sqrt((double) ((dx * dx) + (dy * dy)));
int containerSize = horizontal ? RecyclerView.this.getWidth() : RecyclerView.this.getHeight();
int halfContainerSize = containerSize / 2;
float distance = ((float) halfContainerSize) + (((float) halfContainerSize) * distanceInfluenceForSnapDuration(Math.min(1.0f, (1.0f * ((float) delta)) / ((float) containerSize))));
if (velocity > 0) {
duration = Math.round(1000.0f * Math.abs(distance / ((float) velocity))) * 4;
} else {
if (!horizontal) {
absDx = absDy;
}
duration = (int) (((((float) absDx) / ((float) containerSize)) + 1.0f) * 300.0f);
}
return Math.min(duration, RecyclerView.MAX_SCROLL_DURATION);
}
public void smoothScrollBy(int dx, int dy, int duration) {
smoothScrollBy(dx, dy, duration, RecyclerView.sQuinticInterpolator);
}
public void smoothScrollBy(int dx, int dy, int duration, Interpolator interpolator) {
if (this.mInterpolator != interpolator) {
this.mInterpolator = interpolator;
this.mScroller = ScrollerCompat.create(RecyclerView.this.getContext(), interpolator);
}
RecyclerView.this.setScrollState(2);
this.mLastFlingY = 0;
this.mLastFlingX = 0;
this.mScroller.startScroll(0, 0, dx, dy, duration);
postOnAnimation();
}
public void stop() {
RecyclerView.this.removeCallbacks(this);
this.mScroller.abortAnimation();
}
}
public static abstract class ViewHolder {
static final int FLAG_ADAPTER_FULLUPDATE = 1024;
static final int FLAG_ADAPTER_POSITION_UNKNOWN = 512;
static final int FLAG_APPEARED_IN_PRE_LAYOUT = 4096;
static final int FLAG_BOUNCED_FROM_HIDDEN_LIST = 8192;
static final int FLAG_BOUND = 1;
static final int FLAG_IGNORE = 128;
static final int FLAG_INVALID = 4;
static final int FLAG_MOVED = 2048;
static final int FLAG_NOT_RECYCLABLE = 16;
static final int FLAG_REMOVED = 8;
static final int FLAG_RETURNED_FROM_SCRAP = 32;
static final int FLAG_TMP_DETACHED = 256;
static final int FLAG_UPDATE = 2;
private static final List<Object> FULLUPDATE_PAYLOADS = Collections.EMPTY_LIST;
public final View itemView;
private int mFlags;
private boolean mInChangeScrap = false;
private int mIsRecyclableCount = 0;
long mItemId = -1;
int mItemViewType = -1;
int mOldPosition = -1;
RecyclerView mOwnerRecyclerView;
List<Object> mPayloads = null;
int mPosition = -1;
int mPreLayoutPosition = -1;
private Recycler mScrapContainer = null;
ViewHolder mShadowedHolder = null;
ViewHolder mShadowingHolder = null;
List<Object> mUnmodifiedPayloads = null;
private int mWasImportantForAccessibilityBeforeHidden = 0;
public ViewHolder(View itemView) {
if (itemView == null) {
throw new IllegalArgumentException("itemView may not be null");
}
this.itemView = itemView;
}
void flagRemovedAndOffsetPosition(int mNewPosition, int offset, boolean applyToPreLayout) {
addFlags(8);
offsetPosition(offset, applyToPreLayout);
this.mPosition = mNewPosition;
}
void offsetPosition(int offset, boolean applyToPreLayout) {
if (this.mOldPosition == -1) {
this.mOldPosition = this.mPosition;
}
if (this.mPreLayoutPosition == -1) {
this.mPreLayoutPosition = this.mPosition;
}
if (applyToPreLayout) {
this.mPreLayoutPosition += offset;
}
this.mPosition += offset;
if (this.itemView.getLayoutParams() != null) {
((LayoutParams) this.itemView.getLayoutParams()).mInsetsDirty = true;
}
}
void clearOldPosition() {
this.mOldPosition = -1;
this.mPreLayoutPosition = -1;
}
void saveOldPosition() {
if (this.mOldPosition == -1) {
this.mOldPosition = this.mPosition;
}
}
boolean shouldIgnore() {
return (this.mFlags & 128) != 0;
}
@Deprecated
public final int getPosition() {
return this.mPreLayoutPosition == -1 ? this.mPosition : this.mPreLayoutPosition;
}
public final int getLayoutPosition() {
return this.mPreLayoutPosition == -1 ? this.mPosition : this.mPreLayoutPosition;
}
public final int getAdapterPosition() {
if (this.mOwnerRecyclerView == null) {
return -1;
}
return this.mOwnerRecyclerView.getAdapterPositionFor(this);
}
public final int getOldPosition() {
return this.mOldPosition;
}
public final long getItemId() {
return this.mItemId;
}
public final int getItemViewType() {
return this.mItemViewType;
}
boolean isScrap() {
return this.mScrapContainer != null;
}
void unScrap() {
this.mScrapContainer.unscrapView(this);
}
boolean wasReturnedFromScrap() {
return (this.mFlags & 32) != 0;
}
void clearReturnedFromScrapFlag() {
this.mFlags &= -33;
}
void clearTmpDetachFlag() {
this.mFlags &= -257;
}
void stopIgnoring() {
this.mFlags &= -129;
}
void setScrapContainer(Recycler recycler, boolean isChangeScrap) {
this.mScrapContainer = recycler;
this.mInChangeScrap = isChangeScrap;
}
boolean isInvalid() {
return (this.mFlags & 4) != 0;
}
boolean needsUpdate() {
return (this.mFlags & 2) != 0;
}
boolean isBound() {
return (this.mFlags & 1) != 0;
}
boolean isRemoved() {
return (this.mFlags & 8) != 0;
}
boolean hasAnyOfTheFlags(int flags) {
return (this.mFlags & flags) != 0;
}
boolean isTmpDetached() {
return (this.mFlags & 256) != 0;
}
boolean isAdapterPositionUnknown() {
return (this.mFlags & 512) != 0 || isInvalid();
}
void setFlags(int flags, int mask) {
this.mFlags = (this.mFlags & (mask ^ -1)) | (flags & mask);
}
void addFlags(int flags) {
this.mFlags |= flags;
}
void addChangePayload(Object payload) {
if (payload == null) {
addFlags(1024);
} else if ((this.mFlags & 1024) == 0) {
createPayloadsIfNeeded();
this.mPayloads.add(payload);
}
}
private void createPayloadsIfNeeded() {
if (this.mPayloads == null) {
this.mPayloads = new ArrayList();
this.mUnmodifiedPayloads = Collections.unmodifiableList(this.mPayloads);
}
}
void clearPayload() {
if (this.mPayloads != null) {
this.mPayloads.clear();
}
this.mFlags &= -1025;
}
List<Object> getUnmodifiedPayloads() {
if ((this.mFlags & 1024) != 0) {
return FULLUPDATE_PAYLOADS;
}
if (this.mPayloads == null || this.mPayloads.size() == 0) {
return FULLUPDATE_PAYLOADS;
}
return this.mUnmodifiedPayloads;
}
void resetInternal() {
this.mFlags = 0;
this.mPosition = -1;
this.mOldPosition = -1;
this.mItemId = -1;
this.mPreLayoutPosition = -1;
this.mIsRecyclableCount = 0;
this.mShadowedHolder = null;
this.mShadowingHolder = null;
clearPayload();
this.mWasImportantForAccessibilityBeforeHidden = 0;
}
private void onEnteredHiddenState() {
this.mWasImportantForAccessibilityBeforeHidden = ViewCompat.getImportantForAccessibility(this.itemView);
ViewCompat.setImportantForAccessibility(this.itemView, 4);
}
private void onLeftHiddenState() {
ViewCompat.setImportantForAccessibility(this.itemView, this.mWasImportantForAccessibilityBeforeHidden);
this.mWasImportantForAccessibilityBeforeHidden = 0;
}
public String toString() {
StringBuilder sb = new StringBuilder("ViewHolder{" + Integer.toHexString(hashCode()) + " position=" + this.mPosition + " id=" + this.mItemId + ", oldPos=" + this.mOldPosition + ", pLpos:" + this.mPreLayoutPosition);
if (isScrap()) {
sb.append(" scrap ").append(this.mInChangeScrap ? "[changeScrap]" : "[attachedScrap]");
}
if (isInvalid()) {
sb.append(" invalid");
}
if (!isBound()) {
sb.append(" unbound");
}
if (needsUpdate()) {
sb.append(" update");
}
if (isRemoved()) {
sb.append(" removed");
}
if (shouldIgnore()) {
sb.append(" ignored");
}
if (isTmpDetached()) {
sb.append(" tmpDetached");
}
if (!isRecyclable()) {
sb.append(" not recyclable(" + this.mIsRecyclableCount + ")");
}
if (isAdapterPositionUnknown()) {
sb.append(" undefined adapter position");
}
if (this.itemView.getParent() == null) {
sb.append(" no parent");
}
sb.append("}");
return sb.toString();
}
public final void setIsRecyclable(boolean recyclable) {
this.mIsRecyclableCount = recyclable ? this.mIsRecyclableCount - 1 : this.mIsRecyclableCount + 1;
if (this.mIsRecyclableCount < 0) {
this.mIsRecyclableCount = 0;
Log.e("View", "isRecyclable decremented below 0: unmatched pair of setIsRecyable() calls for " + this);
} else if (!recyclable && this.mIsRecyclableCount == 1) {
this.mFlags |= 16;
} else if (recyclable && this.mIsRecyclableCount == 0) {
this.mFlags &= -17;
}
}
public final boolean isRecyclable() {
return (this.mFlags & 16) == 0 && !ViewCompat.hasTransientState(this.itemView);
}
private boolean shouldBeKeptAsChild() {
return (this.mFlags & 16) != 0;
}
private boolean doesTransientStatePreventRecycling() {
return (this.mFlags & 16) == 0 && ViewCompat.hasTransientState(this.itemView);
}
boolean isUpdated() {
return (this.mFlags & 2) != 0;
}
}
private class ItemAnimatorRestoreListener implements ItemAnimatorListener {
private ItemAnimatorRestoreListener() {
}
public void onAnimationFinished(ViewHolder item) {
item.setIsRecyclable(true);
if (item.mShadowedHolder != null && item.mShadowingHolder == null) {
item.mShadowedHolder = null;
}
item.mShadowingHolder = null;
if (!item.shouldBeKeptAsChild() && !RecyclerView.this.removeAnimatingView(item.itemView) && item.isTmpDetached()) {
RecyclerView.this.removeDetachedView(item.itemView, false);
}
}
}
private class RecyclerViewDataObserver extends AdapterDataObserver {
private RecyclerViewDataObserver() {
}
public void onChanged() {
RecyclerView.this.assertNotInLayoutOrScroll(null);
if (RecyclerView.this.mAdapter.hasStableIds()) {
RecyclerView.this.mState.mStructureChanged = true;
RecyclerView.this.setDataSetChangedAfterLayout();
} else {
RecyclerView.this.mState.mStructureChanged = true;
RecyclerView.this.setDataSetChangedAfterLayout();
}
if (!RecyclerView.this.mAdapterHelper.hasPendingUpdates()) {
RecyclerView.this.requestLayout();
}
}
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
RecyclerView.this.assertNotInLayoutOrScroll(null);
if (RecyclerView.this.mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)) {
triggerUpdateProcessor();
}
}
public void onItemRangeInserted(int positionStart, int itemCount) {
RecyclerView.this.assertNotInLayoutOrScroll(null);
if (RecyclerView.this.mAdapterHelper.onItemRangeInserted(positionStart, itemCount)) {
triggerUpdateProcessor();
}
}
public void onItemRangeRemoved(int positionStart, int itemCount) {
RecyclerView.this.assertNotInLayoutOrScroll(null);
if (RecyclerView.this.mAdapterHelper.onItemRangeRemoved(positionStart, itemCount)) {
triggerUpdateProcessor();
}
}
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
RecyclerView.this.assertNotInLayoutOrScroll(null);
if (RecyclerView.this.mAdapterHelper.onItemRangeMoved(fromPosition, toPosition, itemCount)) {
triggerUpdateProcessor();
}
}
void triggerUpdateProcessor() {
if (RecyclerView.this.mPostUpdatesOnAnimation && RecyclerView.this.mHasFixedSize && RecyclerView.this.mIsAttached) {
ViewCompat.postOnAnimation(RecyclerView.this, RecyclerView.this.mUpdateChildViewsRunnable);
return;
}
RecyclerView.this.mAdapterUpdateDuringMeasure = true;
RecyclerView.this.requestLayout();
}
}
public static class SimpleOnItemTouchListener implements OnItemTouchListener {
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
return false;
}
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
static {
boolean z;
if (VERSION.SDK_INT == 18 || VERSION.SDK_INT == 19 || VERSION.SDK_INT == 20) {
z = true;
} else {
z = false;
}
FORCE_INVALIDATE_DISPLAY_LIST = z;
}
public RecyclerView(Context context) {
this(context, null);
}
public RecyclerView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
boolean z;
boolean z2 = false;
super(context, attrs, defStyle);
this.mObserver = new RecyclerViewDataObserver();
this.mRecycler = new Recycler();
this.mViewInfoStore = new ViewInfoStore();
this.mUpdateChildViewsRunnable = new Runnable() {
public void run() {
if (RecyclerView.this.mFirstLayoutComplete && !RecyclerView.this.isLayoutRequested()) {
if (RecyclerView.this.mLayoutFrozen) {
RecyclerView.this.mLayoutRequestEaten = true;
} else {
RecyclerView.this.consumePendingUpdateOperations();
}
}
}
};
this.mTempRect = new Rect();
this.mItemDecorations = new ArrayList();
this.mOnItemTouchListeners = new ArrayList();
this.mDataSetHasChangedAfterLayout = false;
this.mLayoutOrScrollCounter = 0;
this.mItemAnimator = new DefaultItemAnimator();
this.mScrollState = 0;
this.mScrollPointerId = -1;
this.mScrollFactor = Float.MIN_VALUE;
this.mViewFlinger = new ViewFlinger();
this.mState = new State();
this.mItemsAddedOrRemoved = false;
this.mItemsChanged = false;
this.mItemAnimatorListener = new ItemAnimatorRestoreListener();
this.mPostedAnimatorRunner = false;
this.mMinMaxLayoutPositions = new int[2];
this.mScrollOffset = new int[2];
this.mScrollConsumed = new int[2];
this.mNestedOffsets = new int[2];
this.mItemAnimatorRunner = new Runnable() {
public void run() {
if (RecyclerView.this.mItemAnimator != null) {
RecyclerView.this.mItemAnimator.runPendingAnimations();
}
RecyclerView.this.mPostedAnimatorRunner = false;
}
};
this.mViewInfoProcessCallback = new ProcessCallback() {
public void processDisappeared(ViewHolder viewHolder, ItemHolderInfo info, ItemHolderInfo postInfo) {
RecyclerView.this.mRecycler.unscrapView(viewHolder);
RecyclerView.this.animateDisappearance(viewHolder, info, postInfo);
}
public void processAppeared(ViewHolder viewHolder, ItemHolderInfo preInfo, ItemHolderInfo info) {
RecyclerView.this.animateAppearance(viewHolder, preInfo, info);
}
public void processPersistent(ViewHolder viewHolder, @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) {
viewHolder.setIsRecyclable(false);
if (RecyclerView.this.mDataSetHasChangedAfterLayout) {
if (RecyclerView.this.mItemAnimator.animateChange(viewHolder, viewHolder, preInfo, postInfo)) {
RecyclerView.this.postAnimationRunner();
}
} else if (RecyclerView.this.mItemAnimator.animatePersistence(viewHolder, preInfo, postInfo)) {
RecyclerView.this.postAnimationRunner();
}
}
public void unused(ViewHolder viewHolder) {
RecyclerView.this.mLayout.removeAndRecycleView(viewHolder.itemView, RecyclerView.this.mRecycler);
}
};
setScrollContainer(true);
setFocusableInTouchMode(true);
if (VERSION.SDK_INT >= 16) {
z = true;
} else {
z = false;
}
this.mPostUpdatesOnAnimation = z;
ViewConfiguration vc = ViewConfiguration.get(context);
this.mTouchSlop = vc.getScaledTouchSlop();
this.mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
this.mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
if (ViewCompat.getOverScrollMode(this) == 2) {
z2 = true;
}
setWillNotDraw(z2);
this.mItemAnimator.setListener(this.mItemAnimatorListener);
initAdapterManager();
initChildrenHelper();
if (ViewCompat.getImportantForAccessibility(this) == 0) {
ViewCompat.setImportantForAccessibility(this, 1);
}
this.mAccessibilityManager = (AccessibilityManager) getContext().getSystemService("accessibility");
setAccessibilityDelegateCompat(new RecyclerViewAccessibilityDelegate(this));
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerView, defStyle, 0);
String layoutManagerName = a.getString(R.styleable.RecyclerView_layoutManager);
a.recycle();
createLayoutManager(context, layoutManagerName, attrs, defStyle, 0);
}
this.mScrollingChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
public RecyclerViewAccessibilityDelegate getCompatAccessibilityDelegate() {
return this.mAccessibilityDelegate;
}
public void setAccessibilityDelegateCompat(RecyclerViewAccessibilityDelegate accessibilityDelegate) {
this.mAccessibilityDelegate = accessibilityDelegate;
ViewCompat.setAccessibilityDelegate(this, this.mAccessibilityDelegate);
}
private void createLayoutManager(Context context, String className, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
if (className != null) {
className = className.trim();
if (className.length() != 0) {
className = getFullClassName(context, className);
try {
ClassLoader classLoader;
Constructor<? extends LayoutManager> constructor;
if (isInEditMode()) {
classLoader = getClass().getClassLoader();
} else {
classLoader = context.getClassLoader();
}
Class<? extends LayoutManager> layoutManagerClass = classLoader.loadClass(className).asSubclass(LayoutManager.class);
Object[] constructorArgs = null;
try {
constructor = layoutManagerClass.getConstructor(LAYOUT_MANAGER_CONSTRUCTOR_SIGNATURE);
constructorArgs = new Object[]{context, attrs, Integer.valueOf(defStyleAttr), Integer.valueOf(defStyleRes)};
} catch (NoSuchMethodException e) {
constructor = layoutManagerClass.getConstructor(new Class[0]);
}
constructor.setAccessible(true);
setLayoutManager((LayoutManager) constructor.newInstance(constructorArgs));
} catch (NoSuchMethodException e1) {
e1.initCause(e);
throw new IllegalStateException(attrs.getPositionDescription() + ": Error creating LayoutManager " + className, e1);
} catch (ClassNotFoundException e2) {
throw new IllegalStateException(attrs.getPositionDescription() + ": Unable to find LayoutManager " + className, e2);
} catch (InvocationTargetException e3) {
throw new IllegalStateException(attrs.getPositionDescription() + ": Could not instantiate the LayoutManager: " + className, e3);
} catch (InstantiationException e4) {
throw new IllegalStateException(attrs.getPositionDescription() + ": Could not instantiate the LayoutManager: " + className, e4);
} catch (IllegalAccessException e5) {
throw new IllegalStateException(attrs.getPositionDescription() + ": Cannot access non-public constructor " + className, e5);
} catch (ClassCastException e6) {
throw new IllegalStateException(attrs.getPositionDescription() + ": Class is not a LayoutManager " + className, e6);
}
}
}
}
private String getFullClassName(Context context, String className) {
if (className.charAt(0) == '.') {
return context.getPackageName() + className;
}
return !className.contains(".") ? RecyclerView.class.getPackage().getName() + '.' + className : className;
}
private void initChildrenHelper() {
this.mChildHelper = new ChildHelper(new Callback() {
public int getChildCount() {
return RecyclerView.this.getChildCount();
}
public void addView(View child, int index) {
RecyclerView.this.addView(child, index);
RecyclerView.this.dispatchChildAttached(child);
}
public int indexOfChild(View view) {
return RecyclerView.this.indexOfChild(view);
}
public void removeViewAt(int index) {
View child = RecyclerView.this.getChildAt(index);
if (child != null) {
RecyclerView.this.dispatchChildDetached(child);
}
RecyclerView.this.removeViewAt(index);
}
public View getChildAt(int offset) {
return RecyclerView.this.getChildAt(offset);
}
public void removeAllViews() {
int count = getChildCount();
for (int i = 0; i < count; i++) {
RecyclerView.this.dispatchChildDetached(getChildAt(i));
}
RecyclerView.this.removeAllViews();
}
public ViewHolder getChildViewHolder(View view) {
return RecyclerView.getChildViewHolderInt(view);
}
public void attachViewToParent(View child, int index, android.view.ViewGroup.LayoutParams layoutParams) {
ViewHolder vh = RecyclerView.getChildViewHolderInt(child);
if (vh != null) {
if (vh.isTmpDetached() || vh.shouldIgnore()) {
vh.clearTmpDetachFlag();
} else {
throw new IllegalArgumentException("Called attach on a child which is not detached: " + vh);
}
}
RecyclerView.this.attachViewToParent(child, index, layoutParams);
}
public void detachViewFromParent(int offset) {
View view = getChildAt(offset);
if (view != null) {
ViewHolder vh = RecyclerView.getChildViewHolderInt(view);
if (vh != null) {
if (!vh.isTmpDetached() || vh.shouldIgnore()) {
vh.addFlags(256);
} else {
throw new IllegalArgumentException("called detach on an already detached child " + vh);
}
}
}
RecyclerView.this.detachViewFromParent(offset);
}
public void onEnteredHiddenState(View child) {
ViewHolder vh = RecyclerView.getChildViewHolderInt(child);
if (vh != null) {
vh.onEnteredHiddenState();
}
}
public void onLeftHiddenState(View child) {
ViewHolder vh = RecyclerView.getChildViewHolderInt(child);
if (vh != null) {
vh.onLeftHiddenState();
}
}
});
}
void initAdapterManager() {
this.mAdapterHelper = new AdapterHelper(new Callback() {
public ViewHolder findViewHolder(int position) {
ViewHolder vh = RecyclerView.this.findViewHolderForPosition(position, true);
if (vh == null) {
return null;
}
if (RecyclerView.this.mChildHelper.isHidden(vh.itemView)) {
return null;
}
return vh;
}
public void offsetPositionsForRemovingInvisible(int start, int count) {
RecyclerView.this.offsetPositionRecordsForRemove(start, count, true);
RecyclerView.this.mItemsAddedOrRemoved = true;
State.access$1812(RecyclerView.this.mState, count);
}
public void offsetPositionsForRemovingLaidOutOrNewView(int positionStart, int itemCount) {
RecyclerView.this.offsetPositionRecordsForRemove(positionStart, itemCount, false);
RecyclerView.this.mItemsAddedOrRemoved = true;
}
public void markViewHoldersUpdated(int positionStart, int itemCount, Object payload) {
RecyclerView.this.viewRangeUpdate(positionStart, itemCount, payload);
RecyclerView.this.mItemsChanged = true;
}
public void onDispatchFirstPass(UpdateOp op) {
dispatchUpdate(op);
}
void dispatchUpdate(UpdateOp op) {
switch (op.cmd) {
case 1:
RecyclerView.this.mLayout.onItemsAdded(RecyclerView.this, op.positionStart, op.itemCount);
return;
case 2:
RecyclerView.this.mLayout.onItemsRemoved(RecyclerView.this, op.positionStart, op.itemCount);
return;
case 4:
RecyclerView.this.mLayout.onItemsUpdated(RecyclerView.this, op.positionStart, op.itemCount, op.payload);
return;
case 8:
RecyclerView.this.mLayout.onItemsMoved(RecyclerView.this, op.positionStart, op.itemCount, 1);
return;
default:
return;
}
}
public void onDispatchSecondPass(UpdateOp op) {
dispatchUpdate(op);
}
public void offsetPositionsForAdd(int positionStart, int itemCount) {
RecyclerView.this.offsetPositionRecordsForInsert(positionStart, itemCount);
RecyclerView.this.mItemsAddedOrRemoved = true;
}
public void offsetPositionsForMove(int from, int to) {
RecyclerView.this.offsetPositionRecordsForMove(from, to);
RecyclerView.this.mItemsAddedOrRemoved = true;
}
});
}
public void setHasFixedSize(boolean hasFixedSize) {
this.mHasFixedSize = hasFixedSize;
}
public boolean hasFixedSize() {
return this.mHasFixedSize;
}
public void setClipToPadding(boolean clipToPadding) {
if (clipToPadding != this.mClipToPadding) {
invalidateGlows();
}
this.mClipToPadding = clipToPadding;
super.setClipToPadding(clipToPadding);
if (this.mFirstLayoutComplete) {
requestLayout();
}
}
public void setScrollingTouchSlop(int slopConstant) {
ViewConfiguration vc = ViewConfiguration.get(getContext());
switch (slopConstant) {
case 0:
break;
case 1:
this.mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(vc);
return;
default:
Log.w(TAG, "setScrollingTouchSlop(): bad argument constant " + slopConstant + "; using default value");
break;
}
this.mTouchSlop = vc.getScaledTouchSlop();
}
public void swapAdapter(Adapter adapter, boolean removeAndRecycleExistingViews) {
setLayoutFrozen(false);
setAdapterInternal(adapter, true, removeAndRecycleExistingViews);
setDataSetChangedAfterLayout();
requestLayout();
}
public void setAdapter(Adapter adapter) {
setLayoutFrozen(false);
setAdapterInternal(adapter, false, true);
requestLayout();
}
private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious, boolean removeAndRecycleViews) {
if (this.mAdapter != null) {
this.mAdapter.unregisterAdapterDataObserver(this.mObserver);
this.mAdapter.onDetachedFromRecyclerView(this);
}
if (!compatibleWithPrevious || removeAndRecycleViews) {
if (this.mItemAnimator != null) {
this.mItemAnimator.endAnimations();
}
if (this.mLayout != null) {
this.mLayout.removeAndRecycleAllViews(this.mRecycler);
this.mLayout.removeAndRecycleScrapInt(this.mRecycler);
}
this.mRecycler.clear();
}
this.mAdapterHelper.reset();
Adapter oldAdapter = this.mAdapter;
this.mAdapter = adapter;
if (adapter != null) {
adapter.registerAdapterDataObserver(this.mObserver);
adapter.onAttachedToRecyclerView(this);
}
if (this.mLayout != null) {
this.mLayout.onAdapterChanged(oldAdapter, this.mAdapter);
}
this.mRecycler.onAdapterChanged(oldAdapter, this.mAdapter, compatibleWithPrevious);
this.mState.mStructureChanged = true;
markKnownViewsInvalid();
}
public Adapter getAdapter() {
return this.mAdapter;
}
public void setRecyclerListener(RecyclerListener listener) {
this.mRecyclerListener = listener;
}
public int getBaseline() {
if (this.mLayout != null) {
return this.mLayout.getBaseline();
}
return super.getBaseline();
}
public void addOnChildAttachStateChangeListener(OnChildAttachStateChangeListener listener) {
if (this.mOnChildAttachStateListeners == null) {
this.mOnChildAttachStateListeners = new ArrayList();
}
this.mOnChildAttachStateListeners.add(listener);
}
public void removeOnChildAttachStateChangeListener(OnChildAttachStateChangeListener listener) {
if (this.mOnChildAttachStateListeners != null) {
this.mOnChildAttachStateListeners.remove(listener);
}
}
public void clearOnChildAttachStateChangeListeners() {
if (this.mOnChildAttachStateListeners != null) {
this.mOnChildAttachStateListeners.clear();
}
}
public void setLayoutManager(LayoutManager layout) {
if (layout != this.mLayout) {
if (this.mLayout != null) {
if (this.mIsAttached) {
this.mLayout.dispatchDetachedFromWindow(this, this.mRecycler);
}
this.mLayout.setRecyclerView(null);
}
this.mRecycler.clear();
this.mChildHelper.removeAllViewsUnfiltered();
this.mLayout = layout;
if (layout != null) {
if (layout.mRecyclerView != null) {
throw new IllegalArgumentException("LayoutManager " + layout + " is already attached to a RecyclerView: " + layout.mRecyclerView);
}
this.mLayout.setRecyclerView(this);
if (this.mIsAttached) {
this.mLayout.dispatchAttachedToWindow(this);
}
}
requestLayout();
}
}
protected Parcelable onSaveInstanceState() {
SavedState state = new SavedState(super.onSaveInstanceState());
if (this.mPendingSavedState != null) {
state.copyFrom(this.mPendingSavedState);
} else if (this.mLayout != null) {
state.mLayoutState = this.mLayout.onSaveInstanceState();
} else {
state.mLayoutState = null;
}
return state;
}
protected void onRestoreInstanceState(Parcelable state) {
this.mPendingSavedState = (SavedState) state;
super.onRestoreInstanceState(this.mPendingSavedState.getSuperState());
if (this.mLayout != null && this.mPendingSavedState.mLayoutState != null) {
this.mLayout.onRestoreInstanceState(this.mPendingSavedState.mLayoutState);
}
}
protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
dispatchFreezeSelfOnly(container);
}
protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
dispatchThawSelfOnly(container);
}
private void addAnimatingView(ViewHolder viewHolder) {
View view = viewHolder.itemView;
boolean alreadyParented = view.getParent() == this;
this.mRecycler.unscrapView(getChildViewHolder(view));
if (viewHolder.isTmpDetached()) {
this.mChildHelper.attachViewToParent(view, -1, view.getLayoutParams(), true);
} else if (alreadyParented) {
this.mChildHelper.hide(view);
} else {
this.mChildHelper.addView(view, true);
}
}
private boolean removeAnimatingView(View view) {
eatRequestLayout();
boolean removed = this.mChildHelper.removeViewIfHidden(view);
if (removed) {
ViewHolder viewHolder = getChildViewHolderInt(view);
this.mRecycler.unscrapView(viewHolder);
this.mRecycler.recycleViewHolderInternal(viewHolder);
}
resumeRequestLayout(false);
return removed;
}
public LayoutManager getLayoutManager() {
return this.mLayout;
}
public RecycledViewPool getRecycledViewPool() {
return this.mRecycler.getRecycledViewPool();
}
public void setRecycledViewPool(RecycledViewPool pool) {
this.mRecycler.setRecycledViewPool(pool);
}
public void setViewCacheExtension(ViewCacheExtension extension) {
this.mRecycler.setViewCacheExtension(extension);
}
public void setItemViewCacheSize(int size) {
this.mRecycler.setViewCacheSize(size);
}
public int getScrollState() {
return this.mScrollState;
}
private void setScrollState(int state) {
if (state != this.mScrollState) {
this.mScrollState = state;
if (state != 2) {
stopScrollersInternal();
}
dispatchOnScrollStateChanged(state);
}
}
public void addItemDecoration(ItemDecoration decor, int index) {
if (this.mLayout != null) {
this.mLayout.assertNotInLayoutOrScroll("Cannot add item decoration during a scroll or layout");
}
if (this.mItemDecorations.isEmpty()) {
setWillNotDraw(false);
}
if (index < 0) {
this.mItemDecorations.add(decor);
} else {
this.mItemDecorations.add(index, decor);
}
markItemDecorInsetsDirty();
requestLayout();
}
public void addItemDecoration(ItemDecoration decor) {
addItemDecoration(decor, -1);
}
public void removeItemDecoration(ItemDecoration decor) {
if (this.mLayout != null) {
this.mLayout.assertNotInLayoutOrScroll("Cannot remove item decoration during a scroll or layout");
}
this.mItemDecorations.remove(decor);
if (this.mItemDecorations.isEmpty()) {
setWillNotDraw(ViewCompat.getOverScrollMode(this) == 2);
}
markItemDecorInsetsDirty();
requestLayout();
}
public void setChildDrawingOrderCallback(ChildDrawingOrderCallback childDrawingOrderCallback) {
if (childDrawingOrderCallback != this.mChildDrawingOrderCallback) {
this.mChildDrawingOrderCallback = childDrawingOrderCallback;
setChildrenDrawingOrderEnabled(this.mChildDrawingOrderCallback != null);
}
}
@Deprecated
public void setOnScrollListener(OnScrollListener listener) {
this.mScrollListener = listener;
}
public void addOnScrollListener(OnScrollListener listener) {
if (this.mScrollListeners == null) {
this.mScrollListeners = new ArrayList();
}
this.mScrollListeners.add(listener);
}
public void removeOnScrollListener(OnScrollListener listener) {
if (this.mScrollListeners != null) {
this.mScrollListeners.remove(listener);
}
}
public void clearOnScrollListeners() {
if (this.mScrollListeners != null) {
this.mScrollListeners.clear();
}
}
public void scrollToPosition(int position) {
if (!this.mLayoutFrozen) {
stopScroll();
if (this.mLayout == null) {
Log.e(TAG, "Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.");
return;
}
this.mLayout.scrollToPosition(position);
awakenScrollBars();
}
}
private void jumpToPositionForSmoothScroller(int position) {
if (this.mLayout != null) {
this.mLayout.scrollToPosition(position);
awakenScrollBars();
}
}
public void smoothScrollToPosition(int position) {
if (!this.mLayoutFrozen) {
if (this.mLayout == null) {
Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. Call setLayoutManager with a non-null argument.");
} else {
this.mLayout.smoothScrollToPosition(this, this.mState, position);
}
}
}
public void scrollTo(int x, int y) {
Log.w(TAG, "RecyclerView does not support scrolling to an absolute position. Use scrollToPosition instead");
}
public void scrollBy(int x, int y) {
if (this.mLayout == null) {
Log.e(TAG, "Cannot scroll without a LayoutManager set. Call setLayoutManager with a non-null argument.");
} else if (!this.mLayoutFrozen) {
boolean canScrollHorizontal = this.mLayout.canScrollHorizontally();
boolean canScrollVertical = this.mLayout.canScrollVertically();
if (canScrollHorizontal || canScrollVertical) {
if (!canScrollHorizontal) {
x = 0;
}
if (!canScrollVertical) {
y = 0;
}
scrollByInternal(x, y, null);
}
}
}
private void consumePendingUpdateOperations() {
if (!this.mFirstLayoutComplete) {
return;
}
if (this.mDataSetHasChangedAfterLayout) {
TraceCompat.beginSection(TRACE_ON_DATA_SET_CHANGE_LAYOUT_TAG);
dispatchLayout();
TraceCompat.endSection();
} else if (!this.mAdapterHelper.hasPendingUpdates()) {
} else {
if (this.mAdapterHelper.hasAnyUpdateTypes(4) && !this.mAdapterHelper.hasAnyUpdateTypes(11)) {
TraceCompat.beginSection(TRACE_HANDLE_ADAPTER_UPDATES_TAG);
eatRequestLayout();
this.mAdapterHelper.preProcess();
if (!this.mLayoutRequestEaten) {
if (hasUpdatedView()) {
dispatchLayout();
} else {
this.mAdapterHelper.consumePostponedUpdates();
}
}
resumeRequestLayout(true);
TraceCompat.endSection();
} else if (this.mAdapterHelper.hasPendingUpdates()) {
TraceCompat.beginSection(TRACE_ON_DATA_SET_CHANGE_LAYOUT_TAG);
dispatchLayout();
TraceCompat.endSection();
}
}
}
private boolean hasUpdatedView() {
int childCount = this.mChildHelper.getChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getChildAt(i));
if (holder != null && !holder.shouldIgnore() && holder.isUpdated()) {
return true;
}
}
return false;
}
boolean scrollByInternal(int x, int y, MotionEvent ev) {
int unconsumedX = 0;
int unconsumedY = 0;
int consumedX = 0;
int consumedY = 0;
consumePendingUpdateOperations();
if (this.mAdapter != null) {
eatRequestLayout();
onEnterLayoutOrScroll();
TraceCompat.beginSection(TRACE_SCROLL_TAG);
if (x != 0) {
consumedX = this.mLayout.scrollHorizontallyBy(x, this.mRecycler, this.mState);
unconsumedX = x - consumedX;
}
if (y != 0) {
consumedY = this.mLayout.scrollVerticallyBy(y, this.mRecycler, this.mState);
unconsumedY = y - consumedY;
}
TraceCompat.endSection();
repositionShadowingViews();
onExitLayoutOrScroll();
resumeRequestLayout(false);
}
if (!this.mItemDecorations.isEmpty()) {
invalidate();
}
if (dispatchNestedScroll(consumedX, consumedY, unconsumedX, unconsumedY, this.mScrollOffset)) {
this.mLastTouchX -= this.mScrollOffset[0];
this.mLastTouchY -= this.mScrollOffset[1];
if (ev != null) {
ev.offsetLocation((float) this.mScrollOffset[0], (float) this.mScrollOffset[1]);
}
int[] iArr = this.mNestedOffsets;
iArr[0] = iArr[0] + this.mScrollOffset[0];
iArr = this.mNestedOffsets;
iArr[1] = iArr[1] + this.mScrollOffset[1];
} else if (ViewCompat.getOverScrollMode(this) != 2) {
if (ev != null) {
pullGlows(ev.getX(), (float) unconsumedX, ev.getY(), (float) unconsumedY);
}
considerReleasingGlowsOnScroll(x, y);
}
if (!(consumedX == 0 && consumedY == 0)) {
dispatchOnScrolled(consumedX, consumedY);
}
if (!awakenScrollBars()) {
invalidate();
}
if (consumedX == 0 && consumedY == 0) {
return false;
}
return true;
}
public int computeHorizontalScrollOffset() {
return this.mLayout.canScrollHorizontally() ? this.mLayout.computeHorizontalScrollOffset(this.mState) : 0;
}
public int computeHorizontalScrollExtent() {
return this.mLayout.canScrollHorizontally() ? this.mLayout.computeHorizontalScrollExtent(this.mState) : 0;
}
public int computeHorizontalScrollRange() {
return this.mLayout.canScrollHorizontally() ? this.mLayout.computeHorizontalScrollRange(this.mState) : 0;
}
public int computeVerticalScrollOffset() {
return this.mLayout.canScrollVertically() ? this.mLayout.computeVerticalScrollOffset(this.mState) : 0;
}
public int computeVerticalScrollExtent() {
return this.mLayout.canScrollVertically() ? this.mLayout.computeVerticalScrollExtent(this.mState) : 0;
}
public int computeVerticalScrollRange() {
return this.mLayout.canScrollVertically() ? this.mLayout.computeVerticalScrollRange(this.mState) : 0;
}
void eatRequestLayout() {
if (!this.mEatRequestLayout) {
this.mEatRequestLayout = true;
if (!this.mLayoutFrozen) {
this.mLayoutRequestEaten = false;
}
}
}
void resumeRequestLayout(boolean performLayoutChildren) {
if (this.mEatRequestLayout) {
if (!(!performLayoutChildren || !this.mLayoutRequestEaten || this.mLayoutFrozen || this.mLayout == null || this.mAdapter == null)) {
dispatchLayout();
}
this.mEatRequestLayout = false;
if (!this.mLayoutFrozen) {
this.mLayoutRequestEaten = false;
}
}
}
public void setLayoutFrozen(boolean frozen) {
if (frozen != this.mLayoutFrozen) {
assertNotInLayoutOrScroll("Do not setLayoutFrozen in layout or scroll");
if (frozen) {
long now = SystemClock.uptimeMillis();
onTouchEvent(MotionEvent.obtain(now, now, 3, 0.0f, 0.0f, 0));
this.mLayoutFrozen = frozen;
this.mIgnoreMotionEventTillDown = true;
stopScroll();
return;
}
this.mLayoutFrozen = frozen;
if (!(!this.mLayoutRequestEaten || this.mLayout == null || this.mAdapter == null)) {
requestLayout();
}
this.mLayoutRequestEaten = false;
}
}
public boolean isLayoutFrozen() {
return this.mLayoutFrozen;
}
public void smoothScrollBy(int dx, int dy) {
if (this.mLayout == null) {
Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. Call setLayoutManager with a non-null argument.");
} else if (!this.mLayoutFrozen) {
if (!this.mLayout.canScrollHorizontally()) {
dx = 0;
}
if (!this.mLayout.canScrollVertically()) {
dy = 0;
}
if (dx != 0 || dy != 0) {
this.mViewFlinger.smoothScrollBy(dx, dy);
}
}
}
public boolean fling(int velocityX, int velocityY) {
if (this.mLayout == null) {
Log.e(TAG, "Cannot fling without a LayoutManager set. Call setLayoutManager with a non-null argument.");
return false;
} else if (this.mLayoutFrozen) {
return false;
} else {
boolean canScrollHorizontal = this.mLayout.canScrollHorizontally();
boolean canScrollVertical = this.mLayout.canScrollVertically();
if (!canScrollHorizontal || Math.abs(velocityX) < this.mMinFlingVelocity) {
velocityX = 0;
}
if (!canScrollVertical || Math.abs(velocityY) < this.mMinFlingVelocity) {
velocityY = 0;
}
if ((velocityX == 0 && velocityY == 0) || dispatchNestedPreFling((float) velocityX, (float) velocityY)) {
return false;
}
boolean canScroll;
if (canScrollHorizontal || canScrollVertical) {
canScroll = true;
} else {
canScroll = false;
}
dispatchNestedFling((float) velocityX, (float) velocityY, canScroll);
if (!canScroll) {
return false;
}
this.mViewFlinger.fling(Math.max(-this.mMaxFlingVelocity, Math.min(velocityX, this.mMaxFlingVelocity)), Math.max(-this.mMaxFlingVelocity, Math.min(velocityY, this.mMaxFlingVelocity)));
return true;
}
}
public void stopScroll() {
setScrollState(0);
stopScrollersInternal();
}
private void stopScrollersInternal() {
this.mViewFlinger.stop();
if (this.mLayout != null) {
this.mLayout.stopSmoothScroller();
}
}
public int getMinFlingVelocity() {
return this.mMinFlingVelocity;
}
public int getMaxFlingVelocity() {
return this.mMaxFlingVelocity;
}
private void pullGlows(float x, float overscrollX, float y, float overscrollY) {
boolean invalidate = false;
if (overscrollX < 0.0f) {
ensureLeftGlow();
if (this.mLeftGlow.onPull((-overscrollX) / ((float) getWidth()), 1.0f - (y / ((float) getHeight())))) {
invalidate = true;
}
} else if (overscrollX > 0.0f) {
ensureRightGlow();
if (this.mRightGlow.onPull(overscrollX / ((float) getWidth()), y / ((float) getHeight()))) {
invalidate = true;
}
}
if (overscrollY < 0.0f) {
ensureTopGlow();
if (this.mTopGlow.onPull((-overscrollY) / ((float) getHeight()), x / ((float) getWidth()))) {
invalidate = true;
}
} else if (overscrollY > 0.0f) {
ensureBottomGlow();
if (this.mBottomGlow.onPull(overscrollY / ((float) getHeight()), 1.0f - (x / ((float) getWidth())))) {
invalidate = true;
}
}
if (invalidate || overscrollX != 0.0f || overscrollY != 0.0f) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
private void releaseGlows() {
boolean needsInvalidate = false;
if (this.mLeftGlow != null) {
needsInvalidate = this.mLeftGlow.onRelease();
}
if (this.mTopGlow != null) {
needsInvalidate |= this.mTopGlow.onRelease();
}
if (this.mRightGlow != null) {
needsInvalidate |= this.mRightGlow.onRelease();
}
if (this.mBottomGlow != null) {
needsInvalidate |= this.mBottomGlow.onRelease();
}
if (needsInvalidate) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
private void considerReleasingGlowsOnScroll(int dx, int dy) {
boolean needsInvalidate = false;
if (!(this.mLeftGlow == null || this.mLeftGlow.isFinished() || dx <= 0)) {
needsInvalidate = this.mLeftGlow.onRelease();
}
if (!(this.mRightGlow == null || this.mRightGlow.isFinished() || dx >= 0)) {
needsInvalidate |= this.mRightGlow.onRelease();
}
if (!(this.mTopGlow == null || this.mTopGlow.isFinished() || dy <= 0)) {
needsInvalidate |= this.mTopGlow.onRelease();
}
if (!(this.mBottomGlow == null || this.mBottomGlow.isFinished() || dy >= 0)) {
needsInvalidate |= this.mBottomGlow.onRelease();
}
if (needsInvalidate) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
void absorbGlows(int velocityX, int velocityY) {
if (velocityX < 0) {
ensureLeftGlow();
this.mLeftGlow.onAbsorb(-velocityX);
} else if (velocityX > 0) {
ensureRightGlow();
this.mRightGlow.onAbsorb(velocityX);
}
if (velocityY < 0) {
ensureTopGlow();
this.mTopGlow.onAbsorb(-velocityY);
} else if (velocityY > 0) {
ensureBottomGlow();
this.mBottomGlow.onAbsorb(velocityY);
}
if (velocityX != 0 || velocityY != 0) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
void ensureLeftGlow() {
if (this.mLeftGlow == null) {
this.mLeftGlow = new EdgeEffectCompat(getContext());
if (this.mClipToPadding) {
this.mLeftGlow.setSize((getMeasuredHeight() - getPaddingTop()) - getPaddingBottom(), (getMeasuredWidth() - getPaddingLeft()) - getPaddingRight());
} else {
this.mLeftGlow.setSize(getMeasuredHeight(), getMeasuredWidth());
}
}
}
void ensureRightGlow() {
if (this.mRightGlow == null) {
this.mRightGlow = new EdgeEffectCompat(getContext());
if (this.mClipToPadding) {
this.mRightGlow.setSize((getMeasuredHeight() - getPaddingTop()) - getPaddingBottom(), (getMeasuredWidth() - getPaddingLeft()) - getPaddingRight());
} else {
this.mRightGlow.setSize(getMeasuredHeight(), getMeasuredWidth());
}
}
}
void ensureTopGlow() {
if (this.mTopGlow == null) {
this.mTopGlow = new EdgeEffectCompat(getContext());
if (this.mClipToPadding) {
this.mTopGlow.setSize((getMeasuredWidth() - getPaddingLeft()) - getPaddingRight(), (getMeasuredHeight() - getPaddingTop()) - getPaddingBottom());
} else {
this.mTopGlow.setSize(getMeasuredWidth(), getMeasuredHeight());
}
}
}
void ensureBottomGlow() {
if (this.mBottomGlow == null) {
this.mBottomGlow = new EdgeEffectCompat(getContext());
if (this.mClipToPadding) {
this.mBottomGlow.setSize((getMeasuredWidth() - getPaddingLeft()) - getPaddingRight(), (getMeasuredHeight() - getPaddingTop()) - getPaddingBottom());
} else {
this.mBottomGlow.setSize(getMeasuredWidth(), getMeasuredHeight());
}
}
}
void invalidateGlows() {
this.mBottomGlow = null;
this.mTopGlow = null;
this.mRightGlow = null;
this.mLeftGlow = null;
}
public View focusSearch(View focused, int direction) {
View result = this.mLayout.onInterceptFocusSearch(focused, direction);
if (result != null) {
return result;
}
result = FocusFinder.getInstance().findNextFocus(this, focused, direction);
if (!(result != null || this.mAdapter == null || this.mLayout == null || isComputingLayout() || this.mLayoutFrozen)) {
eatRequestLayout();
result = this.mLayout.onFocusSearchFailed(focused, direction, this.mRecycler, this.mState);
resumeRequestLayout(false);
}
return result != null ? result : super.focusSearch(focused, direction);
}
public void requestChildFocus(View child, View focused) {
boolean z = false;
if (!(this.mLayout.onRequestChildFocus(this, this.mState, child, focused) || focused == null)) {
Rect rect;
this.mTempRect.set(0, 0, focused.getWidth(), focused.getHeight());
android.view.ViewGroup.LayoutParams focusedLayoutParams = focused.getLayoutParams();
if (focusedLayoutParams instanceof LayoutParams) {
LayoutParams lp = (LayoutParams) focusedLayoutParams;
if (!lp.mInsetsDirty) {
Rect insets = lp.mDecorInsets;
rect = this.mTempRect;
rect.left -= insets.left;
rect = this.mTempRect;
rect.right += insets.right;
rect = this.mTempRect;
rect.top -= insets.top;
rect = this.mTempRect;
rect.bottom += insets.bottom;
}
}
offsetDescendantRectToMyCoords(focused, this.mTempRect);
offsetRectIntoDescendantCoords(child, this.mTempRect);
rect = this.mTempRect;
if (!this.mFirstLayoutComplete) {
z = true;
}
requestChildRectangleOnScreen(child, rect, z);
}
super.requestChildFocus(child, focused);
}
public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
return this.mLayout.requestChildRectangleOnScreen(this, child, rect, immediate);
}
public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
if (this.mLayout == null || !this.mLayout.onAddFocusables(this, views, direction, focusableMode)) {
super.addFocusables(views, direction, focusableMode);
}
}
protected void onAttachedToWindow() {
super.onAttachedToWindow();
this.mLayoutOrScrollCounter = 0;
this.mIsAttached = true;
this.mFirstLayoutComplete = false;
if (this.mLayout != null) {
this.mLayout.dispatchAttachedToWindow(this);
}
this.mPostedAnimatorRunner = false;
}
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (this.mItemAnimator != null) {
this.mItemAnimator.endAnimations();
}
this.mFirstLayoutComplete = false;
stopScroll();
this.mIsAttached = false;
if (this.mLayout != null) {
this.mLayout.dispatchDetachedFromWindow(this, this.mRecycler);
}
removeCallbacks(this.mItemAnimatorRunner);
this.mViewInfoStore.onDetach();
}
public boolean isAttachedToWindow() {
return this.mIsAttached;
}
void assertInLayoutOrScroll(String message) {
if (!isComputingLayout()) {
if (message == null) {
throw new IllegalStateException("Cannot call this method unless RecyclerView is computing a layout or scrolling");
}
throw new IllegalStateException(message);
}
}
void assertNotInLayoutOrScroll(String message) {
if (!isComputingLayout()) {
return;
}
if (message == null) {
throw new IllegalStateException("Cannot call this method while RecyclerView is computing a layout or scrolling");
}
throw new IllegalStateException(message);
}
public void addOnItemTouchListener(OnItemTouchListener listener) {
this.mOnItemTouchListeners.add(listener);
}
public void removeOnItemTouchListener(OnItemTouchListener listener) {
this.mOnItemTouchListeners.remove(listener);
if (this.mActiveOnItemTouchListener == listener) {
this.mActiveOnItemTouchListener = null;
}
}
private boolean dispatchOnItemTouchIntercept(MotionEvent e) {
int action = e.getAction();
if (action == 3 || action == 0) {
this.mActiveOnItemTouchListener = null;
}
int listenerCount = this.mOnItemTouchListeners.size();
int i = 0;
while (i < listenerCount) {
OnItemTouchListener listener = (OnItemTouchListener) this.mOnItemTouchListeners.get(i);
if (!listener.onInterceptTouchEvent(this, e) || action == 3) {
i++;
} else {
this.mActiveOnItemTouchListener = listener;
return true;
}
}
return false;
}
private boolean dispatchOnItemTouch(MotionEvent e) {
int action = e.getAction();
if (this.mActiveOnItemTouchListener != null) {
if (action == 0) {
this.mActiveOnItemTouchListener = null;
} else {
this.mActiveOnItemTouchListener.onTouchEvent(this, e);
if (action != 3 && action != 1) {
return true;
}
this.mActiveOnItemTouchListener = null;
return true;
}
}
if (action != 0) {
int listenerCount = this.mOnItemTouchListeners.size();
for (int i = 0; i < listenerCount; i++) {
OnItemTouchListener listener = (OnItemTouchListener) this.mOnItemTouchListeners.get(i);
if (listener.onInterceptTouchEvent(this, e)) {
this.mActiveOnItemTouchListener = listener;
return true;
}
}
}
return false;
}
public boolean onInterceptTouchEvent(MotionEvent e) {
if (this.mLayoutFrozen) {
return false;
}
if (dispatchOnItemTouchIntercept(e)) {
cancelTouch();
return true;
} else if (this.mLayout == null) {
return false;
} else {
boolean canScrollHorizontally = this.mLayout.canScrollHorizontally();
boolean canScrollVertically = this.mLayout.canScrollVertically();
if (this.mVelocityTracker == null) {
this.mVelocityTracker = VelocityTracker.obtain();
}
this.mVelocityTracker.addMovement(e);
int action = MotionEventCompat.getActionMasked(e);
int actionIndex = MotionEventCompat.getActionIndex(e);
int x;
switch (action) {
case 0:
if (this.mIgnoreMotionEventTillDown) {
this.mIgnoreMotionEventTillDown = false;
}
this.mScrollPointerId = MotionEventCompat.getPointerId(e, 0);
x = (int) (e.getX() + 0.5f);
this.mLastTouchX = x;
this.mInitialTouchX = x;
x = (int) (e.getY() + 0.5f);
this.mLastTouchY = x;
this.mInitialTouchY = x;
if (this.mScrollState == 2) {
getParent().requestDisallowInterceptTouchEvent(true);
setScrollState(1);
}
int[] iArr = this.mNestedOffsets;
this.mNestedOffsets[1] = 0;
iArr[0] = 0;
int nestedScrollAxis = 0;
if (canScrollHorizontally) {
nestedScrollAxis = 0 | 1;
}
if (canScrollVertically) {
nestedScrollAxis |= 2;
}
startNestedScroll(nestedScrollAxis);
break;
case 1:
this.mVelocityTracker.clear();
stopNestedScroll();
break;
case 2:
int index = MotionEventCompat.findPointerIndex(e, this.mScrollPointerId);
if (index >= 0) {
int x2 = (int) (MotionEventCompat.getX(e, index) + 0.5f);
int y = (int) (MotionEventCompat.getY(e, index) + 0.5f);
if (this.mScrollState != 1) {
int dx = x2 - this.mInitialTouchX;
int dy = y - this.mInitialTouchY;
boolean startScroll = false;
if (canScrollHorizontally && Math.abs(dx) > this.mTouchSlop) {
this.mLastTouchX = ((dx < 0 ? -1 : 1) * this.mTouchSlop) + this.mInitialTouchX;
startScroll = true;
}
if (canScrollVertically && Math.abs(dy) > this.mTouchSlop) {
this.mLastTouchY = ((dy < 0 ? -1 : 1) * this.mTouchSlop) + this.mInitialTouchY;
startScroll = true;
}
if (startScroll) {
setScrollState(1);
break;
}
}
}
Log.e(TAG, "Error processing scroll; pointer index for id " + this.mScrollPointerId + " not found. Did any MotionEvents get skipped?");
return false;
break;
case 3:
cancelTouch();
break;
case 5:
this.mScrollPointerId = MotionEventCompat.getPointerId(e, actionIndex);
x = (int) (MotionEventCompat.getX(e, actionIndex) + 0.5f);
this.mLastTouchX = x;
this.mInitialTouchX = x;
x = (int) (MotionEventCompat.getY(e, actionIndex) + 0.5f);
this.mLastTouchY = x;
this.mInitialTouchY = x;
break;
case 6:
onPointerUp(e);
break;
}
if (this.mScrollState == 1) {
return true;
}
return false;
}
}
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
int listenerCount = this.mOnItemTouchListeners.size();
for (int i = 0; i < listenerCount; i++) {
((OnItemTouchListener) this.mOnItemTouchListeners.get(i)).onRequestDisallowInterceptTouchEvent(disallowIntercept);
}
super.requestDisallowInterceptTouchEvent(disallowIntercept);
}
/* JADX WARNING: inconsistent code. */
/* Code decompiled incorrectly, please refer to instructions dump. */
public boolean onTouchEvent(android.view.MotionEvent r24) {
/*
r23 = this;
r0 = r23;
r0 = r0.mLayoutFrozen;
r18 = r0;
if (r18 != 0) goto L_0x0010;
L_0x0008:
r0 = r23;
r0 = r0.mIgnoreMotionEventTillDown;
r18 = r0;
if (r18 == 0) goto L_0x0013;
L_0x0010:
r18 = 0;
L_0x0012:
return r18;
L_0x0013:
r18 = r23.dispatchOnItemTouch(r24);
if (r18 == 0) goto L_0x001f;
L_0x0019:
r23.cancelTouch();
r18 = 1;
goto L_0x0012;
L_0x001f:
r0 = r23;
r0 = r0.mLayout;
r18 = r0;
if (r18 != 0) goto L_0x002a;
L_0x0027:
r18 = 0;
goto L_0x0012;
L_0x002a:
r0 = r23;
r0 = r0.mLayout;
r18 = r0;
r5 = r18.canScrollHorizontally();
r0 = r23;
r0 = r0.mLayout;
r18 = r0;
r6 = r18.canScrollVertically();
r0 = r23;
r0 = r0.mVelocityTracker;
r18 = r0;
if (r18 != 0) goto L_0x0050;
L_0x0046:
r18 = android.view.VelocityTracker.obtain();
r0 = r18;
r1 = r23;
r1.mVelocityTracker = r0;
L_0x0050:
r9 = 0;
r13 = android.view.MotionEvent.obtain(r24);
r3 = android.support.v4.view.MotionEventCompat.getActionMasked(r24);
r4 = android.support.v4.view.MotionEventCompat.getActionIndex(r24);
if (r3 != 0) goto L_0x0075;
L_0x005f:
r0 = r23;
r0 = r0.mNestedOffsets;
r18 = r0;
r19 = 0;
r0 = r23;
r0 = r0.mNestedOffsets;
r20 = r0;
r21 = 1;
r22 = 0;
r20[r21] = r22;
r18[r19] = r22;
L_0x0075:
r0 = r23;
r0 = r0.mNestedOffsets;
r18 = r0;
r19 = 0;
r18 = r18[r19];
r0 = r18;
r0 = (float) r0;
r18 = r0;
r0 = r23;
r0 = r0.mNestedOffsets;
r19 = r0;
r20 = 1;
r19 = r19[r20];
r0 = r19;
r0 = (float) r0;
r19 = r0;
r0 = r18;
r1 = r19;
r13.offsetLocation(r0, r1);
switch(r3) {
case 0: goto L_0x00b1;
case 1: goto L_0x02e7;
case 2: goto L_0x0146;
case 3: goto L_0x0368;
case 4: goto L_0x009d;
case 5: goto L_0x0102;
case 6: goto L_0x02e2;
default: goto L_0x009d;
};
L_0x009d:
if (r9 != 0) goto L_0x00aa;
L_0x009f:
r0 = r23;
r0 = r0.mVelocityTracker;
r18 = r0;
r0 = r18;
r0.addMovement(r13);
L_0x00aa:
r13.recycle();
r18 = 1;
goto L_0x0012;
L_0x00b1:
r18 = 0;
r0 = r24;
r1 = r18;
r18 = android.support.v4.view.MotionEventCompat.getPointerId(r0, r1);
r0 = r18;
r1 = r23;
r1.mScrollPointerId = r0;
r18 = r24.getX();
r19 = 1056964608; // 0x3f000000 float:0.5 double:5.222099017E-315;
r18 = r18 + r19;
r0 = r18;
r0 = (int) r0;
r18 = r0;
r0 = r18;
r1 = r23;
r1.mLastTouchX = r0;
r0 = r18;
r1 = r23;
r1.mInitialTouchX = r0;
r18 = r24.getY();
r19 = 1056964608; // 0x3f000000 float:0.5 double:5.222099017E-315;
r18 = r18 + r19;
r0 = r18;
r0 = (int) r0;
r18 = r0;
r0 = r18;
r1 = r23;
r1.mLastTouchY = r0;
r0 = r18;
r1 = r23;
r1.mInitialTouchY = r0;
r11 = 0;
if (r5 == 0) goto L_0x00f8;
L_0x00f6:
r11 = r11 | 1;
L_0x00f8:
if (r6 == 0) goto L_0x00fc;
L_0x00fa:
r11 = r11 | 2;
L_0x00fc:
r0 = r23;
r0.startNestedScroll(r11);
goto L_0x009d;
L_0x0102:
r0 = r24;
r18 = android.support.v4.view.MotionEventCompat.getPointerId(r0, r4);
r0 = r18;
r1 = r23;
r1.mScrollPointerId = r0;
r0 = r24;
r18 = android.support.v4.view.MotionEventCompat.getX(r0, r4);
r19 = 1056964608; // 0x3f000000 float:0.5 double:5.222099017E-315;
r18 = r18 + r19;
r0 = r18;
r0 = (int) r0;
r18 = r0;
r0 = r18;
r1 = r23;
r1.mLastTouchX = r0;
r0 = r18;
r1 = r23;
r1.mInitialTouchX = r0;
r0 = r24;
r18 = android.support.v4.view.MotionEventCompat.getY(r0, r4);
r19 = 1056964608; // 0x3f000000 float:0.5 double:5.222099017E-315;
r18 = r18 + r19;
r0 = r18;
r0 = (int) r0;
r18 = r0;
r0 = r18;
r1 = r23;
r1.mLastTouchY = r0;
r0 = r18;
r1 = r23;
r1.mInitialTouchY = r0;
goto L_0x009d;
L_0x0146:
r0 = r23;
r0 = r0.mScrollPointerId;
r18 = r0;
r0 = r24;
r1 = r18;
r10 = android.support.v4.view.MotionEventCompat.findPointerIndex(r0, r1);
if (r10 >= 0) goto L_0x017e;
L_0x0156:
r18 = "RecyclerView";
r19 = new java.lang.StringBuilder;
r19.<init>();
r20 = "Error processing scroll; pointer index for id ";
r19 = r19.append(r20);
r0 = r23;
r0 = r0.mScrollPointerId;
r20 = r0;
r19 = r19.append(r20);
r20 = " not found. Did any MotionEvents get skipped?";
r19 = r19.append(r20);
r19 = r19.toString();
android.util.Log.e(r18, r19);
r18 = 0;
goto L_0x0012;
L_0x017e:
r0 = r24;
r18 = android.support.v4.view.MotionEventCompat.getX(r0, r10);
r19 = 1056964608; // 0x3f000000 float:0.5 double:5.222099017E-315;
r18 = r18 + r19;
r0 = r18;
r14 = (int) r0;
r0 = r24;
r18 = android.support.v4.view.MotionEventCompat.getY(r0, r10);
r19 = 1056964608; // 0x3f000000 float:0.5 double:5.222099017E-315;
r18 = r18 + r19;
r0 = r18;
r0 = (int) r0;
r16 = r0;
r0 = r23;
r0 = r0.mLastTouchX;
r18 = r0;
r7 = r18 - r14;
r0 = r23;
r0 = r0.mLastTouchY;
r18 = r0;
r8 = r18 - r16;
r0 = r23;
r0 = r0.mScrollConsumed;
r18 = r0;
r0 = r23;
r0 = r0.mScrollOffset;
r19 = r0;
r0 = r23;
r1 = r18;
r2 = r19;
r18 = r0.dispatchNestedPreScroll(r7, r8, r1, r2);
if (r18 == 0) goto L_0x022f;
L_0x01c2:
r0 = r23;
r0 = r0.mScrollConsumed;
r18 = r0;
r19 = 0;
r18 = r18[r19];
r7 = r7 - r18;
r0 = r23;
r0 = r0.mScrollConsumed;
r18 = r0;
r19 = 1;
r18 = r18[r19];
r8 = r8 - r18;
r0 = r23;
r0 = r0.mScrollOffset;
r18 = r0;
r19 = 0;
r18 = r18[r19];
r0 = r18;
r0 = (float) r0;
r18 = r0;
r0 = r23;
r0 = r0.mScrollOffset;
r19 = r0;
r20 = 1;
r19 = r19[r20];
r0 = r19;
r0 = (float) r0;
r19 = r0;
r0 = r18;
r1 = r19;
r13.offsetLocation(r0, r1);
r0 = r23;
r0 = r0.mNestedOffsets;
r18 = r0;
r19 = 0;
r20 = r18[r19];
r0 = r23;
r0 = r0.mScrollOffset;
r21 = r0;
r22 = 0;
r21 = r21[r22];
r20 = r20 + r21;
r18[r19] = r20;
r0 = r23;
r0 = r0.mNestedOffsets;
r18 = r0;
r19 = 1;
r20 = r18[r19];
r0 = r23;
r0 = r0.mScrollOffset;
r21 = r0;
r22 = 1;
r21 = r21[r22];
r20 = r20 + r21;
r18[r19] = r20;
L_0x022f:
r0 = r23;
r0 = r0.mScrollState;
r18 = r0;
r19 = 1;
r0 = r18;
r1 = r19;
if (r0 == r1) goto L_0x0283;
L_0x023d:
r12 = 0;
if (r5 == 0) goto L_0x025b;
L_0x0240:
r18 = java.lang.Math.abs(r7);
r0 = r23;
r0 = r0.mTouchSlop;
r19 = r0;
r0 = r18;
r1 = r19;
if (r0 <= r1) goto L_0x025b;
L_0x0250:
if (r7 <= 0) goto L_0x02cc;
L_0x0252:
r0 = r23;
r0 = r0.mTouchSlop;
r18 = r0;
r7 = r7 - r18;
L_0x025a:
r12 = 1;
L_0x025b:
if (r6 == 0) goto L_0x0278;
L_0x025d:
r18 = java.lang.Math.abs(r8);
r0 = r23;
r0 = r0.mTouchSlop;
r19 = r0;
r0 = r18;
r1 = r19;
if (r0 <= r1) goto L_0x0278;
L_0x026d:
if (r8 <= 0) goto L_0x02d5;
L_0x026f:
r0 = r23;
r0 = r0.mTouchSlop;
r18 = r0;
r8 = r8 - r18;
L_0x0277:
r12 = 1;
L_0x0278:
if (r12 == 0) goto L_0x0283;
L_0x027a:
r18 = 1;
r0 = r23;
r1 = r18;
r0.setScrollState(r1);
L_0x0283:
r0 = r23;
r0 = r0.mScrollState;
r18 = r0;
r19 = 1;
r0 = r18;
r1 = r19;
if (r0 != r1) goto L_0x009d;
L_0x0291:
r0 = r23;
r0 = r0.mScrollOffset;
r18 = r0;
r19 = 0;
r18 = r18[r19];
r18 = r14 - r18;
r0 = r18;
r1 = r23;
r1.mLastTouchX = r0;
r0 = r23;
r0 = r0.mScrollOffset;
r18 = r0;
r19 = 1;
r18 = r18[r19];
r18 = r16 - r18;
r0 = r18;
r1 = r23;
r1.mLastTouchY = r0;
if (r5 == 0) goto L_0x02de;
L_0x02b7:
if (r6 == 0) goto L_0x02e0;
L_0x02b9:
r0 = r23;
r18 = r0.scrollByInternal(r7, r8, r13);
if (r18 == 0) goto L_0x009d;
L_0x02c1:
r18 = r23.getParent();
r19 = 1;
r18.requestDisallowInterceptTouchEvent(r19);
goto L_0x009d;
L_0x02cc:
r0 = r23;
r0 = r0.mTouchSlop;
r18 = r0;
r7 = r7 + r18;
goto L_0x025a;
L_0x02d5:
r0 = r23;
r0 = r0.mTouchSlop;
r18 = r0;
r8 = r8 + r18;
goto L_0x0277;
L_0x02de:
r7 = 0;
goto L_0x02b7;
L_0x02e0:
r8 = 0;
goto L_0x02b9;
L_0x02e2:
r23.onPointerUp(r24);
goto L_0x009d;
L_0x02e7:
r0 = r23;
r0 = r0.mVelocityTracker;
r18 = r0;
r0 = r18;
r0.addMovement(r13);
r9 = 1;
r0 = r23;
r0 = r0.mVelocityTracker;
r18 = r0;
r19 = 1000; // 0x3e8 float:1.401E-42 double:4.94E-321;
r0 = r23;
r0 = r0.mMaxFlingVelocity;
r20 = r0;
r0 = r20;
r0 = (float) r0;
r20 = r0;
r18.computeCurrentVelocity(r19, r20);
if (r5 == 0) goto L_0x0363;
L_0x030b:
r0 = r23;
r0 = r0.mVelocityTracker;
r18 = r0;
r0 = r23;
r0 = r0.mScrollPointerId;
r19 = r0;
r18 = android.support.v4.view.VelocityTrackerCompat.getXVelocity(r18, r19);
r0 = r18;
r15 = -r0;
L_0x031e:
if (r6 == 0) goto L_0x0365;
L_0x0320:
r0 = r23;
r0 = r0.mVelocityTracker;
r18 = r0;
r0 = r23;
r0 = r0.mScrollPointerId;
r19 = r0;
r18 = android.support.v4.view.VelocityTrackerCompat.getYVelocity(r18, r19);
r0 = r18;
r0 = -r0;
r17 = r0;
L_0x0335:
r18 = 0;
r18 = (r15 > r18 ? 1 : (r15 == r18 ? 0 : -1));
if (r18 != 0) goto L_0x0341;
L_0x033b:
r18 = 0;
r18 = (r17 > r18 ? 1 : (r17 == r18 ? 0 : -1));
if (r18 == 0) goto L_0x0355;
L_0x0341:
r0 = (int) r15;
r18 = r0;
r0 = r17;
r0 = (int) r0;
r19 = r0;
r0 = r23;
r1 = r18;
r2 = r19;
r18 = r0.fling(r1, r2);
if (r18 != 0) goto L_0x035e;
L_0x0355:
r18 = 0;
r0 = r23;
r1 = r18;
r0.setScrollState(r1);
L_0x035e:
r23.resetTouch();
goto L_0x009d;
L_0x0363:
r15 = 0;
goto L_0x031e;
L_0x0365:
r17 = 0;
goto L_0x0335;
L_0x0368:
r23.cancelTouch();
goto L_0x009d;
*/
throw new UnsupportedOperationException("Method not decompiled: android.support.v7.widget.RecyclerView.onTouchEvent(android.view.MotionEvent):boolean");
}
private void resetTouch() {
if (this.mVelocityTracker != null) {
this.mVelocityTracker.clear();
}
stopNestedScroll();
releaseGlows();
}
private void cancelTouch() {
resetTouch();
setScrollState(0);
}
private void onPointerUp(MotionEvent e) {
int actionIndex = MotionEventCompat.getActionIndex(e);
if (MotionEventCompat.getPointerId(e, actionIndex) == this.mScrollPointerId) {
int newIndex = actionIndex == 0 ? 1 : 0;
this.mScrollPointerId = MotionEventCompat.getPointerId(e, newIndex);
int x = (int) (MotionEventCompat.getX(e, newIndex) + 0.5f);
this.mLastTouchX = x;
this.mInitialTouchX = x;
x = (int) (MotionEventCompat.getY(e, newIndex) + 0.5f);
this.mLastTouchY = x;
this.mInitialTouchY = x;
}
}
public boolean onGenericMotionEvent(MotionEvent event) {
if (!(this.mLayout == null || this.mLayoutFrozen || (MotionEventCompat.getSource(event) & 2) == 0 || event.getAction() != 8)) {
float vScroll;
float hScroll;
if (this.mLayout.canScrollVertically()) {
vScroll = -MotionEventCompat.getAxisValue(event, 9);
} else {
vScroll = 0.0f;
}
if (this.mLayout.canScrollHorizontally()) {
hScroll = MotionEventCompat.getAxisValue(event, 10);
} else {
hScroll = 0.0f;
}
if (!(vScroll == 0.0f && hScroll == 0.0f)) {
float scrollFactor = getScrollFactor();
scrollByInternal((int) (hScroll * scrollFactor), (int) (vScroll * scrollFactor), event);
}
}
return false;
}
private float getScrollFactor() {
if (this.mScrollFactor == Float.MIN_VALUE) {
TypedValue outValue = new TypedValue();
if (!getContext().getTheme().resolveAttribute(16842829, outValue, true)) {
return 0.0f;
}
this.mScrollFactor = outValue.getDimension(getContext().getResources().getDisplayMetrics());
}
return this.mScrollFactor;
}
protected void onMeasure(int widthSpec, int heightSpec) {
if (this.mAdapterUpdateDuringMeasure) {
eatRequestLayout();
processAdapterUpdatesAndSetAnimationFlags();
if (this.mState.mRunPredictiveAnimations) {
this.mState.mInPreLayout = true;
} else {
this.mAdapterHelper.consumeUpdatesInOnePass();
this.mState.mInPreLayout = false;
}
this.mAdapterUpdateDuringMeasure = false;
resumeRequestLayout(false);
}
if (this.mAdapter != null) {
this.mState.mItemCount = this.mAdapter.getItemCount();
} else {
this.mState.mItemCount = 0;
}
if (this.mLayout == null) {
defaultOnMeasure(widthSpec, heightSpec);
} else {
this.mLayout.onMeasure(this.mRecycler, this.mState, widthSpec, heightSpec);
}
this.mState.mInPreLayout = false;
}
private void defaultOnMeasure(int widthSpec, int heightSpec) {
int width;
int height;
int widthMode = MeasureSpec.getMode(widthSpec);
int heightMode = MeasureSpec.getMode(heightSpec);
int widthSize = MeasureSpec.getSize(widthSpec);
int heightSize = MeasureSpec.getSize(heightSpec);
switch (widthMode) {
case Integer.MIN_VALUE:
case 1073741824:
width = widthSize;
break;
default:
width = ViewCompat.getMinimumWidth(this);
break;
}
switch (heightMode) {
case Integer.MIN_VALUE:
case 1073741824:
height = heightSize;
break;
default:
height = ViewCompat.getMinimumHeight(this);
break;
}
setMeasuredDimension(width, height);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (w != oldw || h != oldh) {
invalidateGlows();
}
}
public void setItemAnimator(ItemAnimator animator) {
if (this.mItemAnimator != null) {
this.mItemAnimator.endAnimations();
this.mItemAnimator.setListener(null);
}
this.mItemAnimator = animator;
if (this.mItemAnimator != null) {
this.mItemAnimator.setListener(this.mItemAnimatorListener);
}
}
private void onEnterLayoutOrScroll() {
this.mLayoutOrScrollCounter++;
}
private void onExitLayoutOrScroll() {
this.mLayoutOrScrollCounter--;
if (this.mLayoutOrScrollCounter < 1) {
this.mLayoutOrScrollCounter = 0;
dispatchContentChangedIfNecessary();
}
}
boolean isAccessibilityEnabled() {
return this.mAccessibilityManager != null && this.mAccessibilityManager.isEnabled();
}
private void dispatchContentChangedIfNecessary() {
int flags = this.mEatenAccessibilityChangeFlags;
this.mEatenAccessibilityChangeFlags = 0;
if (flags != 0 && isAccessibilityEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain();
event.setEventType(2048);
AccessibilityEventCompat.setContentChangeTypes(event, flags);
sendAccessibilityEventUnchecked(event);
}
}
public boolean isComputingLayout() {
return this.mLayoutOrScrollCounter > 0;
}
boolean shouldDeferAccessibilityEvent(AccessibilityEvent event) {
if (!isComputingLayout()) {
return false;
}
int type = 0;
if (event != null) {
type = AccessibilityEventCompat.getContentChangeTypes(event);
}
if (type == 0) {
type = 0;
}
this.mEatenAccessibilityChangeFlags |= type;
return true;
}
public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
if (!shouldDeferAccessibilityEvent(event)) {
super.sendAccessibilityEventUnchecked(event);
}
}
public ItemAnimator getItemAnimator() {
return this.mItemAnimator;
}
private void postAnimationRunner() {
if (!this.mPostedAnimatorRunner && this.mIsAttached) {
ViewCompat.postOnAnimation(this, this.mItemAnimatorRunner);
this.mPostedAnimatorRunner = true;
}
}
private boolean predictiveItemAnimationsEnabled() {
return this.mItemAnimator != null && this.mLayout.supportsPredictiveItemAnimations();
}
private void processAdapterUpdatesAndSetAnimationFlags() {
boolean z;
boolean z2 = true;
if (this.mDataSetHasChangedAfterLayout) {
this.mAdapterHelper.reset();
markKnownViewsInvalid();
this.mLayout.onItemsChanged(this);
}
if (this.mItemAnimator == null || !this.mLayout.supportsPredictiveItemAnimations()) {
this.mAdapterHelper.consumeUpdatesInOnePass();
} else {
this.mAdapterHelper.preProcess();
}
boolean animationTypeSupported;
if (this.mItemsAddedOrRemoved || this.mItemsChanged) {
animationTypeSupported = true;
} else {
animationTypeSupported = false;
}
State state = this.mState;
if (!this.mFirstLayoutComplete || this.mItemAnimator == null || (!(this.mDataSetHasChangedAfterLayout || animationTypeSupported || this.mLayout.mRequestedSimpleAnimations) || (this.mDataSetHasChangedAfterLayout && !this.mAdapter.hasStableIds()))) {
z = false;
} else {
z = true;
}
state.mRunSimpleAnimations = z;
State state2 = this.mState;
if (!(this.mState.mRunSimpleAnimations && animationTypeSupported && !this.mDataSetHasChangedAfterLayout && predictiveItemAnimationsEnabled())) {
z2 = false;
}
state2.mRunPredictiveAnimations = z2;
}
void dispatchLayout() {
if (this.mAdapter == null) {
Log.e(TAG, "No adapter attached; skipping layout");
} else if (this.mLayout == null) {
Log.e(TAG, "No layout manager attached; skipping layout");
} else {
int count;
int i;
ViewHolder holder;
ItemHolderInfo animationInfo;
this.mViewInfoStore.clear();
eatRequestLayout();
onEnterLayoutOrScroll();
processAdapterUpdatesAndSetAnimationFlags();
State state = this.mState;
boolean z = this.mState.mRunSimpleAnimations && this.mItemsChanged;
state.mTrackOldChangeHolders = z;
this.mItemsChanged = false;
this.mItemsAddedOrRemoved = false;
this.mState.mInPreLayout = this.mState.mRunPredictiveAnimations;
this.mState.mItemCount = this.mAdapter.getItemCount();
findMinMaxChildLayoutPositions(this.mMinMaxLayoutPositions);
if (this.mState.mRunSimpleAnimations) {
count = this.mChildHelper.getChildCount();
for (i = 0; i < count; i++) {
holder = getChildViewHolderInt(this.mChildHelper.getChildAt(i));
if (!holder.shouldIgnore() && (!holder.isInvalid() || this.mAdapter.hasStableIds())) {
this.mViewInfoStore.addToPreLayout(holder, this.mItemAnimator.recordPreLayoutInformation(this.mState, holder, ItemAnimator.buildAdapterChangeFlagsForAnimations(holder), holder.getUnmodifiedPayloads()));
if (!(!this.mState.mTrackOldChangeHolders || !holder.isUpdated() || holder.isRemoved() || holder.shouldIgnore() || holder.isInvalid())) {
this.mViewInfoStore.addToOldChangeHolders(getChangedHolderKey(holder), holder);
}
}
}
}
if (this.mState.mRunPredictiveAnimations) {
saveOldPositions();
boolean didStructureChange = this.mState.mStructureChanged;
this.mState.mStructureChanged = false;
this.mLayout.onLayoutChildren(this.mRecycler, this.mState);
this.mState.mStructureChanged = didStructureChange;
for (i = 0; i < this.mChildHelper.getChildCount(); i++) {
ViewHolder viewHolder = getChildViewHolderInt(this.mChildHelper.getChildAt(i));
if (!(viewHolder.shouldIgnore() || this.mViewInfoStore.isInPreLayout(viewHolder))) {
int flags = ItemAnimator.buildAdapterChangeFlagsForAnimations(viewHolder);
boolean wasHidden = viewHolder.hasAnyOfTheFlags(8192);
if (!wasHidden) {
flags |= 4096;
}
animationInfo = this.mItemAnimator.recordPreLayoutInformation(this.mState, viewHolder, flags, viewHolder.getUnmodifiedPayloads());
if (wasHidden) {
recordAnimationInfoIfBouncedHiddenView(viewHolder, animationInfo);
} else {
this.mViewInfoStore.addToAppearedInPreLayoutHolders(viewHolder, animationInfo);
}
}
}
clearOldPositions();
this.mAdapterHelper.consumePostponedUpdates();
} else {
clearOldPositions();
}
this.mState.mItemCount = this.mAdapter.getItemCount();
this.mState.mDeletedInvisibleItemCountSincePreviousLayout = 0;
this.mState.mInPreLayout = false;
this.mLayout.onLayoutChildren(this.mRecycler, this.mState);
this.mState.mStructureChanged = false;
this.mPendingSavedState = null;
state = this.mState;
z = this.mState.mRunSimpleAnimations && this.mItemAnimator != null;
state.mRunSimpleAnimations = z;
if (this.mState.mRunSimpleAnimations) {
count = this.mChildHelper.getChildCount();
for (i = 0; i < count; i++) {
holder = getChildViewHolderInt(this.mChildHelper.getChildAt(i));
if (!holder.shouldIgnore()) {
long key = getChangedHolderKey(holder);
animationInfo = this.mItemAnimator.recordPostLayoutInformation(this.mState, holder);
ViewHolder oldChangeViewHolder = this.mViewInfoStore.getFromOldChangeHolders(key);
if (oldChangeViewHolder == null || oldChangeViewHolder.shouldIgnore()) {
this.mViewInfoStore.addToPostLayout(holder, animationInfo);
} else {
animateChange(oldChangeViewHolder, holder, this.mViewInfoStore.popFromPreLayout(oldChangeViewHolder), animationInfo);
}
}
}
this.mViewInfoStore.process(this.mViewInfoProcessCallback);
}
resumeRequestLayout(false);
this.mLayout.removeAndRecycleScrapInt(this.mRecycler);
this.mState.mPreviousLayoutItemCount = this.mState.mItemCount;
this.mDataSetHasChangedAfterLayout = false;
this.mState.mRunSimpleAnimations = false;
this.mState.mRunPredictiveAnimations = false;
onExitLayoutOrScroll();
this.mLayout.mRequestedSimpleAnimations = false;
if (this.mRecycler.mChangedScrap != null) {
this.mRecycler.mChangedScrap.clear();
}
this.mViewInfoStore.clear();
if (didChildRangeChange(this.mMinMaxLayoutPositions[0], this.mMinMaxLayoutPositions[1])) {
dispatchOnScrolled(0, 0);
}
}
}
private void recordAnimationInfoIfBouncedHiddenView(ViewHolder viewHolder, ItemHolderInfo animationInfo) {
viewHolder.setFlags(0, 8192);
if (this.mState.mTrackOldChangeHolders && viewHolder.isUpdated() && !viewHolder.isRemoved() && !viewHolder.shouldIgnore()) {
this.mViewInfoStore.addToOldChangeHolders(getChangedHolderKey(viewHolder), viewHolder);
}
this.mViewInfoStore.addToPreLayout(viewHolder, animationInfo);
}
private void findMinMaxChildLayoutPositions(int[] into) {
int count = this.mChildHelper.getChildCount();
if (count == 0) {
into[0] = 0;
into[1] = 0;
return;
}
int minPositionPreLayout = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED;
int maxPositionPreLayout = Integer.MIN_VALUE;
for (int i = 0; i < count; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getChildAt(i));
if (!holder.shouldIgnore()) {
int pos = holder.getLayoutPosition();
if (pos < minPositionPreLayout) {
minPositionPreLayout = pos;
}
if (pos > maxPositionPreLayout) {
maxPositionPreLayout = pos;
}
}
}
into[0] = minPositionPreLayout;
into[1] = maxPositionPreLayout;
}
private boolean didChildRangeChange(int minPositionPreLayout, int maxPositionPreLayout) {
int count = this.mChildHelper.getChildCount();
if (count != 0) {
for (int i = 0; i < count; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getChildAt(i));
if (!holder.shouldIgnore()) {
int pos = holder.getLayoutPosition();
if (pos < minPositionPreLayout || pos > maxPositionPreLayout) {
return true;
}
}
}
return false;
} else if (minPositionPreLayout == 0 && maxPositionPreLayout == 0) {
return false;
} else {
return true;
}
}
protected void removeDetachedView(View child, boolean animate) {
ViewHolder vh = getChildViewHolderInt(child);
if (vh != null) {
if (vh.isTmpDetached()) {
vh.clearTmpDetachFlag();
} else if (!vh.shouldIgnore()) {
throw new IllegalArgumentException("Called removeDetachedView with a view which is not flagged as tmp detached." + vh);
}
}
dispatchChildDetached(child);
super.removeDetachedView(child, animate);
}
long getChangedHolderKey(ViewHolder holder) {
return this.mAdapter.hasStableIds() ? holder.getItemId() : (long) holder.mPosition;
}
private void animateAppearance(@NonNull ViewHolder itemHolder, @Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
itemHolder.setIsRecyclable(false);
if (this.mItemAnimator.animateAppearance(itemHolder, preLayoutInfo, postLayoutInfo)) {
postAnimationRunner();
}
}
private void animateDisappearance(@NonNull ViewHolder holder, @NonNull ItemHolderInfo preLayoutInfo, @Nullable ItemHolderInfo postLayoutInfo) {
addAnimatingView(holder);
holder.setIsRecyclable(false);
if (this.mItemAnimator.animateDisappearance(holder, preLayoutInfo, postLayoutInfo)) {
postAnimationRunner();
}
}
private void animateChange(@NonNull ViewHolder oldHolder, @NonNull ViewHolder newHolder, @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) {
oldHolder.setIsRecyclable(false);
if (oldHolder != newHolder) {
oldHolder.mShadowedHolder = newHolder;
addAnimatingView(oldHolder);
this.mRecycler.unscrapView(oldHolder);
newHolder.setIsRecyclable(false);
newHolder.mShadowingHolder = oldHolder;
}
if (this.mItemAnimator.animateChange(oldHolder, newHolder, preInfo, postInfo)) {
postAnimationRunner();
}
}
protected void onLayout(boolean changed, int l, int t, int r, int b) {
eatRequestLayout();
TraceCompat.beginSection(TRACE_ON_LAYOUT_TAG);
dispatchLayout();
TraceCompat.endSection();
resumeRequestLayout(false);
this.mFirstLayoutComplete = true;
}
public void requestLayout() {
if (this.mEatRequestLayout || this.mLayoutFrozen) {
this.mLayoutRequestEaten = true;
} else {
super.requestLayout();
}
}
void markItemDecorInsetsDirty() {
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
((LayoutParams) this.mChildHelper.getUnfilteredChildAt(i).getLayoutParams()).mInsetsDirty = true;
}
this.mRecycler.markItemDecorInsetsDirty();
}
public void draw(Canvas c) {
int padding;
int i;
int i2 = 1;
super.draw(c);
int count = this.mItemDecorations.size();
for (int i3 = 0; i3 < count; i3++) {
((ItemDecoration) this.mItemDecorations.get(i3)).onDrawOver(c, this, this.mState);
}
boolean needsInvalidate = false;
if (!(this.mLeftGlow == null || this.mLeftGlow.isFinished())) {
int restore = c.save();
if (this.mClipToPadding) {
padding = getPaddingBottom();
} else {
padding = 0;
}
c.rotate(270.0f);
c.translate((float) ((-getHeight()) + padding), 0.0f);
if (this.mLeftGlow == null || !this.mLeftGlow.draw(c)) {
needsInvalidate = false;
} else {
needsInvalidate = true;
}
c.restoreToCount(restore);
}
if (!(this.mTopGlow == null || this.mTopGlow.isFinished())) {
restore = c.save();
if (this.mClipToPadding) {
c.translate((float) getPaddingLeft(), (float) getPaddingTop());
}
if (this.mTopGlow == null || !this.mTopGlow.draw(c)) {
i = 0;
} else {
i = 1;
}
needsInvalidate |= i;
c.restoreToCount(restore);
}
if (!(this.mRightGlow == null || this.mRightGlow.isFinished())) {
restore = c.save();
int width = getWidth();
if (this.mClipToPadding) {
padding = getPaddingTop();
} else {
padding = 0;
}
c.rotate(90.0f);
c.translate((float) (-padding), (float) (-width));
if (this.mRightGlow == null || !this.mRightGlow.draw(c)) {
i = 0;
} else {
i = 1;
}
needsInvalidate |= i;
c.restoreToCount(restore);
}
if (!(this.mBottomGlow == null || this.mBottomGlow.isFinished())) {
restore = c.save();
c.rotate(180.0f);
if (this.mClipToPadding) {
c.translate((float) ((-getWidth()) + getPaddingRight()), (float) ((-getHeight()) + getPaddingBottom()));
} else {
c.translate((float) (-getWidth()), (float) (-getHeight()));
}
if (this.mBottomGlow == null || !this.mBottomGlow.draw(c)) {
i2 = 0;
}
needsInvalidate |= i2;
c.restoreToCount(restore);
}
if (!needsInvalidate && this.mItemAnimator != null && this.mItemDecorations.size() > 0 && this.mItemAnimator.isRunning()) {
needsInvalidate = true;
}
if (needsInvalidate) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
public void onDraw(Canvas c) {
super.onDraw(c);
int count = this.mItemDecorations.size();
for (int i = 0; i < count; i++) {
((ItemDecoration) this.mItemDecorations.get(i)).onDraw(c, this, this.mState);
}
}
protected boolean checkLayoutParams(android.view.ViewGroup.LayoutParams p) {
return (p instanceof LayoutParams) && this.mLayout.checkLayoutParams((LayoutParams) p);
}
protected android.view.ViewGroup.LayoutParams generateDefaultLayoutParams() {
if (this.mLayout != null) {
return this.mLayout.generateDefaultLayoutParams();
}
throw new IllegalStateException("RecyclerView has no LayoutManager");
}
public android.view.ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
if (this.mLayout != null) {
return this.mLayout.generateLayoutParams(getContext(), attrs);
}
throw new IllegalStateException("RecyclerView has no LayoutManager");
}
protected android.view.ViewGroup.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams p) {
if (this.mLayout != null) {
return this.mLayout.generateLayoutParams(p);
}
throw new IllegalStateException("RecyclerView has no LayoutManager");
}
public boolean isAnimating() {
return this.mItemAnimator != null && this.mItemAnimator.isRunning();
}
void saveOldPositions() {
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (!holder.shouldIgnore()) {
holder.saveOldPosition();
}
}
}
void clearOldPositions() {
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (!holder.shouldIgnore()) {
holder.clearOldPosition();
}
}
this.mRecycler.clearOldPositions();
}
void offsetPositionRecordsForMove(int from, int to) {
int inBetweenOffset;
int childCount = this.mChildHelper.getUnfilteredChildCount();
int start;
int end;
if (from < to) {
start = from;
end = to;
inBetweenOffset = -1;
} else {
start = to;
end = from;
inBetweenOffset = 1;
}
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (holder != null && holder.mPosition >= start && holder.mPosition <= end) {
if (holder.mPosition == from) {
holder.offsetPosition(to - from, false);
} else {
holder.offsetPosition(inBetweenOffset, false);
}
this.mState.mStructureChanged = true;
}
}
this.mRecycler.offsetPositionRecordsForMove(from, to);
requestLayout();
}
void offsetPositionRecordsForInsert(int positionStart, int itemCount) {
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (!(holder == null || holder.shouldIgnore() || holder.mPosition < positionStart)) {
holder.offsetPosition(itemCount, false);
this.mState.mStructureChanged = true;
}
}
this.mRecycler.offsetPositionRecordsForInsert(positionStart, itemCount);
requestLayout();
}
void offsetPositionRecordsForRemove(int positionStart, int itemCount, boolean applyToPreLayout) {
int positionEnd = positionStart + itemCount;
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (!(holder == null || holder.shouldIgnore())) {
if (holder.mPosition >= positionEnd) {
holder.offsetPosition(-itemCount, applyToPreLayout);
this.mState.mStructureChanged = true;
} else if (holder.mPosition >= positionStart) {
holder.flagRemovedAndOffsetPosition(positionStart - 1, -itemCount, applyToPreLayout);
this.mState.mStructureChanged = true;
}
}
}
this.mRecycler.offsetPositionRecordsForRemove(positionStart, itemCount, applyToPreLayout);
requestLayout();
}
void viewRangeUpdate(int positionStart, int itemCount, Object payload) {
int childCount = this.mChildHelper.getUnfilteredChildCount();
int positionEnd = positionStart + itemCount;
for (int i = 0; i < childCount; i++) {
View child = this.mChildHelper.getUnfilteredChildAt(i);
ViewHolder holder = getChildViewHolderInt(child);
if (holder != null && !holder.shouldIgnore() && holder.mPosition >= positionStart && holder.mPosition < positionEnd) {
holder.addFlags(2);
holder.addChangePayload(payload);
((LayoutParams) child.getLayoutParams()).mInsetsDirty = true;
}
}
this.mRecycler.viewRangeUpdate(positionStart, itemCount);
}
private boolean canReuseUpdatedViewHolder(ViewHolder viewHolder) {
return this.mItemAnimator == null || this.mItemAnimator.canReuseUpdatedViewHolder(viewHolder);
}
private void setDataSetChangedAfterLayout() {
if (!this.mDataSetHasChangedAfterLayout) {
this.mDataSetHasChangedAfterLayout = true;
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (!(holder == null || holder.shouldIgnore())) {
holder.addFlags(512);
}
}
this.mRecycler.setAdapterPositionsAsUnknown();
}
}
void markKnownViewsInvalid() {
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (!(holder == null || holder.shouldIgnore())) {
holder.addFlags(6);
}
}
markItemDecorInsetsDirty();
this.mRecycler.markKnownViewsInvalid();
}
public void invalidateItemDecorations() {
if (this.mItemDecorations.size() != 0) {
if (this.mLayout != null) {
this.mLayout.assertNotInLayoutOrScroll("Cannot invalidate item decorations during a scroll or layout");
}
markItemDecorInsetsDirty();
requestLayout();
}
}
public ViewHolder getChildViewHolder(View child) {
Object parent = child.getParent();
if (parent == null || parent == this) {
return getChildViewHolderInt(child);
}
throw new IllegalArgumentException("View " + child + " is not a direct child of " + this);
}
static ViewHolder getChildViewHolderInt(View child) {
if (child == null) {
return null;
}
return ((LayoutParams) child.getLayoutParams()).mViewHolder;
}
@Deprecated
public int getChildPosition(View child) {
return getChildAdapterPosition(child);
}
public int getChildAdapterPosition(View child) {
ViewHolder holder = getChildViewHolderInt(child);
return holder != null ? holder.getAdapterPosition() : -1;
}
public int getChildLayoutPosition(View child) {
ViewHolder holder = getChildViewHolderInt(child);
return holder != null ? holder.getLayoutPosition() : -1;
}
public long getChildItemId(View child) {
if (this.mAdapter == null || !this.mAdapter.hasStableIds()) {
return -1;
}
ViewHolder holder = getChildViewHolderInt(child);
if (holder != null) {
return holder.getItemId();
}
return -1;
}
@Deprecated
public ViewHolder findViewHolderForPosition(int position) {
return findViewHolderForPosition(position, false);
}
public ViewHolder findViewHolderForLayoutPosition(int position) {
return findViewHolderForPosition(position, false);
}
public ViewHolder findViewHolderForAdapterPosition(int position) {
if (this.mDataSetHasChangedAfterLayout) {
return null;
}
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (holder != null && !holder.isRemoved() && getAdapterPositionFor(holder) == position) {
return holder;
}
}
return null;
}
ViewHolder findViewHolderForPosition(int position, boolean checkNewPosition) {
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (!(holder == null || holder.isRemoved())) {
if (checkNewPosition) {
if (holder.mPosition == position) {
return holder;
}
} else if (holder.getLayoutPosition() == position) {
return holder;
}
}
}
return null;
}
public ViewHolder findViewHolderForItemId(long id) {
int childCount = this.mChildHelper.getUnfilteredChildCount();
for (int i = 0; i < childCount; i++) {
ViewHolder holder = getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
if (holder != null && holder.getItemId() == id) {
return holder;
}
}
return null;
}
public View findChildViewUnder(float x, float y) {
for (int i = this.mChildHelper.getChildCount() - 1; i >= 0; i--) {
View child = this.mChildHelper.getChildAt(i);
float translationX = ViewCompat.getTranslationX(child);
float translationY = ViewCompat.getTranslationY(child);
if (x >= ((float) child.getLeft()) + translationX && x <= ((float) child.getRight()) + translationX && y >= ((float) child.getTop()) + translationY && y <= ((float) child.getBottom()) + translationY) {
return child;
}
}
return null;
}
public boolean drawChild(Canvas canvas, View child, long drawingTime) {
return super.drawChild(canvas, child, drawingTime);
}
public void offsetChildrenVertical(int dy) {
int childCount = this.mChildHelper.getChildCount();
for (int i = 0; i < childCount; i++) {
this.mChildHelper.getChildAt(i).offsetTopAndBottom(dy);
}
}
public void onChildAttachedToWindow(View child) {
}
public void onChildDetachedFromWindow(View child) {
}
public void offsetChildrenHorizontal(int dx) {
int childCount = this.mChildHelper.getChildCount();
for (int i = 0; i < childCount; i++) {
this.mChildHelper.getChildAt(i).offsetLeftAndRight(dx);
}
}
Rect getItemDecorInsetsForChild(View child) {
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (!lp.mInsetsDirty) {
return lp.mDecorInsets;
}
Rect insets = lp.mDecorInsets;
insets.set(0, 0, 0, 0);
int decorCount = this.mItemDecorations.size();
for (int i = 0; i < decorCount; i++) {
this.mTempRect.set(0, 0, 0, 0);
((ItemDecoration) this.mItemDecorations.get(i)).getItemOffsets(this.mTempRect, child, this, this.mState);
insets.left += this.mTempRect.left;
insets.top += this.mTempRect.top;
insets.right += this.mTempRect.right;
insets.bottom += this.mTempRect.bottom;
}
lp.mInsetsDirty = false;
return insets;
}
public void onScrolled(int dx, int dy) {
}
void dispatchOnScrolled(int hresult, int vresult) {
int scrollX = getScrollX();
int scrollY = getScrollY();
onScrollChanged(scrollX, scrollY, scrollX, scrollY);
onScrolled(hresult, vresult);
if (this.mScrollListener != null) {
this.mScrollListener.onScrolled(this, hresult, vresult);
}
if (this.mScrollListeners != null) {
for (int i = this.mScrollListeners.size() - 1; i >= 0; i--) {
((OnScrollListener) this.mScrollListeners.get(i)).onScrolled(this, hresult, vresult);
}
}
}
public void onScrollStateChanged(int state) {
}
void dispatchOnScrollStateChanged(int state) {
if (this.mLayout != null) {
this.mLayout.onScrollStateChanged(state);
}
onScrollStateChanged(state);
if (this.mScrollListener != null) {
this.mScrollListener.onScrollStateChanged(this, state);
}
if (this.mScrollListeners != null) {
for (int i = this.mScrollListeners.size() - 1; i >= 0; i--) {
((OnScrollListener) this.mScrollListeners.get(i)).onScrollStateChanged(this, state);
}
}
}
public boolean hasPendingAdapterUpdates() {
return !this.mFirstLayoutComplete || this.mDataSetHasChangedAfterLayout || this.mAdapterHelper.hasPendingUpdates();
}
private void repositionShadowingViews() {
int count = this.mChildHelper.getChildCount();
for (int i = 0; i < count; i++) {
View view = this.mChildHelper.getChildAt(i);
ViewHolder holder = getChildViewHolder(view);
if (!(holder == null || holder.mShadowingHolder == null)) {
View shadowingView = holder.mShadowingHolder.itemView;
int left = view.getLeft();
int top = view.getTop();
if (left != shadowingView.getLeft() || top != shadowingView.getTop()) {
shadowingView.layout(left, top, shadowingView.getWidth() + left, shadowingView.getHeight() + top);
}
}
}
}
private void dispatchChildDetached(View child) {
ViewHolder viewHolder = getChildViewHolderInt(child);
onChildDetachedFromWindow(child);
if (!(this.mAdapter == null || viewHolder == null)) {
this.mAdapter.onViewDetachedFromWindow(viewHolder);
}
if (this.mOnChildAttachStateListeners != null) {
for (int i = this.mOnChildAttachStateListeners.size() - 1; i >= 0; i--) {
((OnChildAttachStateChangeListener) this.mOnChildAttachStateListeners.get(i)).onChildViewDetachedFromWindow(child);
}
}
}
private void dispatchChildAttached(View child) {
ViewHolder viewHolder = getChildViewHolderInt(child);
onChildAttachedToWindow(child);
if (!(this.mAdapter == null || viewHolder == null)) {
this.mAdapter.onViewAttachedToWindow(viewHolder);
}
if (this.mOnChildAttachStateListeners != null) {
for (int i = this.mOnChildAttachStateListeners.size() - 1; i >= 0; i--) {
((OnChildAttachStateChangeListener) this.mOnChildAttachStateListeners.get(i)).onChildViewAttachedToWindow(child);
}
}
}
private int getAdapterPositionFor(ViewHolder viewHolder) {
if (viewHolder.hasAnyOfTheFlags(524) || !viewHolder.isBound()) {
return -1;
}
return this.mAdapterHelper.applyPendingUpdatesToPosition(viewHolder.mPosition);
}
public void setNestedScrollingEnabled(boolean enabled) {
this.mScrollingChildHelper.setNestedScrollingEnabled(enabled);
}
public boolean isNestedScrollingEnabled() {
return this.mScrollingChildHelper.isNestedScrollingEnabled();
}
public boolean startNestedScroll(int axes) {
return this.mScrollingChildHelper.startNestedScroll(axes);
}
public void stopNestedScroll() {
this.mScrollingChildHelper.stopNestedScroll();
}
public boolean hasNestedScrollingParent() {
return this.mScrollingChildHelper.hasNestedScrollingParent();
}
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
return this.mScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return this.mScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return this.mScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return this.mScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
protected int getChildDrawingOrder(int childCount, int i) {
if (this.mChildDrawingOrderCallback == null) {
return super.getChildDrawingOrder(childCount, i);
}
return this.mChildDrawingOrderCallback.onGetChildDrawingOrder(childCount, i);
}
}