android.graphics.Rect#intersect ( )源码实例Demo

下面列出了android.graphics.Rect#intersect ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: talkback   文件: SwitchAccessNodeCompat.java
private void reduceVisibleRectangleForWindowsAbove(Rect visibleRect) {
  Trace.beginSection("SwitchAccessNodeCompat#reduceVisibleRectangleForWindowsAbove");
  Rect windowBoundsInScreen = new Rect();
  int visibleRectWidth = visibleRect.right - visibleRect.left;
  int visibleRectHeight = visibleRect.bottom - visibleRect.top;
  for (int i = 0; i < windowsAbove.size(); ++i) {
    windowsAbove.get(i).getBoundsInScreen(windowBoundsInScreen);
    windowBoundsInScreen.sort();
    Rect intersectingRectangle = new Rect(visibleRect);
    if (intersectingRectangle.intersect(windowBoundsInScreen)) {
      // If the rect above occupies less than a fraction of both sides of this rect, don't
      // adjust this rect's bounds. This prevents things like FABs changing the bounds
      // of scroll views under them.
      if (((intersectingRectangle.right - intersectingRectangle.left)
              < (visibleRectWidth * MIN_INTERSECTION_TO_CROP))
          && ((intersectingRectangle.bottom - intersectingRectangle.top)
              < (visibleRectHeight * MIN_INTERSECTION_TO_CROP))) {
        Trace.endSection();
        return;
      }
      adjustRectToAvoidIntersection(visibleRect, windowBoundsInScreen);
    }
  }
  Trace.endSection();
}
 
源代码2 项目: za-Farmer   文件: AccessibilityNodeInfoHelper.java
/**
 * Returns the node's bounds clipped to the size of the display
 *
 * @param node
 * @param width pixel width of the display
 * @param height pixel height of the display
 * @return null if node is null, else a Rect containing visible bounds
 */
static Rect getVisibleBoundsInScreen(AccessibilityNodeInfo node, int width, int height) {
    if (node == null) {
        return null;
    }
    // targeted node's bounds
    Rect nodeRect = new Rect();
    node.getBoundsInScreen(nodeRect);

    Rect displayRect = new Rect();
    displayRect.top = 0;
    displayRect.left = 0;
    displayRect.right = width;
    displayRect.bottom = height;

    nodeRect.intersect(displayRect);
    return nodeRect;
}
 
源代码3 项目: GankGirl   文件: VegaLayoutManager.java
public int getSnapHeight() {
    if (!needSnap) {
        return 0;
    }
    needSnap = false;

    Rect displayRect = new Rect(0, scroll, getWidth(), getHeight() + scroll);
    int itemCount = getItemCount();
    for (int i = 0; i < itemCount; i++) {
        Rect itemRect = locationRects.get(i);
        if (displayRect.intersect(itemRect)) {

            if (lastDy > 0) {
                // scroll变大,属于列表往下走,往下找下一个为snapView
                if (i < itemCount - 1) {
                    Rect nextRect = locationRects.get(i + 1);
                    return nextRect.top - displayRect.top;
                }
            }
            return itemRect.top - displayRect.top;
        }
    }
    return 0;
}
 
源代码4 项目: materialup   文件: ViewUtils.java
/**
 * Determines if two views intersect in the window.
 */
public static boolean viewsIntersect(View view1, View view2) {
    final int[] view1Loc = new int[2];
    view1.getLocationOnScreen(view1Loc);
    final Rect view1Rect = new Rect(view1Loc[0],
            view1Loc[1],
            view1Loc[0] + view1.getWidth(),
            view1Loc[1] + view1.getHeight());
    int[] view2Loc = new int[2];
    view2.getLocationOnScreen(view2Loc);
    final Rect view2Rect = new Rect(view2Loc[0],
            view2Loc[1],
            view2Loc[0] + view2.getWidth(),
            view2Loc[1] + view2.getHeight());
    return view1Rect.intersect(view2Rect);
}
 
源代码5 项目: PUMA   文件: LaunchApp.java
/**
* Finds the visible bounds of a partially visible UI element
*
* @param node
* @return null if node is null, else a Rect containing visible bounds
*/
private Rect getVisibleBounds(AccessibilityNodeInfo node) {
	if (node == null) {
		return null;
	}

	// targeted node's bounds
	int w = MyUiDevice.getInstance().getDisplayWidth();
	int h = MyUiDevice.getInstance().getDisplayHeight();
	Rect nodeRect = MyAccessibilityNodeInfoHelper.getVisibleBoundsInScreen(node, w, h);

	// is the targeted node within a scrollable container?
	AccessibilityNodeInfo scrollableParentNode = getScrollableParent(node);
	if (scrollableParentNode == null) {
		// nothing to adjust for so return the node's Rect as is
		return nodeRect;
	}

	// Scrollable parent's visible bounds
	Rect parentRect = MyAccessibilityNodeInfoHelper.getVisibleBoundsInScreen(scrollableParentNode, w, h);
	// adjust for partial clipping of targeted by parent node if required
	nodeRect.intersect(parentRect);
	return nodeRect;
}
 
源代码6 项目: PUMA   文件: MyAccessibilityNodeInfoSuite.java
public static boolean compareAccessibilityNodeInfo(AccessibilityNodeInfo n1, AccessibilityNodeInfo n2) {
	if (n1 != null && n2 != null) {
		String c1 = n1.getClassName().toString();
		String c2 = n2.getClassName().toString();

		Rect b1 = new Rect();
		Rect b2 = new Rect();
		n1.getBoundsInScreen(b1);
		n2.getBoundsInScreen(b2);

		int a1 = b1.height() * b1.width();
		b1.intersect(b2);
		int a2 = b1.height() * b1.width();

		return c1.equals(c2) && (a2 > ((int) (a1 * 0.95)));
	} else {
		return false;
	}
}
 
源代码7 项目: JsDroidCmd   文件: UiObject.java
/**
 * Finds the visible bounds of a partially visible UI element
 *
 * @param node
 * @return null if node is null, else a Rect containing visible bounds
 */
private Rect getVisibleBounds(AccessibilityNodeInfo node) {
    if (node == null) {
        return null;
    }

    // targeted node's bounds
    int w = mDevice.getDisplayWidth();
    int h = mDevice.getDisplayHeight();
    Rect nodeRect = AccessibilityNodeInfoHelper.getVisibleBoundsInScreen(node, w, h);

    // is the targeted node within a scrollable container?
    AccessibilityNodeInfo scrollableParentNode = getScrollableParent(node);
    if(scrollableParentNode == null) {
        // nothing to adjust for so return the node's Rect as is
        return nodeRect;
    }

    // Scrollable parent's visible bounds
    Rect parentRect = AccessibilityNodeInfoHelper
            .getVisibleBoundsInScreen(scrollableParentNode, w, h);
    // adjust for partial clipping of targeted by parent node if required
    nodeRect.intersect(parentRect);
    return nodeRect;
}
 
源代码8 项目: Magnet   文件: Magnet.java
protected boolean iconOverlapsWithRemoveView() {
  if (removeView.isShowing()) {
    View firstView = removeView.buttonImage;
    View secondView = iconView;
    int[] firstPosition = new int[2];
    int[] secondPosition = new int[2];

    firstView.getLocationOnScreen(firstPosition);
    secondView.getLocationOnScreen(secondPosition);

    // Rect constructor parameters: left, top, right, bottom
    Rect rectFirstView = new Rect(firstPosition[0], firstPosition[1],
        firstPosition[0] + firstView.getMeasuredWidth(),
        firstPosition[1] + firstView.getMeasuredHeight());
    Rect rectSecondView = new Rect(secondPosition[0], secondPosition[1],
        secondPosition[0] + secondView.getMeasuredWidth(),
        secondPosition[1] + secondView.getMeasuredHeight());
    return rectFirstView.intersect(rectSecondView);
  }
  return false;
}
 
源代码9 项目: JsDroidCmd   文件: AccessibilityNodeInfoHelper.java
/**
 * Returns the node's bounds clipped to the size of the display
 *
 * @param node
 * @param width pixel width of the display
 * @param height pixel height of the display
 * @return null if node is null, else a Rect containing visible bounds
 */
static Rect getVisibleBoundsInScreen(AccessibilityNodeInfo node, int width, int height) {
    if (node == null) {
        return null;
    }
    // targeted node's bounds
    Rect nodeRect = new Rect();
    node.getBoundsInScreen(nodeRect);

    Rect displayRect = new Rect();
    displayRect.top = 0;
    displayRect.left = 0;
    displayRect.right = width;
    displayRect.bottom = height;

    nodeRect.intersect(displayRect);
    return nodeRect;
}
 
源代码10 项目: Viewer   文件: CameraPreview.java
/**
 * Calculate framing rectangle, relative to the preview frame.
 *
 * Note that the SurfaceView may be larger than the container.
 *
 * Override this for more control over the framing rect calculations.
 *
 * @param container this container, with left = top = 0
 * @param surface   the SurfaceView, relative to this container
 * @return the framing rect, relative to this container
 */
protected Rect calculateFramingRect(Rect container, Rect surface) {
    // intersection is the part of the container that is used for the preview
    Rect intersection = new Rect(container);
    boolean intersects = intersection.intersect(surface);

    if(framingRectSize != null) {
        // Specific size is specified. Make sure it's not larger than the container or surface.
        int horizontalMargin = Math.max(0, (intersection.width() - framingRectSize.width) / 2);
        int verticalMargin = Math.max(0, (intersection.height() - framingRectSize.height) / 2);
        intersection.inset(horizontalMargin, verticalMargin);
        return intersection;
    }
    // margin as 10% (default) of the smaller of width, height
    int margin = (int)Math.min(intersection.width() * marginFraction, intersection.height() * marginFraction);
    intersection.inset(margin, margin);
    if (intersection.height() > intersection.width()) {
        // We don't want a frame that is taller than wide.
        intersection.inset(0, (intersection.height() - intersection.width()) / 2);
    }
    return intersection;
}
 
源代码11 项目: TheGreatAdapter   文件: ViewUtils.java
/**
 * Determines if two views intersect in the window.
 */
public static boolean viewsIntersect(View view1, View view2) {
    if (view1 == null || view2 == null) return false;

    final int[] view1Loc = new int[2];
    view1.getLocationOnScreen(view1Loc);
    final Rect view1Rect = new Rect(view1Loc[0],
            view1Loc[1],
            view1Loc[0] + view1.getWidth(),
            view1Loc[1] + view1.getHeight());
    int[] view2Loc = new int[2];
    view2.getLocationOnScreen(view2Loc);
    final Rect view2Rect = new Rect(view2Loc[0],
            view2Loc[1],
            view2Loc[0] + view2.getWidth(),
            view2Loc[1] + view2.getHeight());
    return view1Rect.intersect(view2Rect);
}
 
源代码12 项目: aptoide-client-v8   文件: AppCoinsInfoFragment.java
public boolean isAppItemShown() {
  final Rect placeHolderPosition = new Rect();
  appCardView.getLocalVisibleRect(placeHolderPosition);
  final Rect screen =
      new Rect(0, 0, (int) screenWidth, (int) screenHeight - appCardView.getHeight() * 2);
  return placeHolderPosition.intersect(screen);
}
 
源代码13 项目: DateTimepicker   文件: TouchExplorationHelper.java
/**
 * Computes whether the specified {@link Rect} intersects with the visible
 * portion of its parent {@link View}. Modifies {@code localRect} to
 * contain only the visible portion.
 *
 * @param localRect A rectangle in local (parent) coordinates.
 * @return Whether the specified {@link Rect} is visible on the screen.
 */
private boolean intersectVisibleToUser(Rect localRect) {
    // Missing or empty bounds mean this view is not visible.
    if ((localRect == null) || localRect.isEmpty()) {
        return false;
    }

    // Attached to invisible window means this view is not visible.
    if (mParentView.getWindowVisibility() != View.VISIBLE) {
        return false;
    }

    // An invisible predecessor or one with alpha zero means
    // that this view is not visible to the user.
    Object current = this;
    while (current instanceof View) {
        final View view = (View) current;
        // We have attach info so this view is attached and there is no
        // need to check whether we reach to ViewRootImpl on the way up.
        if ((view.getAlpha() <= 0) || (view.getVisibility() != View.VISIBLE)) {
            return false;
        }
        current = view.getParent();
    }

    // If no portion of the parent is visible, this view is not visible.
    if (!mParentView.getLocalVisibleRect(mTempVisibleRect)) {
        return false;
    }

    // Check if the view intersects the visible portion of the parent.
    return localRect.intersect(mTempVisibleRect);
}
 
/**
 * Computes whether the specified {@link Rect} intersects with the visible
 * portion of its parent {@link View}. Modifies {@code localRect} to contain
 * only the visible portion.
 *
 * @param localRect A rectangle in local (parent) coordinates.
 * @return Whether the specified {@link Rect} is visible on the screen.
 */
private boolean intersectVisibleToUser(Rect localRect) {
    // Missing or empty bounds mean this view is not visible.
    if ((localRect == null) || localRect.isEmpty()) {
        return false;
    }

    // Attached to invisible window means this view is not visible.
    if (mView.getWindowVisibility() != View.VISIBLE) {
        return false;
    }

    // An invisible predecessor means that this view is not visible.
    ViewParent viewParent = mView.getParent();
    while (viewParent instanceof View) {
        final View view = (View) viewParent;
        if ((ViewCompat.getAlpha(view) <= 0) || (view.getVisibility() != View.VISIBLE)) {
            return false;
        }
        viewParent = view.getParent();
    }

    // A null parent implies the view is not visible.
    if (viewParent == null) {
        return false;
    }

    // If no portion of the parent is visible, this view is not visible.
    if (!mView.getLocalVisibleRect(mTempVisibleRect)) {
        return false;
    }

    // Check if the view intersects the visible portion of the parent.
    return localRect.intersect(mTempVisibleRect);
}
 
源代码15 项目: android-recipes-app   文件: ExploreByTouchHelper.java
/**
 * Computes whether the specified {@link Rect} intersects with the visible
 * portion of its parent {@link View}. Modifies {@code localRect} to contain
 * only the visible portion.
 *
 * @param localRect A rectangle in local (parent) coordinates.
 * @return Whether the specified {@link Rect} is visible on the screen.
 */
private boolean intersectVisibleToUser(Rect localRect) {
    // Missing or empty bounds mean this view is not visible.
    if ((localRect == null) || localRect.isEmpty()) {
        return false;
    }

    // Attached to invisible window means this view is not visible.
    if (mView.getWindowVisibility() != View.VISIBLE) {
        return false;
    }

    // An invisible predecessor means that this view is not visible.
    ViewParent viewParent = mView.getParent();
    while (viewParent instanceof View) {
        final View view = (View) viewParent;
        if ((ViewCompat.getAlpha(view) <= 0) || (view.getVisibility() != View.VISIBLE)) {
            return false;
        }
        viewParent = view.getParent();
    }

    // A null parent implies the view is not visible.
    if (viewParent == null) {
        return false;
    }

    // If no portion of the parent is visible, this view is not visible.
    if (!mView.getLocalVisibleRect(mTempVisibleRect)) {
        return false;
    }

    // Check if the view intersects the visible portion of the parent.
    return localRect.intersect(mTempVisibleRect);
}
 
源代码16 项目: SmartSwipe   文件: ViewCompat.java
/**
 * Offset this view's horizontal location by the specified amount of pixels.
 *
 * @param view view
 * @param offset the number of pixels to offset the view by
 */
public static void offsetLeftAndRight(View view, int offset) {
    if (view == null || offset == 0) {
        return;
    }
    if (Build.VERSION.SDK_INT >= 23) {
        view.offsetLeftAndRight(offset);
    } else if (Build.VERSION.SDK_INT >= 21) {
        final Rect parentRect = getEmptyTempRect();
        boolean needInvalidateWorkaround = false;

        final ViewParent parent = view.getParent();
        if (parent instanceof View) {
            final View p = (View) parent;
            parentRect.set(p.getLeft(), p.getTop(), p.getRight(), p.getBottom());
            // If the view currently does not currently intersect the parent (and is therefore
            // not displayed) we may need need to invalidate
            needInvalidateWorkaround = !parentRect.intersects(view.getLeft(), view.getTop(),
                    view.getRight(), view.getBottom());
        }

        // Now offset, invoking the API 14+ implementation (which contains its own workarounds)
        compatOffsetLeftAndRight(view, offset);

        // The view has now been offset, so let's intersect the Rect and invalidate where
        // the View is now displayed
        if (needInvalidateWorkaround && parentRect.intersect(view.getLeft(), view.getTop(),
                view.getRight(), view.getBottom())) {
            ((View) parent).invalidate(parentRect);
        }
    } else {
        compatOffsetLeftAndRight(view, offset);
    }
}
 
源代码17 项目: Reader   文件: PDFPageView.java
@Override
public void updateHq(boolean update) {
    Rect viewArea = new Rect(getLeft(), getTop(), getRight(), getBottom());
    if (viewArea.width() == mSize.x || viewArea.height() == mSize.y) {
        // If the viewArea's size matches the unzoomed size, there is no need for an hq patch
        if (mPatch != null) {
            mPatch.setImageBitmap(null);
            mPatch.invalidate();
        }
    } else {
        //当前Pageview的实际大小
        final Point patchViewSize = new Point(viewArea.width(), viewArea.height());
        //表示实际要显示pdf的区域,也就是pdf与屏幕的重叠处
        final Rect patchArea = new Rect(0, 0, mParentSize.x, mParentSize.y);

        // Intersect and test that there is an intersection
        if (!patchArea.intersect(viewArea)) {
            return;
        }

        //重新计算重叠处的坐标,这个坐标是相对于当前PDF实际大小
        // Offset patch area to be relative to the view top left
        patchArea.offset(-viewArea.left, -viewArea.top);
        boolean area_unchanged = patchArea.equals(mPatchArea) && patchViewSize.equals(mPatchViewSize);

        // If being asked for the same area as last time and not because of an update then nothing to do
        if (area_unchanged && !update)
            return;
        boolean completeRedraw = !(area_unchanged && update);
        // Stop the drawing of previous patch if still going
        if (mDrawPatch != null) {
            mDrawPatch.cancelAndWait();
            mDrawPatch = null;
        }

        // Create and add the image view if not already done
        if (mPatch == null) {
            mPatch = new OpaqueImageView(mContext);
            mPatch.setScaleType(ImageView.ScaleType.MATRIX);
            addView(mPatch);
            mSearchView.bringToFront();
        }

        CancellableTaskDefinition<Void, Void> task;

        if (completeRedraw) {
            task = getDrawPageTask(mPatchBm, patchViewSize.x, patchViewSize.y,
                    patchArea.left, patchArea.top,
                    patchArea.width(), patchArea.height());
        } else {
            task = getUpdatePageTask(mPatchBm, patchViewSize.x, patchViewSize.y,
                    patchArea.left, patchArea.top,
                    patchArea.width(), patchArea.height());
        }

        mDrawPatch = new CancellableAsyncTask<Void, Void>(task) {

            public void onPostExecute(Void result) {
                mPatchViewSize = patchViewSize;
                mPatchArea = patchArea;
                mPatch.setImageBitmap(mPatchBm);
                mPatch.invalidate();
                //requestLayout();
                // Calling requestLayout here doesn't lead to a later call to layout. No idea
                // why, but apparently others have run into the problem.
                mPatch.layout(mPatchArea.left, mPatchArea.top, mPatchArea.right, mPatchArea.bottom);
            }
        };

        mDrawPatch.execute();
    }
}
 
源代码18 项目: AndroidDocumentViewer   文件: PageView.java
public void updateHq(boolean update) {
    Rect viewArea = new Rect(getLeft(), getTop(), getRight(), getBottom());
    if (viewArea.width() == mSize.x || viewArea.height() == mSize.y) {
        // If the viewArea's size matches the unzoomed size, there is no need for an hq patch
        if (mPatch != null) {
            mPatch.setImageBitmap(null);
            mPatch.invalidate();
        }
    } else {
        final Point patchViewSize = new Point(viewArea.width(), viewArea.height());
        final Rect patchArea = new Rect(0, 0, mParentSize.x, mParentSize.y);

        // Intersect and test that there is an intersection
        if (!patchArea.intersect(viewArea))
            return;

        // Offset patch area to be relative to the view top left
        patchArea.offset(-viewArea.left, -viewArea.top);

        boolean area_unchanged = patchArea.equals(mPatchArea) && patchViewSize.equals(mPatchViewSize);

        // If being asked for the same area as last time and not because of an update then nothing to do
        if (area_unchanged && !update)
            return;

        boolean completeRedraw = !(area_unchanged && update);

        // Stop the drawing of previous patch if still going
        if (mDrawPatch != null) {
            mDrawPatch.cancel();
            mDrawPatch = null;
        }

        // Create and add the image view if not already done
        if (mPatch == null) {
            mPatch = new OpaqueImageView(mContext);
            mPatch.setScaleType(ImageView.ScaleType.MATRIX);
            addView(mPatch);
            mSearchView.bringToFront();
        }

        CancellableTaskDefinition<Void, Void> task;

        if (completeRedraw)
            task = getDrawPageTask(mPatchBm, patchViewSize.x, patchViewSize.y,
                    patchArea.left, patchArea.top,
                    patchArea.width(), patchArea.height());
        else
            task = getUpdatePageTask(mPatchBm, patchViewSize.x, patchViewSize.y,
                    patchArea.left, patchArea.top,
                    patchArea.width(), patchArea.height());

        mDrawPatch = new CancellableAsyncTask<Void, Void>(task) {

            public void onPostExecute(Void result) {
                mPatchViewSize = patchViewSize;
                mPatchArea = patchArea;
                mPatch.setImageBitmap(mPatchBm);
                mPatch.invalidate();
                //requestLayout();
                // Calling requestLayout here doesn't lead to a later call to layout. No idea
                // why, but apparently others have run into the problem.
                mPatch.layout(mPatchArea.left, mPatchArea.top, mPatchArea.right, mPatchArea.bottom);
            }
        };

        mDrawPatch.execute();
    }
}
 
源代码19 项目: AndroidMuPDF   文件: PageView.java
public void updateHq(boolean update) {
	Rect viewArea = new Rect(getLeft(),getTop(),getRight(),getBottom());
	if (viewArea.width() == mSize.x || viewArea.height() == mSize.y) {
		// If the viewArea's size matches the unzoomed size, there is no need for an hq patch
		if (mPatch != null) {
			mPatch.setImageBitmap(null);
			mPatch.invalidate();
		}
	} else {
		final Point patchViewSize = new Point(viewArea.width(), viewArea.height());
		final Rect patchArea = new Rect(0, 0, mParentSize.x, mParentSize.y);

		// Intersect and test that there is an intersection
		if (!patchArea.intersect(viewArea))
			return;

		// Offset patch area to be relative to the view top left
		patchArea.offset(-viewArea.left, -viewArea.top);

		boolean area_unchanged = patchArea.equals(mPatchArea) && patchViewSize.equals(mPatchViewSize);

		// If being asked for the same area as last time and not because of an update then nothing to do
		if (area_unchanged && !update)
			return;

		boolean completeRedraw = !(area_unchanged && update);

		// Stop the drawing of previous patch if still going
		if (mDrawPatch != null) {
			mDrawPatch.cancel();
			mDrawPatch = null;
		}

		// Create and add the image view if not already done
		if (mPatch == null) {
			mPatch = new OpaqueImageView(mContext);
			mPatch.setScaleType(ImageView.ScaleType.MATRIX);
			addView(mPatch);
			mSearchView.bringToFront();
		}

		CancellableTaskDefinition<Void, Void> task;

		if (completeRedraw)
			task = getDrawPageTask(mPatchBm, patchViewSize.x, patchViewSize.y,
							patchArea.left, patchArea.top,
							patchArea.width(), patchArea.height());
		else
			task = getUpdatePageTask(mPatchBm, patchViewSize.x, patchViewSize.y,
					patchArea.left, patchArea.top,
					patchArea.width(), patchArea.height());

		mDrawPatch = new CancellableAsyncTask<Void,Void>(task) {

			public void onPostExecute(Void result) {
				mPatchViewSize = patchViewSize;
				mPatchArea = patchArea;
				mPatch.setImageBitmap(mPatchBm);
				mPatch.invalidate();
				//requestLayout();
				// Calling requestLayout here doesn't lead to a later call to layout. No idea
				// why, but apparently others have run into the problem.
				mPatch.layout(mPatchArea.left, mPatchArea.top, mPatchArea.right, mPatchArea.bottom);
			}
		};

		mDrawPatch.execute();
	}
}
 
/**
 * 回收和填充布局
 *
 * @param recycler Recycler
 * @param state    State
 * @param isStart  是否从头开始,用于控制View遍历方向,true 为从头到尾,false 为从尾到头
 */
@SuppressLint("CheckResult")
private void recycleAndFillItems(RecyclerView.Recycler recycler, RecyclerView.State state,
                                 boolean isStart) {
    if (state.isPreLayout()) {
        return;
    }

    Logi("mOffsetX = " + mOffsetX);
    Logi("mOffsetY = " + mOffsetY);

    // 计算显示区域区前后多存储一列或则一行
    Rect displayRect = new Rect(mOffsetX - mItemWidth, mOffsetY - mItemHeight,
            getUsableWidth() + mOffsetX + mItemWidth, getUsableHeight() + mOffsetY + mItemHeight);
    // 对显显示区域进行修正(计算当前显示区域和最大显示区域对交集)
    displayRect.intersect(0, 0, mMaxScrollX + getUsableWidth(), mMaxScrollY + getUsableHeight());
    Loge("displayRect = " + displayRect.toString());

    int startPos = 0;                  // 获取第一个条目的Pos
    int pageIndex = getPageIndexByOffset();
    startPos = pageIndex * mOnePageSize;
    Logi("startPos = " + startPos);
    startPos = startPos - mOnePageSize * 2;
    if (startPos < 0) {
        startPos = 0;
    }
    int stopPos = startPos + mOnePageSize * 4;
    if (stopPos > getItemCount()) {
        stopPos = getItemCount();
    }

    Loge("startPos = " + startPos);
    Loge("stopPos = " + stopPos);

    detachAndScrapAttachedViews(recycler); // 移除所有View

    if (isStart) {
        for (int i = startPos; i < stopPos; i++) {
            addOrRemove(recycler, displayRect, i);
        }
    } else {
        for (int i = stopPos - 1; i >= startPos; i--) {
            addOrRemove(recycler, displayRect, i);
        }
    }
    Loge("child count = " + getChildCount());
}