List of usage examples for android.view View getTop
@ViewDebug.CapturedViewProperty public final int getTop()
From source file:app.umitems.greenclock.widget.sgv.StaggeredGridView.java
@Override public void computeScroll() { if (mTouchMode == TOUCH_MODE_OVERFLING) { handleOverfling();/* w ww. j ava 2s. c o m*/ } else if (mScroller.computeScrollOffset()) { final int overScrollMode = ViewCompat.getOverScrollMode(this); final boolean supportsOverscroll = overScrollMode != ViewCompat.OVER_SCROLL_NEVER; final int y = mScroller.getCurrY(); final int dy = (int) (y - mLastTouchY); // TODO: Figure out why mLastTouchY is being updated here. Consider using a new class // variable since this value does not represent the last place on the screen where a // touch occurred. mLastTouchY = y; // Check if the top of the motion view is where it is // supposed to be final View motionView = supportsOverscroll && getChildCount() > 0 ? getChildAt(0) : null; final int motionViewPrevTop = motionView != null ? motionView.getTop() : 0; final boolean stopped = !trackMotionScroll(dy, false); if (!stopped && !mScroller.isFinished()) { mTouchMode = TOUCH_MODE_IDLE; ViewCompat.postInvalidateOnAnimation(this); } else if (stopped && dy != 0 && supportsOverscroll) { // Check to see if we have bumped into the scroll limit if (motionView != null) { final int motionViewRealTop = motionView.getTop(); // Apply overscroll final int overscroll = -dy - (motionViewRealTop - motionViewPrevTop); overScrollBy(0, overscroll, 0, getScrollY(), 0, 0, 0, mOverscrollDistance, true); } final EdgeEffectCompat edge; if (dy > 0) { edge = mTopEdge; mBottomEdge.finish(); } else { edge = mBottomEdge; mTopEdge.finish(); } edge.onAbsorb(Math.abs((int) mScroller.getCurrVelocity())); if (mScroller.computeScrollOffset()) { mScroller.notifyVerticalEdgeReached(getScrollY(), 0, mOverscrollDistance); } mTouchMode = TOUCH_MODE_OVERFLING; ViewCompat.postInvalidateOnAnimation(this); } else { mTouchMode = TOUCH_MODE_IDLE; } } }
From source file:com.appunite.list.ListView.java
/** * Do an arrow scroll based on focus searching. If a new view is * given focus, return the selection delta and amount to scroll via * an {@link ArrowScrollFocusResult}, otherwise, return null. * * @param direction either {@link android.view.View#FOCUS_UP} or * {@link android.view.View#FOCUS_DOWN}. * @return The result if focus has changed, or <code>null</code>. *//*from w w w. j ava 2 s.c om*/ private ArrowScrollFocusResult arrowScrollFocused(final int direction) { final View selectedView = getSelectedView(); View newFocus; if (selectedView != null && selectedView.hasFocus()) { View oldFocus = selectedView.findFocus(); newFocus = FocusFinder.getInstance().findNextFocus(this, oldFocus, direction); } else { if (direction == View.FOCUS_DOWN) { final boolean topFadingEdgeShowing = (mFirstPosition > 0); final int listTop = mListPadding.top + (topFadingEdgeShowing ? getArrowScrollPreviewLength() : 0); final int ySearchPoint = (selectedView != null && selectedView.getTop() > listTop) ? selectedView.getTop() : listTop; mTempRect.set(0, ySearchPoint, 0, ySearchPoint); } else { final boolean bottomFadingEdgeShowing = (mFirstPosition + getChildCount() - 1) < mItemCount; final int listBottom = getHeight() - mListPadding.bottom - (bottomFadingEdgeShowing ? getArrowScrollPreviewLength() : 0); final int ySearchPoint = (selectedView != null && selectedView.getBottom() < listBottom) ? selectedView.getBottom() : listBottom; mTempRect.set(0, ySearchPoint, 0, ySearchPoint); } newFocus = FocusFinder.getInstance().findNextFocusFromRect(this, mTempRect, direction); } if (newFocus != null) { final int positionOfNewFocus = positionOfNewFocus(newFocus); // if the focus change is in a different new position, make sure // we aren't jumping over another selectable position if (mSelectedPosition != INVALID_POSITION && positionOfNewFocus != mSelectedPosition) { final int selectablePosition = lookForSelectablePositionOnScreen(direction); if (selectablePosition != INVALID_POSITION && ((direction == View.FOCUS_DOWN && selectablePosition < positionOfNewFocus) || (direction == View.FOCUS_UP && selectablePosition > positionOfNewFocus))) { return null; } } int focusScroll = amountToScrollToNewFocus(direction, newFocus, positionOfNewFocus); final int maxScrollAmount = getMaxScrollAmount(); if (focusScroll < maxScrollAmount) { // not moving too far, safe to give next view focus newFocus.requestFocus(direction); mArrowScrollFocusResult.populate(positionOfNewFocus, focusScroll); return mArrowScrollFocusResult; } else if (distanceToView(newFocus) < maxScrollAmount) { // Case to consider: // too far to get entire next focusable on screen, but by going // max scroll amount, we are getting it at least partially in view, // so give it focus and scroll the max ammount. newFocus.requestFocus(direction); mArrowScrollFocusResult.populate(positionOfNewFocus, maxScrollAmount); return mArrowScrollFocusResult; } } return null; }
From source file:com.appunite.list.ListView.java
/** * Fills the grid based on positioning the new selection at a specific * location. The selection may be moved so that it does not intersect the * faded edges. The grid is then filled upwards and downwards from there. * * @param selectedTop Where the selected item should be * @param childrenTop Where to start drawing children * @param childrenBottom Last pixel where children can be drawn * @return The view that currently has selection *//* w w w .ja v a 2 s .co m*/ private View fillFromSelection(int selectedTop, int childrenTop, int childrenBottom) { int fadingEdgeLength = getVerticalFadingEdgeLength(); final int selectedPosition = mSelectedPosition; View sel; final int topSelectionPixel = getTopSelectionPixel(childrenTop, fadingEdgeLength, selectedPosition); final int bottomSelectionPixel = getBottomSelectionPixel(childrenBottom, fadingEdgeLength, selectedPosition); sel = makeAndAddView(selectedPosition, selectedTop, true, mListPadding.left, true); // Some of the newly selected item extends below the bottom of the list if (sel.getBottom() > bottomSelectionPixel) { // Find space available above the selection into which we can scroll // upwards final int spaceAbove = sel.getTop() - topSelectionPixel; // Find space required to bring the bottom of the selected item // fully into view final int spaceBelow = sel.getBottom() - bottomSelectionPixel; final int offset = Math.min(spaceAbove, spaceBelow); // Now offset the selected item to get it into view sel.offsetTopAndBottom(-offset); } else if (sel.getTop() < topSelectionPixel) { // Find space required to bring the top of the selected item fully // into view final int spaceAbove = topSelectionPixel - sel.getTop(); // Find space available below the selection into which we can scroll // downwards final int spaceBelow = bottomSelectionPixel - sel.getBottom(); final int offset = Math.min(spaceAbove, spaceBelow); // Offset the selected item to get it into view sel.offsetTopAndBottom(offset); } // Fill in views above and below fillAboveAndBelow(sel, selectedPosition); if (!mStackFromBottom) { correctTooHigh(getChildCount()); } else { correctTooLow(getChildCount()); } return sel; }
From source file:com.appunite.list.ListView.java
/** * Scroll the children by amount, adding a view at the end and removing * views that fall off as necessary./* w ww .jav a 2 s .co m*/ * * @param amount The amount (positive or negative) to scroll. */ private void scrollListItemsBy(int amount) { offsetChildrenTopAndBottomUnhide(amount); final int listBottom = getHeight() - mListPadding.bottom; final int listTop = mListPadding.top; final AbsListView.RecycleBin recycleBin = mRecycler; if (amount < 0) { // shifted items up // may need to pan views into the bottom space int numChildren = getChildCount(); View last = getChildAt(numChildren - 1); while (last.getBottom() < listBottom) { final int lastVisiblePosition = mFirstPosition + numChildren - 1; if (lastVisiblePosition < mItemCount - 1) { last = addViewBelow(last, lastVisiblePosition); numChildren++; } else { break; } } // may have brought in the last child of the list that is skinnier // than the fading edge, thereby leaving space at the end. need // to shift back if (last.getBottom() < listBottom) { offsetChildrenTopAndBottomUnhide(listBottom - last.getBottom()); } // top views may be panned off screen View first = getChildAt(0); while (first.getBottom() < listTop) { AbsListView.LayoutParams layoutParams = (LayoutParams) first.getLayoutParams(); if (recycleBin.shouldRecycleViewType(layoutParams.viewType)) { recycleBin.addScrapView(first, mFirstPosition); } detachViewFromParent(first); first = getChildAt(0); mFirstPosition++; } } else { // shifted items down View first = getChildAt(0); // may need to pan views into top while ((first.getTop() > listTop) && (mFirstPosition > 0)) { first = addViewAbove(first, mFirstPosition); mFirstPosition--; } // may have brought the very first child of the list in too far and // need to shift it back if (first.getTop() > listTop) { offsetChildrenTopAndBottomUnhide(listTop - first.getTop()); } int lastIndex = getChildCount() - 1; View last = getChildAt(lastIndex); // bottom view may be panned off screen while (last.getTop() > listBottom) { AbsListView.LayoutParams layoutParams = (LayoutParams) last.getLayoutParams(); if (recycleBin.shouldRecycleViewType(layoutParams.viewType)) { recycleBin.addScrapView(last, mFirstPosition + lastIndex); } detachViewFromParent(last); last = getChildAt(--lastIndex); } } }
From source file:cn.iterlog.myapplication.widget.overscroll.StaggeredGridView.java
/** * Measure and layout all currently visible children. * * @param queryAdapter true to requery the adapter for view data *//*from ww w. j a v a 2 s .c o m*/ final void layoutChildren(boolean queryAdapter) { final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int itemMargin = mItemMargin; final int colWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount; mColWidth = colWidth; int rebuildLayoutRecordsBefore = -1; int rebuildLayoutRecordsAfter = -1; Arrays.fill(mItemBottoms, Integer.MIN_VALUE); final int childCount = getChildCount(); int amountRemoved = 0; for (int i = 0; i < childCount; i++) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int col = lp.column; final int position = mFirstPosition + i; final boolean needsLayout = queryAdapter || child.isLayoutRequested(); if (queryAdapter) { View newView = obtainView(position, child); if (newView == null) { // child has been removed removeViewAt(i); if (i - 1 >= 0) invalidateLayoutRecordsAfterPosition(i - 1); amountRemoved++; continue; } else if (newView != child) { removeViewAt(i); addView(newView, i); child = newView; } lp = (LayoutParams) child.getLayoutParams(); // Might have changed } final int span = Math.min(mColCount, lp.span); final int widthSize = colWidth * span + itemMargin * (span - 1); if (needsLayout) { final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); final int heightSpec; if (lp.height == LayoutParams.WRAP_CONTENT) { heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } else { heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); } child.measure(widthSpec, heightSpec); } int childTop = mItemBottoms[col] > Integer.MIN_VALUE ? mItemBottoms[col] + mItemMargin : child.getTop(); if (span > 1) { int lowest = childTop; for (int j = col + 1; j < col + span; j++) { final int bottom = mItemBottoms[j] + mItemMargin; if (bottom > lowest) { lowest = bottom; } } childTop = lowest; } final int childHeight = child.getMeasuredHeight(); final int childBottom = childTop + childHeight; final int childLeft = paddingLeft + col * (colWidth + itemMargin); final int childRight = childLeft + child.getMeasuredWidth(); child.layout(childLeft, childTop, childRight, childBottom); for (int j = col; j < col + span; j++) { mItemBottoms[j] = childBottom; } final LayoutRecord rec = mLayoutRecords.get(position); if (rec != null && rec.height != childHeight) { // Invalidate our layout records for everything before this. rec.height = childHeight; rebuildLayoutRecordsBefore = position; } if (rec != null && rec.span != span) { // Invalidate our layout records for everything after this. rec.span = span; rebuildLayoutRecordsAfter = position; } } // Update mItemBottoms for any empty columns for (int i = 0; i < mColCount; i++) { if (mItemBottoms[i] == Integer.MIN_VALUE) { mItemBottoms[i] = mItemTops[i]; } } if (rebuildLayoutRecordsBefore >= 0 || rebuildLayoutRecordsAfter >= 0) { if (rebuildLayoutRecordsBefore >= 0) { invalidateLayoutRecordsBeforePosition(rebuildLayoutRecordsBefore); } if (rebuildLayoutRecordsAfter >= 0) { invalidateLayoutRecordsAfterPosition(rebuildLayoutRecordsAfter); } for (int i = 0; i < (childCount - amountRemoved); i++) { final int position = mFirstPosition + i; final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); LayoutRecord rec = mLayoutRecords.get(position); if (rec == null) { rec = new LayoutRecord(); mLayoutRecords.put(position, rec); } rec.column = lp.column; rec.height = child.getHeight(); rec.id = lp.id; rec.span = Math.min(mColCount, lp.span); } } if (this.mSelectorPosition != INVALID_POSITION) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) positionSelector(mMotionPosition, child); } else if (mTouchMode > TOUCH_MODE_DOWN) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) positionSelector(mMotionPosition, child); } else { mSelectorRect.setEmpty(); } }
From source file:com.nttec.everychan.ui.presentation.BoardFragment.java
private void initSearchBar() { if (searchBarInitialized) return;/* w w w . j a v a2s . c o m*/ final EditText field = (EditText) searchBarView.findViewById(R.id.board_search_field); final TextView results = (TextView) searchBarView.findViewById(R.id.board_search_result); if (pageType == TYPE_POSTSLIST) { field.setHint(R.string.search_bar_in_thread_hint); } final View.OnClickListener searchOnClickListener = new View.OnClickListener() { private int lastFound = -1; @Override public void onClick(View v) { if (v != null && v.getId() == R.id.board_search_close) { searchHighlightActive = false; adapter.notifyDataSetChanged(); searchBarView.setVisibility(View.GONE); } else if (listView != null && listView.getChildCount() > 0 && adapter != null && cachedSearchResults != null) { boolean atEnd = listView.getChildAt(listView.getChildCount() - 1).getTop() + listView.getChildAt(listView.getChildCount() - 1).getHeight() == listView.getHeight(); View topView = listView.getChildAt(0); if ((v == null || v.getId() == R.id.board_search_previous) && topView.getTop() < 0 && listView.getChildCount() > 1) topView = listView.getChildAt(1); int currentListPosition = listView.getPositionForView(topView); int newResultIndex = Collections.binarySearch(cachedSearchResults, currentListPosition); if (newResultIndex >= 0) { if (v != null) { if (v.getId() == R.id.board_search_next) ++newResultIndex; else if (v.getId() == R.id.board_search_previous) --newResultIndex; } } else { newResultIndex = -newResultIndex - 1; if (v != null && v.getId() == R.id.board_search_previous) --newResultIndex; } while (newResultIndex < 0) newResultIndex += cachedSearchResults.size(); newResultIndex %= cachedSearchResults.size(); if (v != null && v.getId() == R.id.board_search_next && lastFound == newResultIndex && atEnd) newResultIndex = 0; lastFound = newResultIndex; listView.setSelection(cachedSearchResults.get(newResultIndex)); results.setText((newResultIndex + 1) + "/" + cachedSearchResults.size()); } } }; for (int id : new int[] { R.id.board_search_close, R.id.board_search_previous, R.id.board_search_next }) { searchBarView.findViewById(id).setOnClickListener(searchOnClickListener); } field.setOnKeyListener(new View.OnKeyListener() { private boolean searchUsingChan() { if (pageType != TYPE_THREADSLIST) return false; if (presentationModel != null) if (presentationModel.source != null) if (presentationModel.source.boardModel != null) if (!presentationModel.source.boardModel.searchAllowed) return false; return true; } @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { if (searchUsingChan()) { UrlPageModel model = new UrlPageModel(); model.chanName = chan.getChanName(); model.type = UrlPageModel.TYPE_SEARCHPAGE; model.boardName = tabModel.pageModel.boardName; model.searchRequest = field.getText().toString(); UrlHandler.open(model, activity); } else { int highlightColor = ThemeUtils.getThemeColor(activity.getTheme(), R.attr.searchHighlightBackground, Color.RED); String request = field.getText().toString().toLowerCase(Locale.US); if (cachedSearchRequest == null || !request.equals(cachedSearchRequest)) { cachedSearchRequest = request; cachedSearchResults = new ArrayList<Integer>(); cachedSearchHighlightedSpanables = new SparseArray<Spanned>(); List<PresentationItemModel> safePresentationList = presentationModel .getSafePresentationList(); if (safePresentationList != null) { for (int i = 0; i < safePresentationList.size(); ++i) { PresentationItemModel model = safePresentationList.get(i); if (model.hidden && !staticSettings.showHiddenItems) continue; String comment = model.spannedComment.toString().toLowerCase(Locale.US) .replace('\n', ' '); List<Integer> altFoundPositions = null; if (model.floating) { int floatingpos = FlowTextHelper.getFloatingPosition(model.spannedComment); if (floatingpos != -1 && floatingpos < model.spannedComment.length() && model.spannedComment.charAt(floatingpos) == '\n') { String altcomment = comment.substring(0, floatingpos) + comment.substring(floatingpos + 1, Math.min(model.spannedComment.length(), floatingpos + request.length())); int start = 0; int curpos; while (start < altcomment.length() && (curpos = altcomment.indexOf(request, start)) != -1) { if (altFoundPositions == null) altFoundPositions = new ArrayList<Integer>(); altFoundPositions.add(curpos); start = curpos + request.length(); } } } if (comment.contains(request) || altFoundPositions != null) { cachedSearchResults.add(Integer.valueOf(i)); SpannableStringBuilder spannedHighlited = new SpannableStringBuilder( safePresentationList.get(i).spannedComment); int start = 0; int curpos; while (start < comment.length() && (curpos = comment.indexOf(request, start)) != -1) { start = curpos + request.length(); if (altFoundPositions != null && Collections.binarySearch(altFoundPositions, curpos) >= 0) continue; spannedHighlited.setSpan(new BackgroundColorSpan(highlightColor), curpos, curpos + request.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } if (altFoundPositions != null) { for (Integer pos : altFoundPositions) { spannedHighlited.setSpan(new BackgroundColorSpan(highlightColor), pos, pos + request.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } cachedSearchHighlightedSpanables.put(i, spannedHighlited); } } } } if (cachedSearchResults.size() == 0) { Toast.makeText(activity, R.string.notification_not_found, Toast.LENGTH_LONG).show(); } else { boolean firstTime = !searchHighlightActive; searchHighlightActive = true; adapter.notifyDataSetChanged(); searchBarView.findViewById(R.id.board_search_next).setVisibility(View.VISIBLE); searchBarView.findViewById(R.id.board_search_previous).setVisibility(View.VISIBLE); searchBarView.findViewById(R.id.board_search_result).setVisibility(View.VISIBLE); searchOnClickListener .onClick(firstTime ? null : searchBarView.findViewById(R.id.board_search_next)); } } try { InputMethodManager imm = (InputMethodManager) activity .getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(field.getWindowToken(), 0); } catch (Exception e) { Logger.e(TAG, e); } return true; } return false; } }); field.addTextChangedListener(new OnSearchTextChangedListener(this)); field.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); if (resources.getDimensionPixelSize(R.dimen.panel_height) < field.getMeasuredHeight()) searchBarView.getLayoutParams().height = field.getMeasuredHeight(); searchBarInitialized = true; }
From source file:com.nttec.everychan.ui.presentation.BoardFragment.java
private void saveCurrentPostPosition() { try {//from w ww. j a va2 s . co m String startItemNumber; int startItemTop; if (/*pageType == TYPE_POSTSLIST && */nullAdapterIsSet) { startItemNumber = nullAdapterSavedNumber; startItemTop = nullAdapterSavedTop; } else if (listView != null && listView.getChildCount() > 0 && adapter != null) { View v = listView.getChildAt(0); int position = listView.getPositionForView(v); PresentationItemModel model = adapter.getItem(position); startItemNumber = model.sourceModel.number; startItemTop = v == null ? 0 : v.getTop(); } else return; if (startItemTop != tabModel.startItemTop || !startItemNumber.equals(tabModel.startItemNumber)) { tabModel.startItemNumber = startItemNumber; tabModel.startItemTop = startItemTop; MainApplication.getInstance().serializer .serializeTabsState(MainApplication.getInstance().tabsState); } } catch (Exception e) { Logger.e(TAG, e); } }
From source file:app.umitems.greenclock.widget.sgv.StaggeredGridView.java
/** * Return the current scroll state of this view. * @return {@link ScrollState} The current scroll state */// ww w . ja v a 2s .c o m public ScrollState getScrollState() { final View v = getChildAt(0); if (v == null) { return null; } final LayoutParams lp = (LayoutParams) v.getLayoutParams(); // Since top padding varies with screen orientation, it is not stored in the scroll state // when the scroll adapter position is the first child. final int offset = (lp.position == 0 ? v.getTop() - getPaddingTop() : v.getTop()); return new ScrollState(lp.id, lp.position, offset); }
From source file:cc.flydev.launcher.Workspace.java
void mapPointFromChildToSelf(View v, float[] xy) { xy[0] += v.getLeft(); xy[1] += v.getTop(); }
From source file:com.ad.view.staggeredgridview.StaggeredGridView.java
/** * Measure and layout all currently visible children. * // w w w . j a va 2 s. c o m * @param queryAdapter * true to requery the adapter for view data */ final void layoutChildren(boolean queryAdapter) { final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int itemMargin = mItemMargin; final int colWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount; mColWidth = colWidth; int rebuildLayoutRecordsBefore = -1; int rebuildLayoutRecordsAfter = -1; Arrays.fill(mItemBottoms, Integer.MIN_VALUE); final int childCount = getChildCount(); int amountRemoved = 0; for (int i = 0; i < childCount; i++) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int col = lp.column; final int position = mFirstPosition + i; final boolean needsLayout = queryAdapter || child.isLayoutRequested(); if (queryAdapter) { View newView = obtainView(position, child); if (newView == null) { // child has been removed removeViewAt(i); if (i - 1 >= 0) invalidateLayoutRecordsAfterPosition(i - 1); amountRemoved++; continue; } else if (newView != child) { removeViewAt(i); addView(newView, i); child = newView; } lp = (LayoutParams) child.getLayoutParams(); // Might have // changed } final int span = Math.min(mColCount, lp.span); final int widthSize = colWidth * span + itemMargin * (span - 1); if (needsLayout) { final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); final int heightSpec; if (lp.height == LayoutParams.WRAP_CONTENT) { heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } else { heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); } child.measure(widthSpec, heightSpec); } int childTop = mItemBottoms[col] > Integer.MIN_VALUE ? mItemBottoms[col] + mItemMargin : child.getTop(); if (span > 1) { int lowest = childTop; for (int j = col + 1; j < col + span; j++) { final int bottom = mItemBottoms[j] + mItemMargin; if (bottom > lowest) { lowest = bottom; } } childTop = lowest; } final int childHeight = child.getMeasuredHeight(); final int childBottom = childTop + childHeight; final int childLeft = paddingLeft + col * (colWidth + itemMargin); final int childRight = childLeft + child.getMeasuredWidth(); child.layout(childLeft, childTop, childRight, childBottom); for (int j = col; j < col + span; j++) { mItemBottoms[j] = childBottom; } final LayoutRecord rec = mLayoutRecords.get(position); if (rec != null && rec.height != childHeight) { // Invalidate our layout records for everything before this. rec.height = childHeight; rebuildLayoutRecordsBefore = position; } if (rec != null && rec.span != span) { // Invalidate our layout records for everything after this. rec.span = span; rebuildLayoutRecordsAfter = position; } } // Update mItemBottoms for any empty columns for (int i = 0; i < mColCount; i++) { if (mItemBottoms[i] == Integer.MIN_VALUE) { mItemBottoms[i] = mItemTops[i]; } } if (rebuildLayoutRecordsBefore >= 0 || rebuildLayoutRecordsAfter >= 0) { if (rebuildLayoutRecordsBefore >= 0) { invalidateLayoutRecordsBeforePosition(rebuildLayoutRecordsBefore); } if (rebuildLayoutRecordsAfter >= 0) { invalidateLayoutRecordsAfterPosition(rebuildLayoutRecordsAfter); } for (int i = 0; i < (childCount - amountRemoved); i++) { final int position = mFirstPosition + i; final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); LayoutRecord rec = mLayoutRecords.get(position); if (rec == null) { rec = new LayoutRecord(); mLayoutRecords.put(position, rec); } rec.column = lp.column; rec.height = child.getHeight(); rec.id = lp.id; rec.span = Math.min(mColCount, lp.span); } } if (this.mSelectorPosition != INVALID_POSITION) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) positionSelector(mMotionPosition, child); } else if (mTouchMode > TOUCH_MODE_DOWN) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) positionSelector(mMotionPosition, child); } else { mSelectorRect.setEmpty(); } }