下面列出了androidx.recyclerview.widget.RecyclerView#getWidth ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@SuppressLint("NewApi")
private void drawVertical(Canvas canvas, RecyclerView parent) {
canvas.save();
final int left;
final int right;
if (parent.getClipToPadding()) {
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
canvas.clipRect(left, parent.getPaddingTop(), right,
parent.getHeight() - parent.getPaddingBottom());
} else {
left = 0;
right = parent.getWidth();
}
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, mBounds);
final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child));
final int top = bottom - mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
canvas.restore();
}
@Override
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() + parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View view = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
if (params == null) continue;
final LocalAdapterItem adapterItem = recyclerAdapter.getLocalAdapterItem(params.getViewAdapterPosition());
if (adapterItem == null) continue;
if (!isRegistered(adapterItem)) {
continue;
}
final int top = view.getBottom() + params.bottomMargin;
final int bottom = top + (dividerHeight / 2);
canvas.drawLine(left, bottom, right, bottom, dividerPaint);
}
}
@Override
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
canvas.save();
final int right;
//noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.
if (parent.getClipToPadding()) {
right = parent.getWidth() - parent.getPaddingRight();
canvas.clipRect(leftPadding, parent.getPaddingTop(), right,
parent.getHeight() - parent.getPaddingBottom());
} else {
right = parent.getWidth();
}
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, bounds);
final int bottom = bounds.bottom + Math.round(child.getTranslationY());
final int top = bottom - 1;
divider.setBounds(leftPadding, top, right, bottom);
divider.draw(canvas);
}
canvas.restore();
}
@Override
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getAdapter().getItemCount();
for (int i = 0; i < childCount; i++) {
if (i == (childCount - 1)) {
continue;
}
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private void drawVertical(Canvas canvas, RecyclerView parent) {
canvas.save();
final int left;
final int right;
if (parent.getClipToPadding()) {
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
canvas.clipRect(left, parent.getPaddingTop(), right,
parent.getHeight() - parent.getPaddingBottom());
} else {
left = 0;
right = parent.getWidth();
}
final int childCount = parent.getChildCount() - (doNotDrawForLastItem ? 1 : 0);
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, mBounds);
final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
final int top = bottom - mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
canvas.restore();
}
@Override
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
int dividerLeft = parent.getPaddingLeft();
int dividerRight = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i <= childCount - 2; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int dividerTop = child.getBottom() + params.bottomMargin;
int dividerBottom = dividerTop + mDivider.getIntrinsicHeight();
mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
mDivider.draw(canvas);
}
}
/**
* Performs the actual calculation for determining the number of possible
* columns by using the {@link #maxColumnCount}, {@link #minColumnSpacingEdge}, and
* {@link #minColumnSpacingSeparator} in conjunction with the requested width
* for the items
*
* @param recyclerView The RecyclerView to use when determining the possible number of columns
* @param gridItemWidth The requested width for items to be
* @return The calculated number of possible columns
*/
protected int getColumnCount(@NonNull RecyclerView recyclerView, int gridItemWidth) {
int padding = recyclerView.getPaddingLeft() + recyclerView.getPaddingRight();
int usableWidth = recyclerView.getWidth() - padding;
int columnCount = Math.min(usableWidth / gridItemWidth, maxColumnCount);
int usedColumnWidth, minRequiredSpacing;
//Decreases the columnCount until the specified min spacing can be achieved.
do {
usedColumnWidth = columnCount * gridItemWidth;
minRequiredSpacing = (2 * minColumnSpacingEdge) + ((columnCount -1) * minColumnSpacingSeparator);
//If the specified min spacing is reached, return the number of columns
if (usableWidth - usedColumnWidth - minRequiredSpacing >= 0) {
return columnCount;
}
columnCount--;
} while(columnCount > 1);
return columnCount;
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (divider != null) {
int count = parent.getChildCount();
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
View child = null;
for (int i = 0; i < count; i++) {
if (count == 1) {
break;
}
child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + divider.getIntrinsicHeight();
divider.setBounds(left, top, right, bottom);
divider.draw(c);
}
}
}
/**
* Update the visibility item according the current layout.
*
* @param view the current {@link com.airbnb.epoxy.EpoxyViewHolder}'s itemView
* @param parent the {@link androidx.recyclerview.widget.RecyclerView}
* @return true if the view has been measured
*/
boolean update(@NonNull View view, @NonNull RecyclerView parent, boolean detachEvent) {
// Clear the rect before calling getLocalVisibleRect
localVisibleRect.setEmpty();
boolean viewDrawn = view.getLocalVisibleRect(localVisibleRect) && !detachEvent;
height = view.getHeight();
width = view.getWidth();
viewportHeight = parent.getHeight();
viewportWidth = parent.getWidth();
visibleHeight = viewDrawn ? localVisibleRect.height() : 0;
visibleWidth = viewDrawn ? localVisibleRect.width() : 0;
return height > 0 && width > 0;
}
private void drawVertical(Canvas canvas, RecyclerView parent) {
canvas.save();
final int left;
final int right;
//noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.
if (parent.getClipToPadding()) {
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
canvas.clipRect(left, parent.getPaddingTop(), right,
parent.getHeight() - parent.getPaddingBottom());
} else {
left = 0;
right = parent.getWidth();
}
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, mBounds);
final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
final int top = bottom - mDividerSize;
mDividerPaint.setColor(mDividerColor);
mDividerPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(left + mMarginStart, top + mMarginTop, right - mMarginEnd, bottom - mMarginBottom, mDividerPaint);
}
canvas.restore();
}
/**
* Called when {@link #onMove(RecyclerView, ViewHolder, ViewHolder)} returns true.
* <p>
* ItemTouchHelper does not create an extra Bitmap or View while dragging, instead, it
* modifies the existing View. Because of this reason, it is important that the View is
* still part of the layout after it is moved. This may not work as intended when swapped
* Views are close to RecyclerView bounds or there are gaps between them (e.g. other Views
* which were not eligible for dropping over).
* <p>
* This method is responsible to give necessary hint to the LayoutManager so that it will
* keep the View in visible area. For example, for LinearLayoutManager, this is as simple
* <p>
* <p>
* Default implementation calls {@link RecyclerView#scrollToPosition(int)} if the View's
* new position is likely to be out of bounds.
* <p>
* It is important to ensure the ViewHolder will stay visible as otherwise, it might be
* removed by the LayoutManager if the move causes the View to go out of bounds. In that
* case, drag will end prematurely.
*
* @param recyclerView The RecyclerView controlled by the ItemTouchHelper.
* @param viewHolder The ViewHolder under user's control.
* @param fromPos The previous adapter position of the dragged item (before it was
* moved).
* @param target The ViewHolder on which the currently active item has been dropped.
* @param toPos The new adapter position of the dragged item.
* @param x The updated left value of the dragged View after drag translations
* are applied. This value does not include margins added by
* {@link RecyclerView.ItemDecoration}s.
* @param y The updated top value of the dragged View after drag translations
* are applied. This value does not include margins added by
* {@link RecyclerView.ItemDecoration}s.
*/
public void onMoved(final RecyclerView recyclerView,
final ViewHolder viewHolder, int fromPos, final ViewHolder target, int toPos, int x,
int y) {
final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof ViewDropHandler) {
((ViewDropHandler) layoutManager).prepareForDrop(viewHolder.itemView,
target.itemView, x, y);
return;
}
// if layout manager cannot handle it, do some guesswork
if (layoutManager.canScrollHorizontally()) {
final int minLeft = layoutManager.getDecoratedLeft(target.itemView);
if (minLeft <= recyclerView.getPaddingLeft()) {
recyclerView.scrollToPosition(toPos);
}
final int maxRight = layoutManager.getDecoratedRight(target.itemView);
if (maxRight >= recyclerView.getWidth() - recyclerView.getPaddingRight()) {
recyclerView.scrollToPosition(toPos);
}
}
if (layoutManager.canScrollVertically()) {
final int minTop = layoutManager.getDecoratedTop(target.itemView);
if (minTop <= recyclerView.getPaddingTop()) {
recyclerView.scrollToPosition(toPos);
}
final int maxBottom = layoutManager.getDecoratedBottom(target.itemView);
if (maxBottom >= recyclerView.getHeight() - recyclerView.getPaddingBottom()) {
recyclerView.scrollToPosition(toPos);
}
}
}
public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
/**
* @param c
* @param parent
* @param state
*/
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (dividerDrawable == null) {
return;
}
int childCount = parent.getChildCount();
int rightV = parent.getWidth();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int leftV = parent.getPaddingLeft() + child.getPaddingLeft();
int bottomV = child.getTop() - params.topMargin;
int topV = bottomV - dividerDrawable.getIntrinsicHeight();
int topH = child.getTop() + params.topMargin;
int bottomH = child.getBottom() + params.bottomMargin;
int rightH = child.getLeft() - params.leftMargin;
int leftH = rightH - dividerDrawable.getIntrinsicWidth();
dividerDrawable.setBounds(leftH, topH, rightH, bottomH);
dividerDrawable.draw(c);
dividerDrawable.setBounds(leftV, topV, rightV, bottomV);
dividerDrawable.draw(c);
}
}
public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + divider.getIntrinsicHeight();
divider.setBounds(left, top, right, bottom);
divider.draw(c);
}
}
private void drawVertical(Canvas canvas, RecyclerView parent) {
canvas.save();
int left;
int right;
if (mDividerPadding != 0) {
left = mDividerPadding;
right = parent.getWidth() - mDividerPadding;
canvas.clipRect(left, parent.getPaddingTop(), right, parent.getHeight() - parent.getPaddingBottom());
} else if (parent.getClipToPadding()) {
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
canvas.clipRect(left, parent.getPaddingTop(), right, parent.getHeight() - parent.getPaddingBottom());
} else {
left = 0;
right = parent.getWidth();
}
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; ++i) {
View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, this.mBounds);
int bottom = this.mBounds.bottom + Math.round(child.getTranslationY());
int top = bottom - this.mDivider.getIntrinsicHeight();
this.mDivider.setBounds(left, top, right, bottom);
this.mDivider.draw(canvas);
}
canvas.restore();
}
private void drawVertical(Canvas c, RecyclerView parent) {
int firstDataItemPosition = 0;
int lastDataItemPosition = 0;
RecyclerView.Adapter adapter = recyclerView.getAdapter();
AssemblyRecyclerAdapter recyclerAdapter = null;
if (adapter instanceof AssemblyRecyclerAdapter) {
recyclerAdapter = (AssemblyRecyclerAdapter) adapter;
firstDataItemPosition = recyclerAdapter.getHeaderCount();
lastDataItemPosition = firstDataItemPosition + (recyclerAdapter.getDataCount() - 1);
}
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
int itemPosition = ((RecyclerView.LayoutParams) child.getLayoutParams()).getViewLayoutPosition();
int bottomMargin = ((RecyclerView.LayoutParams) child.getLayoutParams()).bottomMargin;
if (recyclerAdapter == null || (itemPosition >= firstDataItemPosition && itemPosition <= lastDataItemPosition)) {
final int top = child.getBottom() + bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
@Override
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
canvas.save();
final int left;
final int right;
if (parent.getClipToPadding()) {
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
canvas.clipRect(left, parent.getPaddingTop(), right,
parent.getHeight() - parent.getPaddingBottom());
} else {
left = 0;
right = parent.getWidth();
}
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
if (!hasDivider(parent, child))
continue;
parent.getDecoratedBoundsWithMargins(child, mBounds);
final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child));
final int top = bottom - mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.setAlpha((int) (child.getAlpha() * 255));
mDivider.draw(canvas);
}
canvas.restore();
}
/**
* 绘制悬浮组
*
* @param c Canvas
* @param parent RecyclerView
*/
protected void onDrawOverGroup(Canvas c, RecyclerView parent) {
int firstVisiblePosition = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
if (firstVisiblePosition == RecyclerView.NO_POSITION) {
return;
}
Group group = getCroup(firstVisiblePosition);
if (group == null)
return;
String groupTitle = group.toString();
if (TextUtils.isEmpty(groupTitle)) {
return;
}
boolean isRestore = false;
Group nextGroup = getCroup(firstVisiblePosition + 1);
if (nextGroup != null && !group.equals(nextGroup)) {
//说明是当前组最后一个元素,但不一定碰撞了
View child = parent.findViewHolderForAdapterPosition(firstVisiblePosition).itemView;
if (child.getTop() + child.getMeasuredHeight() < mGroupHeight) {
//进一步检测碰撞
c.save();//保存画布当前的状态
isRestore = true;
c.translate(0, child.getTop() + child.getMeasuredHeight() - mGroupHeight);
}
}
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int top = parent.getPaddingTop();
int bottom = top + mGroupHeight;
c.drawRect(left, top, right, bottom, mBackgroundPaint);
float x;
float y = top + mTextBaseLine;
if (isCenter) {
x = parent.getMeasuredWidth() / 2 - getTextX(groupTitle);
} else {
x = mPaddingLeft;
}
c.drawText(groupTitle, x, y, mTextPaint);
if (isRestore) {
//还原画布为初始状态
c.restore();
}
}
/**
* Call from the owning {@link Component}'s onUnmount. This is where the adapter is removed from
* the {@link RecyclerView}.
*
* @param view the {@link RecyclerView} being unmounted.
*/
@UiThread
@Override
public void unmount(RecyclerView view) {
ThreadUtils.assertMainThread();
if (mIsSubAdapter) {
throw new RuntimeException("Can't unmount a RecyclerView in sub adapter mode");
}
final LayoutManager layoutManager = mLayoutInfo.getLayoutManager();
final View firstView = layoutManager.findViewByPosition(mCurrentFirstVisiblePosition);
if (firstView != null) {
final boolean reverseLayout = getReverseLayout();
if (mLayoutInfo.getScrollDirection() == HORIZONTAL) {
mCurrentOffset =
reverseLayout
? view.getWidth()
- layoutManager.getPaddingRight()
- layoutManager.getDecoratedRight(firstView)
: layoutManager.getDecoratedLeft(firstView) - layoutManager.getPaddingLeft();
} else {
mCurrentOffset =
reverseLayout
? view.getHeight()
- layoutManager.getPaddingBottom()
- layoutManager.getDecoratedBottom(firstView)
: layoutManager.getDecoratedTop(firstView) - layoutManager.getPaddingTop();
}
} else {
mCurrentOffset = 0;
}
view.removeOnScrollListener(mViewportManager.getScrollListener());
unregisterDrawListener(view);
maybeDispatchDataRendered();
view.setAdapter(null);
view.setLayoutManager(null);
mViewportManager.removeViewportChangedListener(mViewportChangedListener);
// We might have already unmounted this view when calling mount with a different view. In this
// case we can just return here.
if (mMountedView != view) {
return;
}
mMountedView = null;
if (mStickyHeaderController != null) {
mStickyHeaderController.reset();
}
mLayoutInfo.setRenderInfoCollection(null);
}