GridView.java revision 4df2423a947bcd3f024cc3d3a1a315a8dc428598
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.SoundEffectConstants; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.GridLayoutAnimationController; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A view that shows items in two-dimensional scrolling grid. The items in the 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * grid come from the {@link ListAdapter} associated with this view. 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class GridView extends AbsListView { 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int NO_STRETCH = 0; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STRETCH_SPACING = 1; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STRETCH_COLUMN_WIDTH = 2; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STRETCH_SPACING_UNIFORM = 3; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AUTO_FIT = -1; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNumColumns = AUTO_FIT; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHorizontalSpacing = 0; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRequestedHorizontalSpacing; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mVerticalSpacing = 0; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mStretchMode = STRETCH_COLUMN_WIDTH; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mColumnWidth; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRequestedColumnWidth; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRequestedNumColumns; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mReferenceView = null; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mReferenceViewInSelectedRow = null; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mGravity = Gravity.LEFT; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Rect mTempRect = new Rect(); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GridView(Context context) { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GridView(Context context, AttributeSet attrs) { 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, com.android.internal.R.attr.gridViewStyle); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GridView(Context context, AttributeSet attrs, int defStyle) { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs, defStyle); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = context.obtainStyledAttributes(attrs, 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.GridView, defStyle, 0); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int hSpacing = a.getDimensionPixelOffset( 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.GridView_horizontalSpacing, 0); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHorizontalSpacing(hSpacing); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int vSpacing = a.getDimensionPixelOffset( 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.GridView_verticalSpacing, 0); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setVerticalSpacing(vSpacing); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = a.getInt(com.android.internal.R.styleable.GridView_stretchMode, STRETCH_COLUMN_WIDTH); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0) { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setStretchMode(index); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int columnWidth = a.getDimensionPixelOffset(com.android.internal.R.styleable.GridView_columnWidth, -1); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (columnWidth > 0) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setColumnWidth(columnWidth); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numColumns = a.getInt(com.android.internal.R.styleable.GridView_numColumns, 1); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNumColumns(numColumns); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = a.getInt(com.android.internal.R.styleable.GridView_gravity, -1); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0) { 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setGravity(index); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ListAdapter getAdapter() { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAdapter; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the data behind this GridView. 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param adapter the adapter providing the grid's data 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAdapter(ListAdapter adapter) { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (null != mAdapter) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdapter.unregisterDataSetObserver(mDataSetObserver); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resetList(); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecycler.clear(); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdapter = adapter; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOldSelectedPosition = INVALID_POSITION; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOldSelectedRowId = INVALID_ROW_ID; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdapter != null) { 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOldItemCount = mItemCount; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mItemCount = mAdapter.getCount(); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataChanged = true; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataSetObserver = new AdapterDataSetObserver(); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdapter.registerDataSetObserver(mDataSetObserver); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecycler.setViewTypeCount(mAdapter.getViewTypeCount()); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStackFromBottom) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position = lookForSelectablePosition(mItemCount - 1, false); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position = lookForSelectablePosition(0, true); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectedPositionInt(position); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNextSelectedPositionInt(position); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkSelectionChanged(); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Nothing selected 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkSelectionChanged(); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int lookForSelectablePosition(int position, boolean lookDown) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ListAdapter adapter = mAdapter; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (adapter == null || isInTouchMode()) { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return INVALID_POSITION; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position < 0 || position >= mItemCount) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return INVALID_POSITION; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return position; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void fillGap(boolean down) { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (down) { 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int startOffset = count > 0 ? 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getChildAt(count - 1).getBottom() + verticalSpacing : getListPaddingTop(); 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = mFirstPosition + count; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStackFromBottom) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position += numColumns - 1; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(position, startOffset); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project correctTooHigh(numColumns, verticalSpacing, getChildCount()); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int startOffset = count > 0 ? 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getChildAt(0).getTop() - verticalSpacing : getHeight() - getListPaddingBottom(); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = mFirstPosition; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position -= numColumns; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position--; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(position, startOffset); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project correctTooLow(numColumns, verticalSpacing, getChildCount()); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the list from pos down to the end of the list view. 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pos The first position to put in the list 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param nextTop The location where the top of the item associated with pos 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should be drawn 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that is currently selected, if it happens to be in the 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * range that we draw. 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillDown(int pos, int nextTop) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View selectedView = null; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int end = (mBottom - mTop) - mListPadding.bottom; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (nextTop < end && pos < mItemCount) { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View temp = makeRow(pos, nextTop, true); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp != null) { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedView = temp; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextTop = mReferenceView.getBottom() + mVerticalSpacing; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos += mNumColumns; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return selectedView; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View makeRow(int startPos, int y, boolean flow) { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int columnWidth = mColumnWidth; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int horizontalSpacing = mHorizontalSpacing; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int last; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nextLeft = mListPadding.left + ((mStretchMode == STRETCH_SPACING_UNIFORM) ? horizontalSpacing : 0); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project last = Math.min(startPos + mNumColumns, mItemCount); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project last = startPos + 1; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startPos = Math.max(0, startPos - mNumColumns + 1); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (last - startPos < mNumColumns) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextLeft += (mNumColumns - (last - startPos)) * (columnWidth + horizontalSpacing); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View selectedView = null; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean hasFocus = shouldShowSelector(); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean inClick = touchModeDrawsInPressedState(); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = mSelectedPosition; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReferenceView = null; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int pos = startPos; pos < last; pos++) { 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is this the selected item? 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean selected = pos == selectedPosition; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // does the list view have focus or contain focus 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int where = flow ? -1 : pos - startPos; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View child = makeAndAddView(pos, y, flow, nextLeft, selected, where); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReferenceView = child; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextLeft += columnWidth; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos < last - 1) { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextLeft += horizontalSpacing; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selected && (hasFocus || inClick)) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedView = child; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selectedView != null) { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReferenceViewInSelectedRow = mReferenceView; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return selectedView; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the list from pos up to the top of the list view. 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pos The first position to put in the list 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param nextBottom The location where the bottom of the item associated 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with pos should be drawn 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that is currently selected 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillUp(int pos, int nextBottom) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View selectedView = null; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int end = mListPadding.top; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (nextBottom > end && pos >= 0) { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View temp = makeRow(pos, nextBottom, false); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp != null) { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedView = temp; 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextBottom = mReferenceView.getTop() - mVerticalSpacing; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = pos; 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos -= mNumColumns; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStackFromBottom) { 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = Math.max(0, pos + 1); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return selectedView; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the list from top to bottom, starting with mFirstPosition 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param nextTop The location where the top of the first item should be 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * drawn 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that is currently selected 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillFromTop(int nextTop) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = Math.min(mFirstPosition, mSelectedPosition); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = Math.min(mFirstPosition, mItemCount - 1); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition < 0) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = 0; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition -= mFirstPosition % mNumColumns; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fillDown(mFirstPosition, nextTop); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillFromBottom(int lastPosition, int nextBottom) { 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastPosition = Math.max(lastPosition, mSelectedPosition); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastPosition = Math.min(lastPosition, mItemCount - 1); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedPosition = mItemCount - 1 - lastPosition; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastPosition = mItemCount - 1 - (invertedPosition - (invertedPosition % mNumColumns)); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fillUp(lastPosition, nextBottom); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillSelection(int childrenTop, int childrenBottom) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = reconcileSelectedPosition(); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowStart; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowEnd = -1; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = selectedPosition - (selectedPosition % numColumns); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedSelection = mItemCount - 1 - selectedPosition; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = Math.max(0, rowEnd - numColumns + 1); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int fadingEdgeLength = getVerticalFadingEdgeLength(); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int topSelectionPixel = getTopSelectionPixel(childrenTop, fadingEdgeLength, rowStart); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View sel = makeRow(mStackFromBottom ? rowEnd : rowStart, topSelectionPixel, true); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = rowStart; 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View referenceView = mReferenceView; 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowStart + numColumns, referenceView.getBottom() + verticalSpacing); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pinToBottom(childrenBottom); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - numColumns, referenceView.getTop() - verticalSpacing); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int bottomSelectionPixel = getBottomSelectionPixel(childrenBottom, 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fadingEdgeLength, numColumns, rowStart); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = bottomSelectionPixel - referenceView.getBottom(); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(offset); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - 1, referenceView.getTop() - verticalSpacing); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pinToTop(childrenTop); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowEnd + numColumns, referenceView.getBottom() + verticalSpacing); 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sel; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void pinToTop(int childrenTop) { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition == 0) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int top = getChildAt(0).getTop(); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = childrenTop - top; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset < 0) { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(offset); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void pinToBottom(int childrenBottom) { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition + count == mItemCount) { 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int bottom = getChildAt(count - 1).getBottom(); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = childrenBottom - bottom; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset > 0) { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(offset); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int findMotionRow(int y) { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount > 0) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < childCount; i += numColumns) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y <= getChildAt(i).getBottom()) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFirstPosition + i; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = childCount - 1; i >= 0; i -= numColumns) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y >= getChildAt(i).getTop()) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFirstPosition + i; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFirstPosition + childCount - 1; 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return INVALID_POSITION; 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Layout during a scroll that results from tracking motion events. Places 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the mMotionPosition view at the offset specified by mMotionViewTop, and 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * then build surrounding views from there. 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position the position at which to start filling 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param top the top of the view at that position 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The selected view, or null if the selected view is outside the 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * visible area. 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillSpecific(int position, int top) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int motionRowStart; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int motionRowEnd = -1; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project motionRowStart = position - (position % numColumns); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedSelection = mItemCount - 1 - position; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project motionRowEnd = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project motionRowStart = Math.max(0, motionRowEnd - numColumns + 1); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View temp = makeRow(mStackFromBottom ? motionRowEnd : motionRowStart, top, true); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Possibly changed again in fillUp if we add rows above this one. 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = motionRowStart; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View referenceView = mReferenceView; 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View above; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View below; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project above = fillUp(motionRowStart - numColumns, referenceView.getTop() - verticalSpacing); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project below = fillDown(motionRowStart + numColumns, referenceView.getBottom() + verticalSpacing); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if we have dragged the bottom of the grid too high 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount > 0) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project correctTooHigh(numColumns, verticalSpacing, childCount); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project below = fillDown(motionRowEnd + numColumns, referenceView.getBottom() + verticalSpacing); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project above = fillUp(motionRowStart - 1, referenceView.getTop() - verticalSpacing); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if we have dragged the bottom of the grid too high 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount > 0) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project correctTooLow(numColumns, verticalSpacing, childCount); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp != null) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return temp; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (above != null) { 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return above; 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return below; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void correctTooHigh(int numColumns, int verticalSpacing, int childCount) { 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First see if the last item is visible 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int lastPosition = mFirstPosition + childCount - 1; 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastPosition == mItemCount - 1 && childCount > 0) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the last child ... 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View lastChild = getChildAt(childCount - 1); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ... and its bottom edge 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int lastBottom = lastChild.getBottom(); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is bottom of our drawable area 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int end = (mBottom - mTop) - mListPadding.bottom; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is how far the bottom edge of the last view is from the bottom of the 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // drawable area 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bottomOffset = end - lastBottom; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View firstChild = getChildAt(0); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int firstTop = firstChild.getTop(); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure we are 1) Too high, and 2) Either there are more rows above the 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // first row or the first row is scrolled off the top of the drawable area 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bottomOffset > 0 && (mFirstPosition > 0 || firstTop < mListPadding.top)) { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition == 0) { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't pull the top too far down 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottomOffset = Math.min(bottomOffset, mListPadding.top - firstTop); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Move everything down 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(bottomOffset); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition > 0) { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fill the gap that was opened above mFirstPosition with more rows, if 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // possible 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(mFirstPosition - (mStackFromBottom ? 1 : numColumns), 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstChild.getTop() - verticalSpacing); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Close up the remaining gap 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void correctTooLow(int numColumns, int verticalSpacing, int childCount) { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition == 0 && childCount > 0) { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the first child ... 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View firstChild = getChildAt(0); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ... and its top edge 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int firstTop = firstChild.getTop(); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is top of our drawable area 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int start = mListPadding.top; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is bottom of our drawable area 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int end = (mBottom - mTop) - mListPadding.bottom; 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is how far the top edge of the first view is from the top of the 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // drawable area 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topOffset = firstTop - start; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View lastChild = getChildAt(childCount - 1); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int lastBottom = lastChild.getBottom(); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int lastPosition = mFirstPosition + childCount - 1; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure we are 1) Too low, and 2) Either there are more rows below the 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // last row or the last row is scrolled off the bottom of the drawable area 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (topOffset > 0 && (lastPosition < mItemCount - 1 || lastBottom > end)) { 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastPosition == mItemCount - 1 ) { 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't pull the bottom too far up 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project topOffset = Math.min(topOffset, lastBottom - end); 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Move everything up 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(-topOffset); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastPosition < mItemCount - 1) { 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fill the gap that was opened below the last position with more rows, if 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // possible 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(lastPosition + (!mStackFromBottom ? 1 : numColumns), 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastChild.getBottom() + verticalSpacing); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Close up the remaining gap 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the grid based on positioning the new selection at a specific 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location. The selection may be moved so that it does not intersect the 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * faded edges. The grid is then filled upwards and downwards from there. 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectedTop Where the selected item should be 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenTop Where to start drawing children 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenBottom Last pixel where children can be drawn 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that currently has selection 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillFromSelection(int selectedTop, int childrenTop, int childrenBottom) { 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int fadingEdgeLength = getVerticalFadingEdgeLength(); 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = mSelectedPosition; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowStart; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowEnd = -1; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = selectedPosition - (selectedPosition % numColumns); 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int invertedSelection = mItemCount - 1 - selectedPosition; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = Math.max(0, rowEnd - numColumns + 1); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View sel; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View referenceView; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topSelectionPixel = getTopSelectionPixel(childrenTop, fadingEdgeLength, rowStart); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bottomSelectionPixel = getBottomSelectionPixel(childrenBottom, fadingEdgeLength, 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project numColumns, rowStart); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = makeRow(mStackFromBottom ? rowEnd : rowStart, selectedTop, true); 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Possibly changed again in fillUp if we add rows above this one. 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = rowStart; 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenceView = mReferenceView; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustForTopFadingEdge(referenceView, topSelectionPixel, bottomSelectionPixel); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustForBottomFadingEdge(referenceView, topSelectionPixel, bottomSelectionPixel); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - numColumns, referenceView.getTop() - verticalSpacing); 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowStart + numColumns, referenceView.getBottom() + verticalSpacing); 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowEnd + numColumns, referenceView.getBottom() + verticalSpacing); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - 1, referenceView.getTop() - verticalSpacing); 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sel; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Calculate the bottom-most pixel we can draw the selection into 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenBottom Bottom pixel were children can be drawn 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fadingEdgeLength Length of the fading edge in pixels, if present 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param numColumns Number of columns in the grid 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rowStart The start of the row that will contain the selection 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The bottom-most pixel we can draw the selection into 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getBottomSelectionPixel(int childrenBottom, int fadingEdgeLength, 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numColumns, int rowStart) { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Last pixel we can draw the selection into 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bottomSelectionPixel = childrenBottom; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rowStart + numColumns - 1 < mItemCount - 1) { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottomSelectionPixel -= fadingEdgeLength; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bottomSelectionPixel; 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Calculate the top-most pixel we can draw the selection into 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenTop Top pixel were children can be drawn 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fadingEdgeLength Length of the fading edge in pixels, if present 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rowStart The start of the row that will contain the selection 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The top-most pixel we can draw the selection into 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getTopSelectionPixel(int childrenTop, int fadingEdgeLength, int rowStart) { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // first pixel we can draw the selection into 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topSelectionPixel = childrenTop; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rowStart > 0) { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project topSelectionPixel += fadingEdgeLength; 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return topSelectionPixel; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Move all views upwards so the selected row does not interesect the bottom 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fading edge (if necessary). 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childInSelectedRow A child in the row that contains the selection 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param topSelectionPixel The topmost pixel we can draw the selection into 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bottomSelectionPixel The bottommost pixel we can draw the 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection into 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void adjustForBottomFadingEdge(View childInSelectedRow, 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topSelectionPixel, int bottomSelectionPixel) { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Some of the newly selected item extends below the bottom of the 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // list 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childInSelectedRow.getBottom() > bottomSelectionPixel) { 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Find space available above the selection into which we can 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // scroll upwards 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceAbove = childInSelectedRow.getTop() - topSelectionPixel; 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Find space required to bring the bottom of the selected item 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fully into view 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceBelow = childInSelectedRow.getBottom() - bottomSelectionPixel; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offset = Math.min(spaceAbove, spaceBelow); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now offset the selected item to get it into view 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(-offset); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Move all views upwards so the selected row does not interesect the top 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fading edge (if necessary). 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childInSelectedRow A child in the row that contains the selection 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param topSelectionPixel The topmost pixel we can draw the selection into 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bottomSelectionPixel The bottommost pixel we can draw the 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection into 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void adjustForTopFadingEdge(View childInSelectedRow, 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topSelectionPixel, int bottomSelectionPixel) { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Some of the newly selected item extends above the top of the list 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childInSelectedRow.getTop() < topSelectionPixel) { 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Find space required to bring the top of the selected item 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fully into view 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceAbove = topSelectionPixel - childInSelectedRow.getTop(); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Find space available below the selection into which we can 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // scroll downwards 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceBelow = bottomSelectionPixel - childInSelectedRow.getBottom(); 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offset = Math.min(spaceAbove, spaceBelow); 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now offset the selected item to get it into view 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(offset); 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the grid based on positioning the new selection relative to the old 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection. The new selection will be placed at, above, or below the 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location of the new selection depending on how the selection is moving. 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The selection will then be pinned to the visible part of the screen, 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * excluding the edges that are faded. The grid is then filled upwards and 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * downwards from there. 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param delta Which way we are moving 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenTop Where to start drawing children 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenBottom Last pixel where children can be drawn 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that currently has selection 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View moveSelection(int delta, int childrenTop, int childrenBottom) { 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int fadingEdgeLength = getVerticalFadingEdgeLength(); 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = mSelectedPosition; 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int oldRowStart; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowStart; 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowEnd = -1; 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldRowStart = (selectedPosition - delta) - ((selectedPosition - delta) % numColumns); 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = selectedPosition - (selectedPosition % numColumns); 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int invertedSelection = mItemCount - 1 - selectedPosition; 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = Math.max(0, rowEnd - numColumns + 1); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invertedSelection = mItemCount - 1 - (selectedPosition - delta); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldRowStart = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldRowStart = Math.max(0, oldRowStart - numColumns + 1); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowDelta = rowStart - oldRowStart; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int topSelectionPixel = getTopSelectionPixel(childrenTop, fadingEdgeLength, rowStart); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int bottomSelectionPixel = getBottomSelectionPixel(childrenBottom, fadingEdgeLength, 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project numColumns, rowStart); 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Possibly changed again in fillUp if we add rows above this one. 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = rowStart; 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View sel; 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View referenceView; 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rowDelta > 0) { 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Case 1: Scrolling down. 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int oldBottom = mReferenceViewInSelectedRow == null ? 0 : 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReferenceViewInSelectedRow.getBottom(); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = makeRow(mStackFromBottom ? rowEnd : rowStart, oldBottom + verticalSpacing, true); 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenceView = mReferenceView; 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustForBottomFadingEdge(referenceView, topSelectionPixel, bottomSelectionPixel); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (rowDelta < 0) { 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Case 2: Scrolling up. 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int oldTop = mReferenceViewInSelectedRow == null ? 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0 : mReferenceViewInSelectedRow .getTop(); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = makeRow(mStackFromBottom ? rowEnd : rowStart, oldTop - verticalSpacing, false); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenceView = mReferenceView; 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustForTopFadingEdge(referenceView, topSelectionPixel, bottomSelectionPixel); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Keep selection where it was 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int oldTop = mReferenceViewInSelectedRow == null ? 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0 : mReferenceViewInSelectedRow .getTop(); 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = makeRow(mStackFromBottom ? rowEnd : rowStart, oldTop, true); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenceView = mReferenceView; 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - numColumns, referenceView.getTop() - verticalSpacing); 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowStart + numColumns, referenceView.getBottom() + verticalSpacing); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowEnd + numColumns, referenceView.getBottom() + verticalSpacing); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - 1, referenceView.getTop() - verticalSpacing); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sel; 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void determineColumns(int availableSpace) { 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int requestedHorizontalSpacing = mRequestedHorizontalSpacing; 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int stretchMode = mStretchMode; 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int requestedColumnWidth = mRequestedColumnWidth; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRequestedNumColumns == AUTO_FIT) { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (requestedColumnWidth > 0) { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client told us to pick the number of columns 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumColumns = (availableSpace + requestedHorizontalSpacing) / 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (requestedColumnWidth + requestedHorizontalSpacing); 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Just make up a number if we don't have enough info 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumColumns = 2; 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We picked the columns 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumColumns = mRequestedNumColumns; 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNumColumns <= 0) { 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumColumns = 1; 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (stretchMode) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NO_STRETCH: 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Nobody stretches 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnWidth = requestedColumnWidth; 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing; 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceLeftOver = availableSpace - (mNumColumns * requestedColumnWidth) - 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mNumColumns - 1) * requestedHorizontalSpacing); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (stretchMode) { 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STRETCH_COLUMN_WIDTH: 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Stretch the columns 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnWidth = requestedColumnWidth + spaceLeftOver / mNumColumns; 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing; 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STRETCH_SPACING: 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Stretch the spacing between columns 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnWidth = requestedColumnWidth; 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNumColumns > 1) { 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing + 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spaceLeftOver / (mNumColumns - 1); 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing + spaceLeftOver; 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STRETCH_SPACING_UNIFORM: 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Stretch the spacing between columns 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnWidth = requestedColumnWidth; 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNumColumns > 1) { 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing + 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spaceLeftOver / (mNumColumns + 1); 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing + spaceLeftOver; 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sets up mListPadding 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onMeasure(widthMeasureSpec, heightMeasureSpec); 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthMode = MeasureSpec.getMode(widthMeasureSpec); 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int heightMode = MeasureSpec.getMode(heightMeasureSpec); 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthSize = MeasureSpec.getSize(widthMeasureSpec); 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int heightSize = MeasureSpec.getSize(heightMeasureSpec); 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (widthMode == MeasureSpec.UNSPECIFIED) { 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mColumnWidth > 0) { 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthSize = mColumnWidth + mListPadding.left + mListPadding.right; 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthSize = mListPadding.left + mListPadding.right; 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthSize += getVerticalScrollbarWidth(); 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childWidth = widthSize - mListPadding.left - mListPadding.right; 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project determineColumns(childWidth); 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childHeight = 0; 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mItemCount = mAdapter == null ? 0 : mAdapter.getCount(); 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = mItemCount; 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count > 0) { 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View child = obtainView(0); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AbsListView.LayoutParams p = (AbsListView.LayoutParams)child.getLayoutParams(); 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.LayoutParams.WRAP_CONTENT, 0); 9324df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project child.setLayoutParams(p); 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.viewType = mAdapter.getItemViewType(0); 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childHeightSpec = getChildMeasureSpec( 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height); 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childWidthSpec = getChildMeasureSpec( 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.measure(childWidthSpec, childHeightSpec); 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childHeight = child.getMeasuredHeight(); 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRecycler.shouldRecycleViewType(p.viewType)) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecycler.addScrapView(child); 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (heightMode == MeasureSpec.UNSPECIFIED) { 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heightSize = mListPadding.top + mListPadding.bottom + childHeight + 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getVerticalFadingEdgeLength() * 2; 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (heightMode == MeasureSpec.AT_MOST) { 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ourSize = mListPadding.top + mListPadding.bottom; 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i += numColumns) { 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ourSize += childHeight; 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i + numColumns < count) { 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ourSize += mVerticalSpacing; 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ourSize >= heightSize) { 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ourSize = heightSize; 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heightSize = ourSize; 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMeasuredDimension(widthSize, heightSize); 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidthMeasureSpec = widthMeasureSpec; 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void attachLayoutAnimationParameters(View child, 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.LayoutParams params, int index, int count) { 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GridLayoutAnimationController.AnimationParameters animationParams = 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters; 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (animationParams == null) { 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams = new GridLayoutAnimationController.AnimationParameters(); 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params.layoutAnimationParameters = animationParams; 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.count = count; 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.index = index; 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.columnsCount = mNumColumns; 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.rowsCount = count / mNumColumns; 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.column = index % mNumColumns; 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.row = index / mNumColumns; 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedIndex = count - 1 - index; 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.column = mNumColumns - 1 - (invertedIndex % mNumColumns); 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.row = animationParams.rowsCount - 1 - invertedIndex / mNumColumns; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void layoutChildren() { 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean blockLayoutRequests = mBlockLayoutRequests; 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!blockLayoutRequests) { 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBlockLayoutRequests = true; 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.layoutChildren(); 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdapter == null) { 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resetList(); 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childrenTop = mListPadding.top; 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childrenBottom = mBottom - mTop - mListPadding.bottom; 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childCount = getChildCount(); 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index; 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int delta = 0; 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View sel; 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View oldSel = null; 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View oldFirst = null; 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View newSel = null; 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remember stuff we will need down below 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (mLayoutMode) { 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SET_SELECTION: 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = mNextSelectedPosition - mFirstPosition; 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0 && index < childCount) { 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newSel = getChildAt(index); 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_FORCE_TOP: 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_FORCE_BOTTOM: 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SPECIFIC: 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SYNC: 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_MOVE_SELECTION: 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextSelectedPosition >= 0) { 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = mNextSelectedPosition - mSelectedPosition; 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remember the previously selected view 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = mSelectedPosition - mFirstPosition; 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0 && index < childCount) { 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldSel = getChildAt(index); 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remember the previous first child 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldFirst = getChildAt(0); 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean dataChanged = mDataChanged; 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dataChanged) { 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleDataChanged(); 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Handle the empty set by removing all views that are visible 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and calling it a day 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mItemCount == 0) { 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resetList(); 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectedPositionInt(mNextSelectedPosition); 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Pull all children into the RecycleBin. 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // These views will be reused if possible 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int firstPosition = mFirstPosition; 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final RecycleBin recycleBin = mRecycler; 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dataChanged) { 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < childCount; i++) { 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project recycleBin.addScrapView(getChildAt(i)); 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project recycleBin.fillActiveViews(childCount, firstPosition); 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Clear out old views 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //removeAllViewsInLayout(); 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project detachAllViewsFromParent(); 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (mLayoutMode) { 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SET_SELECTION: 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newSel != null) { 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillFromSelection(newSel.getTop(), childrenTop, childrenBottom); 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSelection(childrenTop, childrenBottom); 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_FORCE_TOP: 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = 0; 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillFromTop(childrenTop); 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_FORCE_BOTTOM: 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillUp(mItemCount - 1, childrenBottom); 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SPECIFIC: 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(mSelectedPosition, mSpecificTop); 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SYNC: 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(mSyncPosition, mSpecificTop); 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_MOVE_SELECTION: 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Move the selection relative to its old position 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = moveSelection(delta, childrenTop, childrenBottom); 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount == 0) { 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectedPositionInt(0); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillFromTop(childrenTop); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int last = mItemCount - 1; 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectedPositionInt(last); 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillFromBottom(last, childrenBottom); 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSelectedPosition >= 0 && mSelectedPosition < mItemCount) { 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(mSelectedPosition, oldSel == null ? 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childrenTop : oldSel.getTop()); 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mFirstPosition < mItemCount) { 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(mFirstPosition, oldFirst == null ? 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childrenTop : oldFirst.getTop()); 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(0, childrenTop); 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Flush any cached views that did not get reused above 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project recycleBin.scrapActiveViews(); 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sel != null) { 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project positionSelector(sel); 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSelectedTop = sel.getTop(); 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSelectedTop = 0; 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSelectorRect.setEmpty(); 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_NORMAL; 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataChanged = false; 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedSync = false; 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNextSelectedPositionInt(mSelectedPosition); 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateScrollIndicators(); 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mItemCount > 0) { 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkSelectionChanged(); 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!blockLayoutRequests) { 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBlockLayoutRequests = false; 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Obtain the view and add it to our list of children. The view can be made 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fresh, converted from an unused view, or used as is if it was in the 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * recycle bin. 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position Logical position in the list 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y Top or bottom edge of the view to add 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flow if true, align top edge to y. If false, align bottom edge to 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * y. 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenLeft Left edge where children should be positioned 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selected Is this position selected? 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where to add new item in the list 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return View that was added 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View makeAndAddView(int position, int y, boolean flow, int childrenLeft, 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean selected, int where) { 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View child; 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDataChanged) { 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try to use an exsiting view for this position 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child = mRecycler.getActiveView(position); 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child != null) { 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Found it -- we're using an existing child 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This just needs to be positioned 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setupChild(child, position, y, flow, childrenLeft, selected, true, where); 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return child; 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make a new view for this position, or convert an unused view if 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // possible 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child = obtainView(position); 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This needs to be positioned and measured 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setupChild(child, position, y, flow, childrenLeft, selected, false, where); 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return child; 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Add a view as a child and make sure it is measured (if necessary) and 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * positioned properly. 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param child The view to add 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position The position of the view 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y The y position relative to which this view will be positioned 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flow if true, align top edge to y. If false, align bottom edge 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to y. 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenLeft Left edge where children should be positioned 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selected Is this position selected? 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param recycled Has this view been pulled from the recycle bin? If so it 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * does not need to be remeasured. 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where Where to add the item in the list 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void setupChild(View child, int position, int y, boolean flow, int childrenLeft, 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean selected, boolean recycled, int where) { 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isSelected = selected && shouldShowSelector(); 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean updateChildSelected = isSelected != child.isSelected(); 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested(); 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Respect layout params that are already in the view. Otherwise make 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // some up... 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AbsListView.LayoutParams p = (AbsListView.LayoutParams)child.getLayoutParams(); 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.LayoutParams.WRAP_CONTENT, 0); 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.viewType = mAdapter.getItemViewType(position); 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (recycled) { 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachViewToParent(child, where, p); 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addViewInLayout(child, where, p, true); 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (updateChildSelected) { 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.setSelected(isSelected); 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isSelected) { 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestFocus(); 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (needToMeasure) { 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childHeightSpec = ViewGroup.getChildMeasureSpec( 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height); 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childWidthSpec = ViewGroup.getChildMeasureSpec( 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width); 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.measure(childWidthSpec, childHeightSpec); 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cleanupLayoutState(child); 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int w = child.getMeasuredWidth(); 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int h = child.getMeasuredHeight(); 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childLeft; 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childTop = flow ? y : y - h; 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Gravity.LEFT: 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childLeft = childrenLeft; 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Gravity.CENTER_HORIZONTAL: 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childLeft = childrenLeft + ((mColumnWidth - w) / 2); 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Gravity.RIGHT: 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childLeft = childrenLeft + mColumnWidth - w; 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childLeft = childrenLeft; 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (needToMeasure) { 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childRight = childLeft + w; 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childBottom = childTop + h; 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.layout(childLeft, childTop, childRight, childBottom); 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.offsetLeftAndRight(childLeft - child.getLeft()); 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.offsetTopAndBottom(childTop - child.getTop()); 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCachingStarted) { 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.setDrawingCacheEnabled(true); 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the currently selected item 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position Index (starting at 0) of the data item to be selected. 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If in touch mode, the item will not be selected but it will still be positioned 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appropriately. 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSelection(int position) { 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isInTouchMode()) { 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNextSelectedPositionInt(position); 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResurrectToPosition = position; 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_SET_SELECTION; 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Makes the item at the supplied position selected. 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position the position of the new selection 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void setSelectionInt(int position) { 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNextSelectedPositionInt(position); 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project layoutChildren(); 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return commonKey(keyCode, 1, event); 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return commonKey(keyCode, repeatCount, event); 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return commonKey(keyCode, 1, event); 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean commonKey(int keyCode, int count, KeyEvent event) { 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdapter == null) { 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataChanged) { 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project layoutChildren(); 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean handled = false; 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int action = event.getAction(); 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (action != KeyEvent.ACTION_UP) { 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSelectedPosition < 0) { 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (keyCode) { 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_UP: 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_DOWN: 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_LEFT: 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_RIGHT: 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_SPACE: 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_ENTER: 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resurrectSelection(); 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (keyCode) { 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_LEFT: 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = arrowScroll(FOCUS_LEFT); 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_RIGHT: 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = arrowScroll(FOCUS_RIGHT); 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_UP: 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!event.isAltPressed()) { 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = arrowScroll(FOCUS_UP); 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = fullScroll(FOCUS_UP); 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_DOWN: 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!event.isAltPressed()) { 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = arrowScroll(FOCUS_DOWN); 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = fullScroll(FOCUS_DOWN); 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_ENTER: { 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getChildCount() > 0 && event.getRepeatCount() == 0) { 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project keyPressed(); 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_SPACE: 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPopup == null || !mPopup.isShowing()) { 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!event.isShiftPressed()) { 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = pageScroll(FOCUS_DOWN); 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = pageScroll(FOCUS_UP); 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!handled) { 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = sendToTextFilter(keyCode, count, event); 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (handled) { 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (action) { 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.ACTION_DOWN: 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onKeyDown(keyCode, event); 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.ACTION_UP: 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onKeyUp(keyCode, event); 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.ACTION_MULTIPLE: 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onKeyMultiple(keyCode, count, event); 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Scrolls up or down by the number of items currently present on screen. 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param direction either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return whether selection was moved 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean pageScroll(int direction) { 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nextPage = -1; 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (direction == FOCUS_UP) { 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextPage = Math.max(0, mSelectedPosition - getChildCount() - 1); 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (direction == FOCUS_DOWN) { 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextPage = Math.min(mItemCount - 1, mSelectedPosition + getChildCount() - 1); 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nextPage >= 0) { 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(nextPage); 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Go to the last or first item if possible. 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param direction either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN}. 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether selection was moved. 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean fullScroll(int direction) { 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean moved = false; 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (direction == FOCUS_UP) { 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_SET_SELECTION; 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(0); 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (direction == FOCUS_DOWN) { 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_SET_SELECTION; 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(mItemCount - 1); 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return moved; 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Scrolls to the next or previous item, horizontally or vertically. 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param direction either {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT}, 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return whether selection was moved 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean arrowScroll(int direction) { 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = mSelectedPosition; 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int startOfRowPos; 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int endOfRowPos; 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean moved = false; 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startOfRowPos = (selectedPosition / numColumns) * numColumns; 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endOfRowPos = Math.min(startOfRowPos + numColumns - 1, mItemCount - 1); 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedSelection = mItemCount - 1 - selectedPosition; 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endOfRowPos = mItemCount - 1 - (invertedSelection / numColumns) * numColumns; 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startOfRowPos = Math.max(0, endOfRowPos - numColumns + 1); 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (direction) { 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FOCUS_UP: 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (startOfRowPos > 0) { 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_MOVE_SELECTION; 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(Math.max(0, selectedPosition - numColumns)); 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FOCUS_DOWN: 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (endOfRowPos < mItemCount - 1) { 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_MOVE_SELECTION; 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(Math.min(selectedPosition + numColumns, mItemCount - 1)); 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FOCUS_LEFT: 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selectedPosition > startOfRowPos) { 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_MOVE_SELECTION; 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(selectedPosition - 1); 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FOCUS_RIGHT: 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selectedPosition < endOfRowPos) { 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_MOVE_SELECTION; 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(selectedPosition + 1); 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (moved) { 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction)); 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return moved; 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int closestChildIndex = -1; 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (gainFocus && previouslyFocusedRect != null) { 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project previouslyFocusedRect.offset(mScrollX, mScrollY); 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // figure out which item should be selected based on previously 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // focused rect 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect otherRect = mTempRect; 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int minDistance = Integer.MAX_VALUE; 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < childCount; i++) { 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // only consider view's on appropriate edge of grid 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isCandidateSelection(i, direction)) { 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View other = getChildAt(i); 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project other.getDrawingRect(otherRect); 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetDescendantRectToMyCoords(other, otherRect); 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int distance = getDistance(previouslyFocusedRect, otherRect, direction); 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (distance < minDistance) { 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minDistance = distance; 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project closestChildIndex = i; 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (closestChildIndex >= 0) { 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelection(closestChildIndex + mFirstPosition); 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Is childIndex a candidate for next focus given the direction the focus 15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * change is coming from? 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childIndex The index to check. 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param direction The direction, one of 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT} 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether childIndex is a candidate. 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isCandidateSelection(int childIndex, int direction) { 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedIndex = count - 1 - childIndex; 16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowStart; 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowEnd; 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = childIndex - (childIndex % mNumColumns); 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = Math.max(rowStart + mNumColumns - 1, count); 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = count - 1 - (invertedIndex - (invertedIndex % mNumColumns)); 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = Math.max(0, rowEnd - mNumColumns + 1); 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (direction) { 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.FOCUS_RIGHT: 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // coming from left, selection is only valid if it is on left 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // edge 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return childIndex == rowStart; 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.FOCUS_DOWN: 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // coming from top; only valid if in top row 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return rowStart == 0; 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.FOCUS_LEFT: 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // coming from right, must be on right edge 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return childIndex == rowEnd; 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.FOCUS_UP: 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // coming from bottom, need to be in last row 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return rowEnd == count - 1; 16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("direction must be one of " 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}."); 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Describes how the child views are horizontally aligned. Defaults to Gravity.LEFT 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity the gravity to apply to this grid's children 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_gravity 16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGravity(int gravity) { 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGravity != gravity) { 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGravity = gravity; 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the amount of horizontal (x) spacing to place between each item 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the grid. 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param horizontalSpacing The amount of horizontal space between items, 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in pixels. 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_horizontalSpacing 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setHorizontalSpacing(int horizontalSpacing) { 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (horizontalSpacing != mRequestedHorizontalSpacing) { 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRequestedHorizontalSpacing = horizontalSpacing; 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the amount of vertical (y) spacing to place between each item 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the grid. 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param verticalSpacing The amount of vertical space between items, 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in pixels. 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_verticalSpacing 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setVerticalSpacing(int verticalSpacing) { 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (verticalSpacing != mVerticalSpacing) { 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVerticalSpacing = verticalSpacing; 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control how items are stretched to fill their space. 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param stretchMode Either {@link #NO_STRETCH}, 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #STRETCH_SPACING}, {@link #STRETCH_SPACING_UNIFORM}, or {@link #STRETCH_COLUMN_WIDTH}. 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_stretchMode 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setStretchMode(int stretchMode) { 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stretchMode != mStretchMode) { 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStretchMode = stretchMode; 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStretchMode() { 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStretchMode; 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the width of columns in the grid. 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnWidth The column width, in pixels. 17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_columnWidth 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColumnWidth(int columnWidth) { 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (columnWidth != mRequestedColumnWidth) { 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRequestedColumnWidth = columnWidth; 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the number of columns in the grid 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param numColumns The desired number of columns. 17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_numColumns 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setNumColumns(int numColumns) { 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numColumns != mRequestedNumColumns) { 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRequestedNumColumns = numColumns; 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Make sure views are touching the top or bottom edge, as appropriate for 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * our gravity 17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void adjustViewsUpOrDown() { 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount > 0) { 17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int delta; 17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View child; 17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Uh-oh -- we came up short. Slide all views up to make them 17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // align with the top 17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child = getChildAt(0); 17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = child.getTop() - mListPadding.top; 17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition != 0) { 17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It's OK to have some space above the first item if it is 17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // part of the vertical spacing 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta -= mVerticalSpacing; 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (delta < 0) { 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We only are looking to see if we are too low, not too high 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = 0; 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we are too high, slide all views down to align with bottom 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child = getChildAt(childCount - 1); 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = child.getBottom() - (getHeight() - mListPadding.bottom); 17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition + childCount < mItemCount) { 17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It's OK to have some space below the last item if it is 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // part of the vertical spacing 17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta += mVerticalSpacing; 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (delta > 0) { 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We only are looking to see if we are too high, not too low 17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = 0; 17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (delta != 0) { 17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(-delta); 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int computeVerticalScrollExtent() { 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count > 0) { 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowCount = (count + numColumns - 1) / numColumns; 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int extent = rowCount * 100; 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View view = getChildAt(0); 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int top = view.getTop(); 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int height = view.getHeight(); 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height > 0) { 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extent += (top * 100) / height; 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view = getChildAt(count - 1); 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int bottom = view.getBottom(); 17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project height = view.getHeight(); 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height > 0) { 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extent -= ((bottom - getHeight()) * 100) / height; 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return extent; 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int computeVerticalScrollOffset() { 18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition >= 0 && getChildCount() > 0) { 18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View view = getChildAt(0); 18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int top = view.getTop(); 18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int height = view.getHeight(); 18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height > 0) { 18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int whichRow = mFirstPosition / mNumColumns; 18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Math.max(whichRow * 100 - (top * 100) / height, 0); 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int computeVerticalScrollRange() { 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: Account for vertical spacing too 18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowCount = (mItemCount + numColumns - 1) / numColumns; 18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Math.max(rowCount * 100, 0); 18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1832