/**
* galaxy inc.
* meetup client for android
*/
package com.galaxy.meetup.client.android.ui.view;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.util.SparseArrayCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.VelocityTrackerCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.EdgeEffectCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.Scroller;
import com.galaxy.meetup.client.android.R;
/**
*
* @author sihai
*
*/
public class ColumnGridView extends ViewGroup {
private static final String TAG = "ColumnGridView";
public static final int COLUMN_COUNT_AUTO = -1;
private static final int TOUCH_MODE_IDLE = 0;
private static final int TOUCH_MODE_DRAGGING = 1;
private static final int TOUCH_MODE_FLINGING = 2;
private int mActivePointerId;
private ListAdapter mAdapter;
private Bug6713624LinkedHashMap mBug6713624LinkedHashMap;
private int mColCount;
private int mColCountSetting;
private final Point mCurrentTouchPoint;
private boolean mDataChanged;
private final EdgeEffectCompat mEndEdge;
private int mFirstPosition;
private final int mFlingVelocity;
private boolean mHasStableIds;
private boolean mHorizontalOrientation;
private boolean mInLayout;
private int mItemCount;
private int mItemEnd[];
private int mItemMargin;
private int mItemStart[];
private int mLastScrollState;
private float mLastTouch;
private final SparseArrayCompat mLayoutRecords;
private int mLocation[];
private final int mMaximumVelocity;
private int mMinColWidth;
private final AdapterDataSetObserver mObserver;
private OnScrollListener mOnScrollListener;
private boolean mPopulating;
private boolean mPressed;
private float mRatio;
private final RecycleBin mRecycler;
private int mRestoreOffset;
private int mScrollState;
private final Scroller mScroller;
private final SparseBooleanArray mSelectedPositions;
private ItemSelectionListener mSelectionListener;
private boolean mSelectionMode;
private final Point mSelectionStartPoint;
private Drawable mSelector;
private Runnable mSetPressedRunnable = new Runnable() {
public final void run()
{
mPressed = true;
invalidate();
}
};
private final EdgeEffectCompat mStartEdge;
private float mTouchRemainder;
private final int mTouchSlop;
private final VelocityTracker mVelocityTracker;
private int mVisibleOffset;
public ColumnGridView(Context context) {
this(context, null);
}
public ColumnGridView(Context context, AttributeSet attributeset) {
this(context, attributeset, 0);
}
public ColumnGridView(Context context, AttributeSet attributeset, int i) {
super(context, attributeset, i);
mColCountSetting = 2;
mColCount = 2;
mMinColWidth = 0;
mLayoutRecords = new SparseArrayCompat();
mRecycler = new RecycleBin();
mObserver = new AdapterDataSetObserver();
mVelocityTracker = VelocityTracker.obtain();
mRatio = 1.0F;
mBug6713624LinkedHashMap = new Bug6713624LinkedHashMap();
mSelectedPositions = new SparseBooleanArray();
mSelectionStartPoint = new Point();
mCurrentTouchPoint = new Point(-1, -1);
mLocation = new int[2];
ViewConfiguration viewconfiguration = ViewConfiguration.get(context);
mTouchSlop = viewconfiguration.getScaledTouchSlop();
mMaximumVelocity = viewconfiguration.getScaledMaximumFlingVelocity();
mFlingVelocity = viewconfiguration.getScaledMinimumFlingVelocity();
mScroller = new Scroller(context);
mStartEdge = new EdgeEffectCompat(context);
mEndEdge = new EdgeEffectCompat(context);
setWillNotDraw(false);
setClipToPadding(false);
}
private void checkForSelection(int i, int j) {
if (!mSelectionMode) {
return;
}
int k = mSelectionStartPoint.x - i;
int l = mSelectionStartPoint.y - j;
if (k * k + l * l < mTouchSlop * mTouchSlop) {
int i1 = mFirstPosition;
boolean flag = false;
int j1 = -1 + getChildCount();
while (j1 >= 0) {
View view = getChildAt(j1);
view.getLocationOnScreen(mLocation);
if (i >= mLocation[0] && i <= mLocation[0] + view.getWidth()
&& j >= mLocation[1]
&& j <= mLocation[1] + view.getHeight()) {
int k1 = j1 + i1;
if (isSelected(k1))
deselect(k1);
else
select(k1);
flag = true;
}
j1--;
}
if (flag)
invalidate();
}
}
private void clearAllState() {
mBug6713624LinkedHashMap.put("clearallstate - clear", Integer.valueOf(0));
mLayoutRecords.clear();
removeAllViews();
resetStateForGridTop();
mRecycler.clear();
}
private void clearPressedState() {
if(mPressed)
invalidate();
mPressed = false;
removeCallbacks(mSetPressedRunnable);
}
private int fillDown(int fromPosition, int overhang)
{
final int paddingLeft = getPaddingLeft();
final int paddingRight = getPaddingRight();
final int itemMargin = mItemMargin;
final int colWidth =
(getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount;
final int gridBottom = getHeight() - getPaddingBottom();
final int fillTo = gridBottom + overhang;
int nextCol = getNextColumnDown();
int position = fromPosition;
while (nextCol >= 0 && mItemEnd[nextCol] < fillTo && position < mItemCount) {
final View child = obtainView(position, null);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (child.getParent() != this) {
if (mInLayout) {
addViewInLayout(child, -1, lp);
} else {
addView(child);
}
}
final int span = Math.min(mColCount, lp.minorSpan);
final int widthSize = colWidth * span + itemMargin * (span - 1);
final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
LayoutRecord rec;
if (span > 1) {
rec = getNextRecordDown(position, span, mItemEnd);
nextCol = rec.column;
} else {
rec = (LayoutRecord)mLayoutRecords.get(position);
}
boolean invalidateAfter = false;
if (rec == null) {
rec = new LayoutRecord();
mLayoutRecords.put(position, rec);
rec.column = nextCol;
rec.span = span;
} else if (span != rec.span) {
rec.span = span;
rec.column = nextCol;
invalidateAfter = true;
} else {
nextCol = rec.column;
}
if (mHasStableIds) {
final long id = mAdapter.getItemId(position);
rec.id = id;
lp.id = id;
}
lp.column = nextCol;
final int heightSpec;
if (lp.height == LayoutParams.WRAP_CONTENT) {
heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
} else {
heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
}
child.measure(widthSpec, heightSpec);
final int childHeight = child.getMeasuredHeight();
if (invalidateAfter || (childHeight != rec.size && rec.size > 0)) {
invalidateLayoutRecordsAfterPosition(position);
}
rec.size = childHeight;
final int startFrom;
if (span > 1) {
int lowest = mItemEnd[nextCol];
for (int i = nextCol + 1; i < nextCol + span; i++) {
final int bottom = mItemEnd[i];
if (bottom > lowest) {
lowest = bottom;
}
}
startFrom = lowest;
} else {
startFrom = mItemEnd[nextCol];
}
final int childTop = startFrom + itemMargin;
final int childBottom = childTop + childHeight;
final int childLeft = paddingLeft + nextCol * (colWidth + itemMargin);
final int childRight = childLeft + child.getMeasuredWidth();
child.layout(childLeft, childTop, childRight, childBottom);
for (int i = nextCol; i < nextCol + span; i++) {
mItemEnd[i] = childBottom + rec.getMarginAfter(i - nextCol);
}
nextCol = getNextColumnDown();
position++;
}
int lowestView = 0;
for (int i = 0; i < mColCount; i++) {
if (mItemEnd[i] > lowestView) {
lowestView = mItemEnd[i];
}
}
return lowestView - gridBottom;
}
private int fillUp(int fromPosition, int overhang) {
final int paddingLeft = getPaddingLeft();
final int paddingRight = getPaddingRight();
final int itemMargin = mItemMargin;
final int colWidth =
(getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount;
final int gridTop = getPaddingTop();
final int fillTo = gridTop - overhang;
int nextCol = getNextColumnUp();
int position = fromPosition;
while (nextCol >= 0 && mItemStart[nextCol] > fillTo && position >= 0) {
final View child = obtainView(position, null);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (child.getParent() != this) {
if (mInLayout) {
addViewInLayout(child, 0, lp);
} else {
addView(child, 0);
}
}
final int span = Math.min(mColCount, lp.minorSpan);
final int widthSize = colWidth * span + itemMargin * (span - 1);
final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
LayoutRecord rec;
if (span > 1) {
rec = getNextRecordUp(position, span);
nextCol = rec.column;
} else {
rec = (LayoutRecord)mLayoutRecords.get(position);
}
boolean invalidateBefore = false;
if (rec == null) {
rec = new LayoutRecord();
mLayoutRecords.put(position, rec);
rec.column = nextCol;
rec.span = span;
} else if (span != rec.span) {
rec.span = span;
rec.column = nextCol;
invalidateBefore = true;
} else {
nextCol = rec.column;
}
if (mHasStableIds) {
final long id = mAdapter.getItemId(position);
rec.id = id;
lp.id = id;
}
lp.column = nextCol;
final int heightSpec;
if (lp.height == LayoutParams.WRAP_CONTENT) {
heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
} else {
heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
}
child.measure(widthSpec, heightSpec);
final int childHeight = child.getMeasuredHeight();
if (invalidateBefore || (childHeight != rec.size && rec.size > 0)) {
invalidateLayoutRecordsBeforePosition(position);
}
rec.size = childHeight;
final int startFrom;
if (span > 1) {
int highest = mItemStart[nextCol];
for (int i = nextCol + 1; i < nextCol + span; i++) {
final int top = mItemStart[i];
if (top < highest) {
highest = top;
}
}
startFrom = highest;
} else {
startFrom = mItemStart[nextCol];
}
final int childBottom = startFrom;
final int childTop = childBottom - childHeight;
final int childLeft = paddingLeft + nextCol * (colWidth + itemMargin);
final int childRight = childLeft + child.getMeasuredWidth();
child.layout(childLeft, childTop, childRight, childBottom);
for (int i = nextCol; i < nextCol + span; i++) {
mItemStart[i] = childTop - rec.getMarginBefore(i - nextCol) - itemMargin;
}
nextCol = getNextColumnUp();
mFirstPosition = position--;
}
int highestView = getHeight();
for (int i = 0; i < mColCount; i++) {
if (mItemStart[i] < highestView) {
highestView = mItemStart[i];
}
}
return gridTop - highestView;
}
/**
* Return a LayoutRecord for the given position
* @param position
* @param span
* @return
*/
final LayoutRecord getNextRecordUp(int position, int span) {
LayoutRecord rec = (LayoutRecord)mLayoutRecords.get(position);
if (rec == null) {
rec = new LayoutRecord();
rec.span = span;
mLayoutRecords.put(position, rec);
} else if (rec.span != span) {
throw new IllegalStateException("Invalid LayoutRecord! Record had span=" + rec.span +
" but caller requested span=" + span + " for position=" + position);
}
int targetCol = -1;
int bottomMost = Integer.MIN_VALUE;
final int colCount = mColCount;
for (int i = colCount - span; i >= 0; i--) {
int top = Integer.MAX_VALUE;
for (int j = i; j < i + span; j++) {
final int singleTop = mItemStart[j];
if (singleTop < top) {
top = singleTop;
}
}
if (top > bottomMost) {
bottomMost = top;
targetCol = i;
}
}
rec.column = targetCol;
for (int i = 0; i < span; i++) {
rec.setMarginAfter(i, mItemStart[i + targetCol] - bottomMost);
}
return rec;
}
public LayoutParams generateDefaultLayoutParams() {
int i;
if(mHorizontalOrientation)
i = 1;
else
i = 2;
return new LayoutParams(i, -2, 1, 1);
}
public LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams layoutparams) {
LayoutParams layoutparams1 = new LayoutParams(layoutparams);
int i;
if(mHorizontalOrientation)
i = 1;
else
i = 2;
layoutparams1.orientation = i;
return layoutparams1;
}
final int getNextColumnDown() {
int result = -1;
int topMost = Integer.MAX_VALUE;
final int colCount = mColCount;
for (int i = 0; i < colCount; i++) {
final int bottom = mItemEnd[i];
if (bottom < topMost) {
topMost = bottom;
result = i;
}
}
return result;
}
private int getNextColumnUp() {
int i = -1;
int j = 0x80000000;
for(int k = -1 + mColCount; k >= 0; k--)
{
int l = mItemStart[k];
if(l > j)
{
j = l;
i = k;
}
}
return i;
}
private LayoutRecord getNextRecordDown(int i, int j, int ai[]) {
mBug6713624LinkedHashMap.put("getnextrecorddown - get", Integer.valueOf(i));
LayoutRecord layoutrecord = (LayoutRecord)mLayoutRecords.get(i);
int k;
int l;
int i1;
if(layoutrecord == null)
{
layoutrecord = new LayoutRecord();
layoutrecord.span = j;
mBug6713624LinkedHashMap.put("getnextrecorddown - put", Integer.valueOf(i));
mLayoutRecords.put(i, layoutrecord);
} else
if(layoutrecord.span != j)
throw new IllegalStateException((new StringBuilder("Invalid LayoutRecord! Record had span=")).append(layoutrecord.span).append(" but caller requested span=").append(j).append(" for position=").append(i).toString());
k = -1;
l = 0x7fffffff;
i1 = mColCount;
for(int j1 = 0; j1 <= i1 - j; j1++)
{
int l1 = 0x80000000;
for(int i2 = j1; i2 < j1 + j; i2++)
{
int j2 = ai[i2];
if(j2 > l1)
l1 = j2;
}
if(l1 < l)
{
l = l1;
k = j1;
}
}
layoutrecord.column = k;
for(int k1 = 0; k1 < j; k1++)
layoutrecord.setMarginBefore(k1, l - ai[k1 + k]);
return layoutrecord;
}
private void invalidateLayoutRecordsAfterPosition(int i)
{
int j;
for(j = -1 + mLayoutRecords.size(); j >= 0 && mLayoutRecords.keyAt(j) > i; j--);
int k = j + 1;
mBug6713624LinkedHashMap.put("invalidateafter - removeatrange", Integer.valueOf(mLayoutRecords.size() - k));
mLayoutRecords.removeAtRange(k + 1, mLayoutRecords.size() - k);
}
private void invalidateLayoutRecordsBeforePosition(int i)
{
int j;
for(j = 0; j < mLayoutRecords.size() && mLayoutRecords.keyAt(j) < i; j++);
mBug6713624LinkedHashMap.put("invalidatebefore - removeatrange", Integer.valueOf(j));
mLayoutRecords.removeAtRange(0, j);
}
private void invokeOnItemScrollListener(int i)
{
if(mOnScrollListener != null)
mOnScrollListener.onScroll(this, mFirstPosition, mVisibleOffset, getChildCount(), mItemCount, i);
onScrollChanged(0, 0, 0, 0);
}
private boolean isSelected(int i)
{
return mSelectedPositions.get(i, false);
}
private View obtainView(int i, View view)
{
View view1 = mRecycler.getTransientStateView(i);
View view4;
if(view1 != null)
{
view4 = view1;
} else
{
int j;
int k;
View view2;
View view3;
Object obj;
if(view != null)
j = ((LayoutParams)view.getLayoutParams()).viewType;
else
j = -1;
k = mAdapter.getItemViewType(i);
if(j == k)
view2 = view;
else
view2 = mRecycler.getScrapView(k);
view3 = mAdapter.getView(i, view2, this);
if(view3 != view2 && view2 != null)
mRecycler.addScrap(view2);
LayoutParams layoutparams;
obj = view3.getLayoutParams();
if(view3.getParent() != this)
{
if(obj == null)
{
Log.e("ColumnGridView", (new StringBuilder("view at position ")).append(i).append(" doesn't have layout parameters;using default layout paramters").toString());
obj = generateDefaultLayoutParams();
} else
if(!checkLayoutParams(((android.view.ViewGroup.LayoutParams) (obj))))
{
Log.e("ColumnGridView", (new StringBuilder("view at position ")).append(i).append(" doesn't have layout parameters of type ColumnGridView.LayoutParams; wrapping parameters").toString());
obj = generateLayoutParams(((android.view.ViewGroup.LayoutParams) (obj)));
}
view3.setLayoutParams(((android.view.ViewGroup.LayoutParams) (obj)));
}
layoutparams = (LayoutParams)obj;
layoutparams.position = i;
layoutparams.viewType = k;
view4 = view3;
}
return view4;
}
private void populate() {
if (getWidth() == 0 || getHeight() == 0) {
return;
}
if (mColCount == COLUMN_COUNT_AUTO) {
final int colCount = getWidth() / mMinColWidth;
if (colCount != mColCount) {
mColCount = colCount;
}
}
final int colCount = mColCount;
if (mItemStart == null || mItemStart.length != colCount) {
mItemStart = new int[colCount];
mItemEnd = new int[colCount];
final int top = getPaddingTop();
final int offset = top + Math.min(mRestoreOffset, 0);
Arrays.fill(mItemStart, offset);
Arrays.fill(mItemEnd, offset);
mLayoutRecords.clear();
if (mInLayout) {
removeAllViewsInLayout();
} else {
removeAllViews();
}
mRestoreOffset = 0;
}
mPopulating = true;
layoutChildren(mDataChanged);
fillDown(mFirstPosition + getChildCount(), 0);
fillUp(mFirstPosition - 1, 0);
mPopulating = false;
mDataChanged = false;
}
/**
* Measure and layout all currently visible children.
*
* @param queryAdapter true to requery the adapter for view data
*/
final void layoutChildren(boolean queryAdapter) {
final int paddingLeft = getPaddingLeft();
final int paddingRight = getPaddingRight();
final int itemMargin = mItemMargin;
final int colWidth =
(getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount;
int rebuildLayoutRecordsBefore = -1;
int rebuildLayoutRecordsAfter = -1;
Arrays.fill(mItemEnd, Integer.MIN_VALUE);
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int col = lp.column;
final int position = mFirstPosition + i;
final boolean needsLayout = queryAdapter || child.isLayoutRequested();
if (queryAdapter) {
View newView = obtainView(position, child);
if (newView != child) {
removeViewAt(i);
addView(newView, i);
child = newView;
}
lp = (LayoutParams) child.getLayoutParams(); // Might have changed
}
final int span = Math.min(mColCount, lp.minorSpan);
final int widthSize = colWidth * span + itemMargin * (span - 1);
if (needsLayout) {
final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
final int heightSpec;
if (lp.height == LayoutParams.WRAP_CONTENT) {
heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
} else {
heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
}
child.measure(widthSpec, heightSpec);
}
int childTop = mItemEnd[col] > Integer.MIN_VALUE ?
mItemEnd[col] + mItemMargin : child.getTop();
if (span > 1) {
int lowest = childTop;
for (int j = col + 1; j < col + span; j++) {
final int bottom = mItemEnd[j] + mItemMargin;
if (bottom > lowest) {
lowest = bottom;
}
}
childTop = lowest;
}
final int childHeight = child.getMeasuredHeight();
final int childBottom = childTop + childHeight;
final int childLeft = paddingLeft + col * (colWidth + itemMargin);
final int childRight = childLeft + child.getMeasuredWidth();
child.layout(childLeft, childTop, childRight, childBottom);
for (int j = col; j < col + span; j++) {
mItemEnd[j] = childBottom;
}
final LayoutRecord rec = (LayoutRecord)mLayoutRecords.get(position);
if (rec != null && rec.size != childHeight) {
// Invalidate our layout records for everything before this.
rec.size = childHeight;
rebuildLayoutRecordsBefore = position;
}
if (rec != null && rec.span != span) {
// Invalidate our layout records for everything after this.
rec.span = span;
rebuildLayoutRecordsAfter = position;
}
}
// Update mItemEnd for any empty columns
for (int i = 0; i < mColCount; i++) {
if (mItemEnd[i] == Integer.MIN_VALUE) {
mItemEnd[i] = mItemStart[i];
}
}
if (rebuildLayoutRecordsBefore >= 0 || rebuildLayoutRecordsAfter >= 0) {
if (rebuildLayoutRecordsBefore >= 0) {
invalidateLayoutRecordsBeforePosition(rebuildLayoutRecordsBefore);
}
if (rebuildLayoutRecordsAfter >= 0) {
invalidateLayoutRecordsAfterPosition(rebuildLayoutRecordsAfter);
}
for (int i = 0; i < childCount; i++) {
final int position = mFirstPosition + i;
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
LayoutRecord rec = (LayoutRecord)mLayoutRecords.get(position);
if (rec == null) {
rec = new LayoutRecord();
mLayoutRecords.put(position, rec);
}
rec.column = lp.column;
rec.size = child.getHeight();
rec.id = lp.id;
rec.span = Math.min(mColCount, lp.minorSpan);
}
}
}
private void reportScrollStateChange(int i)
{
if(i != mLastScrollState)
{
mLastScrollState = i;
if(mOnScrollListener != null)
mOnScrollListener.onScrollStateChanged(this, i);
}
}
private void resetStateForGridTop()
{
int i = mColCount;
if(i != -1)
{
if(mItemStart == null || mItemStart.length != i)
{
mItemStart = new int[i];
mItemEnd = new int[i];
}
int j = getPaddingTop();
Arrays.fill(mItemStart, j);
Arrays.fill(mItemEnd, j);
}
mFirstPosition = 0;
mVisibleOffset = 0;
mRestoreOffset = 0;
}
private void setVisibleOffset()
{
int i = -mItemMargin;
mVisibleOffset = 0;
int j = 0;
int k = getChildCount();
do
{
if(j >= k)
break;
View view = getChildAt(j);
int l;
if(mHorizontalOrientation)
l = view.getRight();
else
l = view.getBottom();
if(l >= i)
break;
mVisibleOffset = 1 + mVisibleOffset;
j++;
} while(true);
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
final int y = mScroller.getCurrY();
final int dy = (int) (y - mLastTouch);
mLastTouch = y;
final boolean stopped = !trackMotionScroll(dy, false);
if (!stopped && !mScroller.isFinished()) {
ViewCompat.postInvalidateOnAnimation(this);
} else {
if (stopped) {
final int overScrollMode = ViewCompat.getOverScrollMode(this);
if (overScrollMode != ViewCompat.OVER_SCROLL_NEVER) {
final EdgeEffectCompat edge;
if (dy > 0) {
edge = mStartEdge;
} else {
edge = mEndEdge;
}
edge.onAbsorb(Math.abs((int) mScroller.getCurrVelocity()));
ViewCompat.postInvalidateOnAnimation(this);
}
mScroller.abortAnimation();
}
mScrollState = TOUCH_MODE_IDLE;
}
}
}
/**
*
* @param deltaY Pixels that content should move by
* @return true if the movement completed, false if it was stopped prematurely.
*/
private boolean trackMotionScroll(int deltaY, boolean allowOverScroll) {
final boolean contentFits = contentFits();
final int allowOverhang = Math.abs(deltaY);
final int overScrolledBy;
final int movedBy;
if (!contentFits) {
final int overhang;
final boolean up;
mPopulating = true;
if (deltaY > 0) {
overhang = fillUp(mFirstPosition - 1, allowOverhang);
up = true;
} else {
overhang = fillDown(mFirstPosition + getChildCount(), allowOverhang) + mItemMargin;
up = false;
}
movedBy = Math.min(overhang, allowOverhang);
offsetChildren(up ? movedBy : -movedBy);
recycleOffscreenViews();
mPopulating = false;
overScrolledBy = allowOverhang - overhang;
} else {
overScrolledBy = allowOverhang;
movedBy = 0;
}
if (allowOverScroll) {
final int overScrollMode = ViewCompat.getOverScrollMode(this);
if (overScrollMode == ViewCompat.OVER_SCROLL_ALWAYS ||
(overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits)) {
if (overScrolledBy > 0) {
EdgeEffectCompat edge = deltaY > 0 ? mStartEdge : mEndEdge;
edge.onPull((float) Math.abs(deltaY) / getHeight());
ViewCompat.postInvalidateOnAnimation(this);
}
}
}
return deltaY == 0 || movedBy != 0;
}
private void recycleOffscreenViews() {
final int height = getHeight();
final int clearAbove = -mItemMargin;
final int clearBelow = height + mItemMargin;
for (int i = getChildCount() - 1; i >= 0; i--) {
final View child = getChildAt(i);
if (child.getTop() <= clearBelow) {
// There may be other offscreen views, but we need to maintain
// the invariant documented above.
break;
}
if (mInLayout) {
removeViewsInLayout(i, 1);
} else {
removeViewAt(i);
}
mRecycler.addScrap(child);
}
while (getChildCount() > 0) {
final View child = getChildAt(0);
if (child.getBottom() >= clearAbove) {
// There may be other offscreen views, but we need to maintain
// the invariant documented above.
break;
}
if (mInLayout) {
removeViewsInLayout(0, 1);
} else {
removeViewAt(0);
}
mRecycler.addScrap(child);
mFirstPosition++;
}
final int childCount = getChildCount();
if (childCount > 0) {
// Repair the top and bottom column boundaries from the views we still have
Arrays.fill(mItemStart, Integer.MAX_VALUE);
Arrays.fill(mItemEnd, Integer.MIN_VALUE);
for (int i = 0; i < childCount; i++){
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int top = child.getTop() - mItemMargin;
final int bottom = child.getBottom();
final LayoutRecord rec = (LayoutRecord)mLayoutRecords.get(mFirstPosition + i);
final int colEnd = lp.column + Math.min(mColCount, lp.minorSpan);
for (int col = lp.column; col < colEnd; col++) {
final int colTop = top - rec.getMarginBefore(col - lp.column);
final int colBottom = bottom + rec.getMarginAfter(col - lp.column);
if (colTop < mItemStart[col]) {
mItemStart[col] = colTop;
}
if (colBottom > mItemEnd[col]) {
mItemEnd[col] = colBottom;
}
}
}
for (int col = 0; col < mColCount; col++) {
if (mItemStart[col] == Integer.MAX_VALUE) {
// If one was untouched, both were.
mItemStart[col] = 0;
mItemEnd[col] = 0;
}
}
}
}
final void offsetChildren(int offset) {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
child.layout(child.getLeft(), child.getTop() + offset,
child.getRight(), child.getBottom() + offset);
}
final int colCount = mColCount;
for (int i = 0; i < colCount; i++) {
mItemStart[i] += offset;
mItemEnd[i] += offset;
}
}
private final boolean contentFits() {
if (mFirstPosition != 0 || getChildCount() != mItemCount) {
return false;
}
int topmost = Integer.MAX_VALUE;
int bottommost = Integer.MIN_VALUE;
for (int i = 0; i < mColCount; i++) {
if (mItemStart[i] < topmost) {
topmost = mItemStart[i];
}
if (mItemEnd[i] > bottommost) {
bottommost = mItemEnd[i];
}
}
return topmost >= getPaddingTop() && bottommost <= getHeight() - getPaddingBottom();
}
public final void deselect(int i)
{
if(mSelectionMode && mSelectedPositions.get(i))
{
mSelectedPositions.put(i, false);
View view = getChildAt(i - mFirstPosition);
if(mSelectionListener != null)
mSelectionListener.onItemDeselected(view, i);
}
}
public void dispatchDraw(Canvas canvas)
{
super.dispatchDraw(canvas);
if(mSelector != null)
{
int i = getPaddingLeft();
int j = getRight() - getPaddingRight();
int k = getPaddingTop();
int l = getBottom() - getPaddingBottom();
int i1 = -1 + getChildCount();
for(; i1 >= 0; i1--)
{
View view = getChildAt(i1);
if(!isSelected(i1 + mFirstPosition))
{
if(!mPressed || mCurrentTouchPoint.x < 0 || mCurrentTouchPoint.y < 0 || (view instanceof PressedHighlightable) && !((PressedHighlightable)view).shouldHighlightOnPress())
continue;
view.getLocationOnScreen(mLocation);
if(mCurrentTouchPoint.x < mLocation[0] || mCurrentTouchPoint.x > mLocation[0] + view.getWidth() || mCurrentTouchPoint.y < mLocation[1] || mCurrentTouchPoint.y > mLocation[1] + view.getHeight())
continue;
}
int j1 = view.getLeft();
int k1 = view.getRight();
int l1 = view.getTop();
int i2 = view.getBottom();
if(j1 <= j && k1 >= i && l1 <= l && i2 >= k)
{
mSelector.setBounds(j1, l1, k1, i2);
mSelector.draw(canvas);
}
}
}
return;
}
public void draw(Canvas canvas)
{
super.draw(canvas);
if(mStartEdge != null)
{
boolean flag = mStartEdge.isFinished();
boolean flag1 = false;
int k;
if(!flag)
{
if(mHorizontalOrientation)
{
int l = canvas.save();
canvas.rotate(270F);
canvas.translate(-getHeight(), 0.0F);
mStartEdge.draw(canvas);
canvas.restoreToCount(l);
} else
{
mStartEdge.draw(canvas);
}
flag1 = true;
}
if(!mEndEdge.isFinished())
{
if(mHorizontalOrientation)
{
k = canvas.save();
canvas.rotate(90F);
canvas.translate(0.0F, -getWidth());
mEndEdge.draw(canvas);
canvas.restoreToCount(k);
} else
{
int i = canvas.save();
int j = getWidth();
canvas.translate(-j, getHeight());
canvas.rotate(180F, j, 0.0F);
mEndEdge.draw(canvas);
canvas.restoreToCount(i);
}
flag1 = true;
}
if(flag1)
ViewCompat.postInvalidateOnAnimation(this);
}
}
public final void endSelectionMode()
{
if(!mSelectionMode)
throw new IllegalStateException("Not in selection mode!");
mSelectionMode = false;
if(mSelectedPositions.size() > 0)
invalidate();
mSelectedPositions.clear();
}
public android.view.ViewGroup.LayoutParams generateLayoutParams(AttributeSet attributeset)
{
return new LayoutParams(getContext(), attributeset);
}
public final ListAdapter getAdapter()
{
return mAdapter;
}
public final int getColumnCount()
{
return mColCount;
}
public final int getColumnSize()
{
int i;
int j;
int k;
if(mHorizontalOrientation)
i = getPaddingTop();
else
i = getPaddingLeft();
if(mHorizontalOrientation)
j = getPaddingBottom();
else
j = getPaddingRight();
if(mHorizontalOrientation)
k = getHeight();
else
k = getWidth();
return (k - i - j - mItemMargin * (-1 + mColCount)) / mColCount;
}
public final int getFirstVisiblePosition()
{
return mFirstPosition;
}
public final int getLastVisiblePosition()
{
return -1 + (mFirstPosition + getChildCount());
}
public final void invalidateViews()
{
mDataChanged = true;
requestLayout();
invalidate();
}
public final boolean isInSelectionMode()
{
return mSelectionMode;
}
protected void onDetachedFromWindow()
{
super.onDetachedFromWindow();
removeCallbacks(mSetPressedRunnable);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent motionevent) {
boolean flag = true;
mVelocityTracker.addMovement(motionevent);
final int action = motionevent.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mCurrentTouchPoint.set((int) motionevent.getRawX(),
(int) motionevent.getRawY());
postDelayed(mSetPressedRunnable, ViewConfiguration.getTapTimeout());
mVelocityTracker.clear();
mScroller.abortAnimation();
if (mHorizontalOrientation)
mLastTouch = motionevent.getX();
else
mLastTouch = motionevent.getY();
mActivePointerId = MotionEventCompat.getPointerId(motionevent, 0);
mTouchRemainder = 0.0F;
if (mScrollState == TOUCH_MODE_FLINGING)
mScrollState = ((flag) ? TOUCH_MODE_DRAGGING : TOUCH_MODE_IDLE);
else if (!mSelectionMode) {
// FIXME
}
break;
case 1:
case 3:
mCurrentTouchPoint.set(-1, -1);
clearPressedState();
flag = false;
break;
case 2:
int i = MotionEventCompat.findPointerIndex(motionevent,
mActivePointerId);
if (i < 0) {
Log.e("ColumnGridView",
(new StringBuilder(
"onInterceptTouchEvent could not find pointer with id "))
.append(mActivePointerId)
.append(" - did we receive an inconsistent event stream?")
.toString());
flag = false;
} else {
float f;
float f1;
if (mHorizontalOrientation)
f = MotionEventCompat.getX(motionevent, i);
else
f = MotionEventCompat.getY(motionevent, i);
f1 = (f - mLastTouch) + mTouchRemainder;
mTouchRemainder = f1 - (float) (int) f1;
if (Math.abs(f1) > (float) mTouchSlop)
mScrollState = ((flag) ? TOUCH_MODE_DRAGGING : TOUCH_MODE_IDLE);
}
break;
default:
flag = false;
break;
}
return flag;
}
protected void onLayout(boolean flag, int i, int j, int k, int l)
{
mInLayout = true;
populate();
mInLayout = false;
int i1 = k - i;
int j1 = l - j;
if(mHorizontalOrientation)
{
mStartEdge.setSize(j1, i1);
mEndEdge.setSize(j1, i1);
} else
{
mStartEdge.setSize(i1, j1);
mEndEdge.setSize(i1, j1);
}
invokeOnItemScrollListener(0);
}
protected void onMeasure(int i, int j)
{
int k = android.view.View.MeasureSpec.getMode(i);
int l = android.view.View.MeasureSpec.getMode(j);
int i1 = android.view.View.MeasureSpec.getSize(i);
int j1 = android.view.View.MeasureSpec.getSize(j);
if(k != 0x40000000)
Log.e("ColumnGridView", (new StringBuilder("onMeasure: must have an exact width or match_parent! Using fallback spec of EXACTLY ")).append(i1).toString());
if(l != 0x40000000)
Log.e("ColumnGridView", (new StringBuilder("onMeasure: must have an exact height or match_parent! Using fallback spec of EXACTLY ")).append(j1).toString());
setMeasuredDimension(i1, j1);
if(mColCountSetting == -1 && j1 > 0 && i1 > 0)
{
int k1;
if(mHorizontalOrientation)
k1 = j1 / mMinColWidth;
else
k1 = i1 / mMinColWidth;
mColCount = k1;
}
}
public final void onPause()
{
clearPressedState();
}
public void onRestoreInstanceState(Parcelable parcelable)
{
SavedState savedstate = (SavedState)parcelable;
super.onRestoreInstanceState(savedstate.getSuperState());
mDataChanged = true;
mFirstPosition = savedstate.position;
mVisibleOffset = savedstate.visibleOffset;
mRestoreOffset = savedstate.topOffset;
mSelectedPositions.clear();
for(int i = -1 + savedstate.selectedPositions.size(); i >= 0; i--)
mSelectedPositions.put(savedstate.selectedPositions.keyAt(i), savedstate.selectedPositions.valueAt(i));
mSelectionMode = savedstate.selectionMode;
requestLayout();
}
public final void onResume()
{
clearPressedState();
}
public Parcelable onSaveInstanceState()
{
SavedState savedstate = new SavedState(super.onSaveInstanceState());
int i = mFirstPosition;
int j = mVisibleOffset;
savedstate.position = i;
savedstate.visibleOffset = j;
if(i >= 0 && mAdapter != null && i < mAdapter.getCount())
savedstate.firstId = mAdapter.getItemId(i);
int k = mSelectedPositions.size();
SparseBooleanArray sparsebooleanarray = new SparseBooleanArray(k);
for(int l = k - 1; l >= 0; l--)
sparsebooleanarray.put(mSelectedPositions.keyAt(l), mSelectedPositions.valueAt(l));
savedstate.selectedPositions = sparsebooleanarray;
savedstate.selectionMode = mSelectionMode;
int i1 = getChildCount();
int j1 = 0;
// FIXME
return savedstate;
}
public boolean onTouchEvent(MotionEvent motionevent) {
mVelocityTracker.addMovement(motionevent);
final int action = motionevent.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mCurrentTouchPoint.set((int)motionevent.getRawX(), (int)motionevent.getRawY());
mSelectionStartPoint.set((int)motionevent.getRawX(), (int)motionevent.getRawY());
postDelayed(mSetPressedRunnable, ViewConfiguration.getTapTimeout());
mVelocityTracker.clear();
mScroller.abortAnimation();
if(mHorizontalOrientation)
mLastTouch = motionevent.getX();
else
mLastTouch = motionevent.getY();
mActivePointerId = MotionEventCompat.getPointerId(motionevent, 0);
mTouchRemainder = 0.0F;
reportScrollStateChange(mScrollState);
break;
case MotionEvent.ACTION_MOVE: {
mCurrentTouchPoint.set((int)motionevent.getRawX(), (int)motionevent.getRawY());
clearPressedState();
final int index = MotionEventCompat.findPointerIndex(motionevent, mActivePointerId);
if (index < 0) {
Log.e(TAG, "onInterceptTouchEvent could not find pointer with id " +
mActivePointerId + " - did StaggeredGridView receive an inconsistent " +
"event stream?");
return false;
}
float y;
float dy;
if(mHorizontalOrientation)
y = MotionEventCompat.getX(motionevent, index);
else
y = MotionEventCompat.getY(motionevent, index);
dy = (y - mLastTouch) + mTouchRemainder;
final int deltaY = (int) dy;
mTouchRemainder = dy - (float)deltaY;
if(Math.abs(dy) > (float)mTouchSlop)
mScrollState = TOUCH_MODE_DRAGGING;
if(mScrollState == TOUCH_MODE_DRAGGING)
{
mLastTouch = y;
if(!trackMotionScroll(deltaY, true))
mVelocityTracker.clear();
}
break;
}
case MotionEvent.ACTION_CANCEL:
mCurrentTouchPoint.set(-1, -1);
clearPressedState();
mScrollState = TOUCH_MODE_IDLE;
reportScrollStateChange(mScrollState);
break;
case MotionEvent.ACTION_UP: {
mCurrentTouchPoint.set(-1, -1);
clearPressedState();
mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
float f;
if(mHorizontalOrientation)
f = VelocityTrackerCompat.getXVelocity(mVelocityTracker, mActivePointerId);
else
f = VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId);
if(Math.abs(f) > (float)mFlingVelocity)
{
mScrollState = TOUCH_MODE_FLINGING;
int i;
int j;
if(mHorizontalOrientation)
i = (int)f;
else
i = 0;
if(mHorizontalOrientation)
j = 0;
else
j = (int)f;
mScroller.fling(0, 0, i, j, 0x80000000, 0x7fffffff, 0x80000000, 0x7fffffff);
mLastTouch = 0.0F;
ViewCompat.postInvalidateOnAnimation(this);
} else
{
mScrollState = TOUCH_MODE_IDLE;
}
checkForSelection((int)motionevent.getRawX(), (int)motionevent.getRawY());
reportScrollStateChange(mScrollState);
break;
}
default:{
reportScrollStateChange(mScrollState);
break;
}
}
return true;
}
public final void registerSelectionListener(ItemSelectionListener itemselectionlistener)
{
mSelectionListener = itemselectionlistener;
}
public void requestDisallowInterceptTouchEvent(boolean flag)
{
if(flag)
{
mCurrentTouchPoint.set(-1, -1);
clearPressedState();
}
super.requestDisallowInterceptTouchEvent(flag);
}
public void requestLayout()
{
if(!mPopulating)
super.requestLayout();
}
public final void select(int i)
{
if(mSelectionMode && !mSelectedPositions.get(i))
{
mSelectedPositions.put(i, true);
View view = getChildAt(i - mFirstPosition);
if(mSelectionListener != null)
mSelectionListener.onItemSelected(view, i);
}
}
public void setAdapter(ListAdapter listadapter)
{
if(mAdapter != null)
{
mAdapter.unregisterDataSetObserver(mObserver);
clearAllState();
}
mAdapter = listadapter;
mDataChanged = true;
int i;
if(listadapter != null)
i = listadapter.getCount();
else
i = 0;
mItemCount = i;
if(listadapter != null)
{
listadapter.registerDataSetObserver(mObserver);
mRecycler.setViewTypeCount(listadapter.getViewTypeCount());
mHasStableIds = listadapter.hasStableIds();
} else
{
mHasStableIds = false;
}
if(mSelectionMode)
endSelectionMode();
populate();
}
public void setColumnCount(int i)
{
if(i <= 0 && i != -1)
throw new IllegalArgumentException((new StringBuilder("colCount must be at least 1 - received ")).append(i).toString());
boolean flag;
if(i != mColCount)
flag = true;
else
flag = false;
mColCountSetting = i;
mColCount = i;
if(flag)
populate();
}
public void setItemMargin(int i)
{
boolean flag;
if(i != mItemMargin)
flag = true;
else
flag = false;
mItemMargin = i;
if(flag)
populate();
}
public void setMinColumnWidth(int i)
{
mMinColWidth = i;
setColumnCount(-1);
}
public void setOnScrollListener(OnScrollListener onscrolllistener)
{
mOnScrollListener = onscrolllistener;
invokeOnItemScrollListener(0);
}
public void setOrientation(int i)
{
boolean flag = true;
if(i != 1)
flag = false;
mHorizontalOrientation = flag;
}
public void setRatio(float f)
{
mRatio = f;
}
public void setRecyclerListener(RecyclerListener recyclerlistener)
{
mRecycler.mRecyclerListener = recyclerlistener;
}
public void setSelection(int i)
{
setSelectionFromTop(i, 0);
}
public void setSelectionFromTop(int i, int j)
{
if(mAdapter != null)
{
mFirstPosition = Math.max(0, i);
mVisibleOffset = 0;
mRestoreOffset = j;
requestLayout();
}
}
public void setSelectionToTop()
{
removeAllViews();
resetStateForGridTop();
populate();
}
public void setSelector(int i)
{
if(i == 0)
mSelector = null;
else
mSelector = getResources().getDrawable(i);
}
public void setSelector(Drawable drawable)
{
mSelector = drawable;
}
public final void startSelectionMode()
{
if(mSelectionMode)
{
throw new IllegalStateException("Already in selection mode!");
} else
{
mSelectionMode = true;
return;
}
}
public final void unregisterSelectionListener()
{
mSelectionListener = null;
}
public static class LayoutParams extends ViewGroup.LayoutParams {
int column;
long id;
public boolean isBoxStart;
public int majorSpan;
public int minorSpan;
int orientation;
int position;
int viewType;
public LayoutParams(int i, int j) {
super(0, 0);
int k;
if(i == 1 && j != -3)
k = j;
else
k = -1;
if(i != 1) {
if(j == -3)
j = -1;
} else {
j = -1;
}
this.width = k;
this.height = j;
majorSpan = 1;
minorSpan = 1;
id = -1L;
isBoxStart = true;
orientation = 2;
orientation = i;
}
public LayoutParams(int i, int j, int k, int l)
{
this(i, j);
minorSpan = k;
majorSpan = l;
}
public LayoutParams(Context context, AttributeSet attributeset)
{
super(context, attributeset);
majorSpan = 1;
minorSpan = 1;
id = -1L;
isBoxStart = true;
orientation = 2;
TypedArray typedarray = context.obtainStyledAttributes(attributeset, R.styleable.ColumnGridView_Layout);
minorSpan = typedarray.getInteger(1, 1);
majorSpan = typedarray.getInteger(2, 1);
orientation = typedarray.getInteger(0, 2);
typedarray.recycle();
if(orientation != 1) {
if(width != -1)
{
Log.w("ColumnGridView", (new StringBuilder("Inflation setting LayoutParams width to ")).append(width).append(" - must be MATCH_PARENT").toString());
width = -1;
}
} else {
if(height != -1)
{
Log.w("ColumnGridView", (new StringBuilder("Inflation setting LayoutParams height to ")).append(height).append(" - must be MATCH_PARENT").toString());
height = -1;
}
}
}
public LayoutParams(ViewGroup.LayoutParams layoutparams)
{
super(layoutparams);
majorSpan = 1;
minorSpan = 1;
id = -1L;
isBoxStart = true;
orientation = 2;
if(orientation != 1) {
if(width != -1)
{
Log.w("ColumnGridView", (new StringBuilder("Constructing LayoutParams with width ")).append(width).append(" - must be MATCH_PARENT").toString());
width = -1;
}
} else {
if(height != -1)
{
Log.w("ColumnGridView", (new StringBuilder("Constructing LayoutParams with height ")).append(height).append(" - must be MATCH_PARENT").toString());
height = -1;
}
}
}
public String toString()
{
return (new StringBuilder("ColumnGridView.LayoutParams: id=")).append(id).append(" major=").append(majorSpan).append(" minor=").append(minorSpan).append(" pos=").append(position).append(" type=").append(viewType).append(" col=").append(column).append(" boxstart=").append(isBoxStart).append(" orient=").append(orientation).toString();
}
}
private static final class LayoutRecord
{
public int column;
public long id;
private int mMargins[];
public int size;
public int span;
public LayoutRecord()
{
id = -1L;
}
private final void ensureMargins()
{
if(mMargins == null)
mMargins = new int[2 * span];
}
public final int getMarginAfter(int i)
{
int j;
if(mMargins == null)
j = 0;
else
j = mMargins[1 + i * 2];
return j;
}
public final int getMarginBefore(int i)
{
int j;
if(mMargins == null)
j = 0;
else
j = mMargins[i * 2];
return j;
}
public final void setMarginAfter(int i, int j)
{
if(mMargins != null || j != 0)
{
ensureMargins();
mMargins[1 + i * 2] = j;
}
}
public final void setMarginBefore(int i, int j)
{
if(mMargins != null || j != 0)
{
ensureMargins();
mMargins[i * 2] = j;
}
}
public final String toString()
{
String s = (new StringBuilder("LayoutRecord{c=")).append(column).append(", id=").append(id).append(" sz=").append(size).append(" sp=").append(span).toString();
if(mMargins != null)
{
String s1 = (new StringBuilder()).append(s).append(" margins[before, after](").toString();
for(int i = 0; i < mMargins.length; i += 2)
s1 = (new StringBuilder()).append(s1).append("[").append(mMargins[i]).append(", ").append(mMargins[i + 1]).append("]").toString();
s = (new StringBuilder()).append(s1).append(")").toString();
}
return (new StringBuilder()).append(s).append("}").toString();
}
}
public static interface OnScrollListener {
void onScroll(ColumnGridView columngridview, int i, int j, int k,
int l, int i1);
void onScrollStateChanged(ColumnGridView columngridview, int i);
}
public static interface ItemSelectionListener {
void onItemDeselected(View view, int i);
void onItemSelected(View view, int i);
}
public static interface PressedHighlightable {
boolean shouldHighlightOnPress();
}
private static final class Bug6713624LinkedHashMap extends LinkedHashMap {
protected final boolean removeEldestEntry(Map.Entry entry) {
boolean flag;
if (size() > 32)
flag = true;
else
flag = false;
return flag;
}
private static final long serialVersionUID = 0xe954f0cbe61dabdbL;
Bug6713624LinkedHashMap() {
}
}
private final class AdapterDataSetObserver extends DataSetObserver {
public final void onChanged() {
int i;
mDataChanged = true;
i = mItemCount;
mItemCount = mAdapter.getCount();
if (mItemCount < i) {
for (int l = -1 + mSelectedPositions.size(); l >= 0; l--) {
int i1 = mSelectedPositions.keyAt(l);
if (i1 >= mItemCount && mSelectedPositions.valueAt(l))
deselect(i1);
}
}
mRecycler.clearTransientViews();
if (0 == mItemCount) {
clearAllState();
} else {
if (!mHasStableIds || mItemCount < i) {
mBug6713624LinkedHashMap.put("onchanged - clear", Integer.valueOf(0));
mLayoutRecords.clear();
for(i = 0; i < getChildCount(); i++)
mRecycler.addScrap(getChildAt(i));
if(mInLayout)
removeAllViewsInLayout();
else
removeAllViews();
if (mItemStart != null) {
int j = mColCount;
int k = 0;
while (k < j) {
mItemEnd[k] = mItemStart[k];
k++;
}
}
}
}
requestLayout();
}
public final void onInvalidated() {
}
}
public static interface RecyclerListener {
void onMovedToScrapHeap(View view);
}
private class RecycleBin {
private ArrayList<View>[] mScrapViews;
private int mViewTypeCount;
private int mMaxScrap;
private SparseArray<View> mTransientStateViews;
private RecyclerListener mRecyclerListener;
public void setViewTypeCount(int viewTypeCount) {
if (viewTypeCount < 1) {
throw new IllegalArgumentException("Must have at least one view type (" +
viewTypeCount + " types reported)");
}
if (viewTypeCount == mViewTypeCount) {
return;
}
ArrayList<View>[] scrapViews = new ArrayList[viewTypeCount];
for (int i = 0; i < viewTypeCount; i++) {
scrapViews[i] = new ArrayList<View>();
}
mViewTypeCount = viewTypeCount;
mScrapViews = scrapViews;
}
public void clear() {
final int typeCount = mViewTypeCount;
for (int i = 0; i < typeCount; i++) {
mScrapViews[i].clear();
}
if (mTransientStateViews != null) {
mTransientStateViews.clear();
}
}
public void clearTransientViews() {
if (mTransientStateViews != null) {
mTransientStateViews.clear();
}
}
public void addScrap(View v) {
final LayoutParams lp = (LayoutParams) v.getLayoutParams();
if (ViewCompat.hasTransientState(v)) {
if (mTransientStateViews == null) {
mTransientStateViews = new SparseArray<View>();
}
mTransientStateViews.put(lp.position, v);
return;
}
final int childCount = getChildCount();
if (childCount > mMaxScrap) {
mMaxScrap = childCount;
}
ArrayList<View> scrap = mScrapViews[lp.viewType];
if (scrap.size() < mMaxScrap) {
scrap.add(v);
if(mRecyclerListener != null)
mRecyclerListener.onMovedToScrapHeap(v);
}
}
public View getTransientStateView(int position) {
if (mTransientStateViews == null) {
return null;
}
final View result = mTransientStateViews.get(position);
if (result != null) {
mTransientStateViews.remove(position);
}
return result;
}
public View getScrapView(int type) {
ArrayList<View> scrap = mScrapViews[type];
if (scrap.isEmpty()) {
return null;
}
final int index = scrap.size() - 1;
final View result = scrap.get(index);
scrap.remove(index);
return result;
}
}
static class SavedState extends View.BaseSavedState
{
long firstId;
int position;
SparseBooleanArray selectedPositions;
boolean selectionMode;
int topOffset;
int visibleOffset;
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public final Object createFromParcel(Parcel parcel)
{
return new SavedState(parcel);
}
public final Object[] newArray(int i)
{
return new SavedState[i];
}
};
private SavedState(Parcel parcel)
{
super(parcel);
boolean flag = true;
firstId = -1L;
firstId = parcel.readLong();
position = parcel.readInt();
visibleOffset = parcel.readInt();
topOffset = parcel.readInt();
selectedPositions = parcel.readSparseBooleanArray();
if(parcel.readInt() != 1)
flag = false;
selectionMode = flag;
}
SavedState(Parcel parcel, byte byte0)
{
this(parcel);
}
SavedState(Parcelable parcelable)
{
super(parcelable);
firstId = -1L;
}
public String toString()
{
return (new StringBuilder("StaggereGridView.SavedState{")).append(Integer.toHexString(System.identityHashCode(this))).append(" firstId=").append(firstId).append(" position=").append(position).append(" selected=").append(selectedPositions).append(" selectionMode=").append(selectionMode).append("}").toString();
}
public void writeToParcel(Parcel parcel, int i)
{
super.writeToParcel(parcel, i);
parcel.writeLong(firstId);
parcel.writeInt(position);
parcel.writeInt(visibleOffset);
parcel.writeInt(topOffset);
parcel.writeSparseBooleanArray(selectedPositions);
int j;
if(selectionMode)
j = 1;
else
j = 0;
parcel.writeInt(j);
}
}
}