下面列出了android.support.v7.widget.RecyclerView#findViewHolderForAdapterPosition ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* notify item state changed
*/
private void notifyItemExpandedOrCollapsed(int parentIndex, boolean isExpand) {
if (mRecyclerViewList != null && !mRecyclerViewList.isEmpty()) {
RecyclerView recyclerView = mRecyclerViewList.get(0);
BaseAdapterItem viewHolderForAdapterPosition = (BaseAdapterItem) recyclerView.findViewHolderForAdapterPosition(parentIndex);
try {
AbstractAdapterItem<Object> item = viewHolderForAdapterPosition.getItem();
if (item != null && item instanceof AbstractExpandableAdapterItem) {
AbstractExpandableAdapterItem abstractExpandableAdapterItem = (AbstractExpandableAdapterItem) item;
abstractExpandableAdapterItem.onExpansionToggled(isExpand);
}
} catch (Exception e) {
}
}
}
/**
* 同步 parent 的展开折叠状态
* <p>
* 如果当前要通知的 parent 未 laid out , 后期当该 parent attach 到 {@link RecyclerView} 时,
* 会完成同步并回调相关接口
* </p>
*
* @param parentPosition parent 列表项位置
*/
private void syncParentExpandableState(int parentPosition) {
final int parentAdapterPos = getParentAdapterPosition(parentPosition);
if (parentAdapterPos == RecyclerView.NO_POSITION) return;
ItemWrapper itemWrapper = getItem(parentAdapterPos);
final boolean expandable = itemWrapper.isExpandable();
Logger.e(TAG, "syncParentExpandableState=>" + parentPosition + "," + expandable);
for (RecyclerView rv : mAttachedRecyclerViews) {
ParentViewHolder pvh = (ParentViewHolder) rv
.findViewHolderForAdapterPosition(parentAdapterPos);
if (pvh != null && pvh.isExpandable() != expandable) {
pvh.setExpandable(expandable);
notifyParentExpandableStateChanged(pvh, expandable);
} else if (pvh == null) {
pendingExpandableAdd(rv, parentPosition);
}
}
}
private int getScrollDistanceOfColumnClosestToLeft(final RecyclerView recyclerView) {
final LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
final RecyclerView.ViewHolder firstVisibleColumnViewHolder = recyclerView.findViewHolderForAdapterPosition(manager.findFirstVisibleItemPosition());
if (firstVisibleColumnViewHolder == null) {
return 0;
}
Log.d("YouQi", "firstVisibleColumnViewHolder: " + firstVisibleColumnViewHolder.getAdapterPosition());
final int columnWidth = firstVisibleColumnViewHolder.itemView.getMeasuredWidth();
final int left = firstVisibleColumnViewHolder.itemView.getLeft();
final int absoluteLeft = Math.abs(left);
final int columnHeight = firstVisibleColumnViewHolder.itemView.getMeasuredHeight();
final int top = firstVisibleColumnViewHolder.itemView.getTop();
final int absoluteTop = Math.abs(top);
Log.d("YouQi", "columnWidth: " + columnWidth);
Log.d("YouQi", "left: " + left);
Log.d("YouQi", "absoluteLeft: " + absoluteLeft);
Log.d("YouQi", "columnHeight: " + columnHeight);
Log.d("YouQi", "top: " + top);
Log.d("YouQi", "absoluteTop: " + absoluteTop);
//return absoluteLeft <= (columnWidth / 2) ? left : columnWidth - absoluteLeft;
return absoluteTop <= (columnHeight / 2) ? top : columnHeight - absoluteTop;
}
/**
* Dismiss the swipe menu for the view at position
* @param position the position of the item to dismiss
*/
public void dismissSwipeMenu(RecyclerView recyclerView, int position) {
// retrieve the viewholder at position
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(position);
// check if the viewholder is an instance of ConversationListAdapter.ViewHolder
if(viewHolder instanceof ViewHolder) {
// cast the holder to ConversationListAdapter.ViewHolder
ViewHolder holder = (ViewHolder) viewHolder;
// dismiss the menu
holder.swipeItem.close();
}
}
/**
* 同步 attach 到当前 adapter 的所有 RecyclerView 指定的适配器位置的 parentItem 的展开状态
* <p>
* <b>注意:</b>可能由于 ParentItem 未 laid out 到 RecyclerView 并且 RecyclerView 没有正确回调
* {@link #onBindParentViewHolder(ParentViewHolder, int)} 方法导致同步
* 展开状态失败,这里存储待处理的 parentItem 的位置,以至于能够在 {@link #onViewAttachedToWindow(BaseViewHolder)}
* 时处理状态同步逻辑
* </p>
*
* @param parentPosition 指定的同步展开状态的 parent 的在父列表项里的位置
*/
@SuppressWarnings("unchecked")
private void syncViewExpansionState(Integer parentPosition, boolean byUser)
{
Logger.e(TAG, "syncViewExpansionState=>" + parentPosition);
int parentAdapterPos = getParentAdapterPosition(parentPosition);
if (parentAdapterPos == RecyclerView.NO_POSITION) return;
ItemWrapper itemWrapper = getItem(parentAdapterPos);
boolean expanded = itemWrapper.isExpanded();
for (RecyclerView rv : mAttachedRecyclerViews) {
PVH pvh = (PVH) rv.findViewHolderForAdapterPosition(parentAdapterPos);
if (pvh != null && !pvh.isExpanded() && expanded) {
//这里需要额外判断当该 parent 可以 expandable 时才应用同步设置和通知展开逻辑
//防止不可展开的 parent 的不必要的同步设置和通知处理
pvh.setExpanded(true);
notifyParentExpanded(pvh, false, byUser);
} else if (pvh == null && expanded) {
Logger.e(TAG, "expandViews pvh is null---->parentPos=" + parentPosition +
",parentAdapterPos=" + parentAdapterPos);
//未 laid out 的 Parent ,虽然无法获取并设置展开折叠标识,
// 这里添加待处理展开逻辑的所有 parentItem 的 position
// 如果先前已经记录待折叠位置记录,移除该记录并以最新的待展开记录为准!
pendingCollapseRemove(rv, parentPosition);
pendingExpandAdd(rv, parentPosition);
}
}
}
/**
* Calls through to the ParentViewHolder to expand views for each
* RecyclerView the specified parent is a child of.
* <p>
* These calls to the ParentViewHolder are made so that animations can be
* triggered at the ViewHolder level.
*
* @param flatParentPosition The index of the parent to expand
*/
@SuppressWarnings("unchecked")
@UiThread
private void expandViews(@NonNull ExpandableWrapper<P, C> parentWrapper, int flatParentPosition) {
PVH viewHolder;
for (RecyclerView recyclerView : mAttachedRecyclerViewPool) {
viewHolder = (PVH) recyclerView.findViewHolderForAdapterPosition(flatParentPosition);
if (viewHolder != null && !viewHolder.isExpanded()) {
viewHolder.setExpanded(true);
viewHolder.onExpansionToggled(false);
}
}
updateExpandedParent(parentWrapper, flatParentPosition, false);
}
private void computeOffsetWith(RecyclerView recyclerView) {
if (recyclerView.getAdapter() == null) {
setTranslationY(getMeasuredHeight());
return;
}
int lastPosition = recyclerView.getAdapter().getItemCount() - 1;
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(lastPosition);
if (viewHolder != null && viewHolder.itemView != null && viewHolder.itemView.isShown()) {
int scrollRange = recyclerView.computeVerticalScrollRange();
int currentScroll = recyclerView.computeVerticalScrollOffset();
int rHeight = recyclerView.getHeight();
int rPadTop = recyclerView.getPaddingTop();
int offset = scrollRange - currentScroll - rHeight + getHeight() + rPadTop;
checkAutoLoad();
setTranslationY(offset);
if (offset < 0) {
dispatchOverScroll(offset, recyclerView.getScrollState());
}
} else if (recyclerView.getAdapter().getItemCount() == 0) {//no item
setTranslationY(-recyclerView.getHeight() / 2 + getMeasuredHeight() / 2);
checkAutoLoad();
} else {
setTranslationY(getMeasuredHeight());
}
}
@SuppressWarnings("unchecked")
@Override
public void onDragAnimationEnd(RecyclerView recyclerView, int position) {
VH selectedViewHolder = (VH) recyclerView.findViewHolderForAdapterPosition(position);
if(selectedViewHolder == null) return;
onDragAnimationEnd(selectedViewHolder,position);
}
@Nullable
public static View getItemView(@Nullable final RecyclerView recyclerView, final int position) {
if (recyclerView != null) {
final RecyclerView.ViewHolder vh = recyclerView
.findViewHolderForAdapterPosition(position);
if (vh != null) {
return vh.itemView;
}
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public void onMergeCancel(RecyclerView parent, int selectedPosition, int targetPosition) {
VH selectedViewHolder = (VH) parent.findViewHolderForAdapterPosition(selectedPosition);
VH targetViewHolder = (VH) parent.findViewHolderForAdapterPosition(targetPosition);
if(selectedViewHolder == null || targetViewHolder == null) return;
onMergeCancel(selectedViewHolder, targetViewHolder, selectedPosition, targetPosition);
}
/**
* Calls through to the {@link ParentViewHolder} to collapse views for each
* {@link RecyclerView} a specified parent is a child of. These calls to
* the {@code ParentViewHolder} are made so that animations can be
* triggered at the {@link android.support.v7.widget.RecyclerView.ViewHolder}
* level.
*
* @param parentIndex The index of the parent to collapse
*/
private void collapseViews(ParentWrapper parentWrapper, int parentIndex) {
for (RecyclerView recyclerView : mAttachedRecyclerViewPool) {
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(parentIndex);
if (viewHolder != null
&& ((ParentViewHolder) viewHolder).isExpanded()) {
((ParentViewHolder) viewHolder).setExpanded(false);
((ParentViewHolder) viewHolder).onExpansionToggled(true);
}
collapseHelperItem(parentWrapper, parentIndex, true);
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (recyclerView.getAdapter() == null) return;
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(0);
if (viewHolder != null && viewHolder.itemView != null) {
int currentScroll = recyclerView.computeVerticalScrollOffset();
setTranslationY(-currentScroll - getHeight());
dispatchOverScroll(-currentScroll, recyclerView.getScrollState());
}
}
@SuppressWarnings("unchecked")
@Override
public void onStartMergeAnimation(RecyclerView parent, int selectedPosition, int targetPosition,int duration) {
VH selectedViewHolder = (VH) parent.findViewHolderForAdapterPosition(selectedPosition);
VH targetViewHolder = (VH) parent.findViewHolderForAdapterPosition(targetPosition);
if(selectedViewHolder == null || targetViewHolder == null) return;
onStartMergeAnimation(selectedViewHolder, targetViewHolder, selectedPosition, targetPosition,duration);
}
@SuppressWarnings("unchecked")
private void syncViewCollapseState(Integer parentPosition, boolean byUser)
{
Logger.e(TAG, "syncViewCollapseState=>" + parentPosition);
int parentAdapterPos = getParentAdapterPosition(parentPosition);
if (parentAdapterPos == RecyclerView.NO_POSITION) return;
ItemWrapper itemWrapper = getItem(parentAdapterPos);
boolean collapsed = !itemWrapper.isExpanded();
for (RecyclerView rv : mAttachedRecyclerViews) {
PVH pvh = (PVH) rv.findViewHolderForAdapterPosition(parentAdapterPos);
if (pvh != null && pvh.isExpanded() && collapsed) {
pvh.setExpanded(false);
// 通知所有监听 Parent 展开折叠状态监听器当前 Parent 已折叠
notifyParentCollapsed(pvh, false, byUser);
} else if (pvh == null && collapsed) {
// 判断当前的 parent 是否 expandable ,防止记录不可 expandable 的 parent 的待折叠位置信息
// 当该后期应用该位置的 parent 折叠操作时导致本该应用该位置的 parent 展开操作时被该折叠操作所覆盖问题
Logger.e(TAG, "collapseViews pvh is null---->parentPos=" + parentPosition +
",parentAdapterPos=" + parentAdapterPos);
// 未 laid out 的 Parent ,虽然无法获取并设置展开折叠标识,
// 这里添加待处理折叠逻辑的所有 parentItem 的 position
// 如果先前已经记录待折叠位置记录,移除该记录并以最新的待展开记录为准!
pendingExpandRemove(rv, parentPosition);
pendingCollapseAdd(rv, parentPosition);
}
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
final int position = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
if (position == RecyclerView.NO_POSITION) {
return;
}
View child = parent.findViewHolderForAdapterPosition(position).itemView;
String initial = getTag(position);
if (initial == null) {
return;
}
boolean flag = false;
if (getTag(position + 1) != null && !initial.equals(getTag(position + 1))) {
if (child.getHeight() + child.getTop() < mTitleHeight) {
c.save();
flag = true;
c.translate(0, child.getHeight() + child.getTop() - mTitleHeight);
}
}
c.drawRect(parent.getPaddingLeft(), parent.getPaddingTop(),
parent.getRight() - parent.getPaddingRight(), parent.getPaddingTop() + mTitleHeight, mBackgroundPaint);
c.drawText(initial, child.getPaddingLeft() + mTextStartMargin,
parent.getPaddingTop() + mTitleHeight - (mTitleHeight - mTextHeight) / 2 - mTextBaselineOffset, mTextPaint);
if (flag) {
c.restore();
}
}
@SuppressWarnings("unchecked")
@Override
public void onItemClick(RecyclerView recyclerView, int position, View pressedView) {
VH viewHolder = (VH) recyclerView.findViewHolderForAdapterPosition(position);
if(viewHolder != null)
PrimitiveSimpleAdapter.this.onItemClick(viewHolder,mParentPosition,position);
}
public Matcher<View> atPositionOnView(final int position, final int targetViewId) {
return new TypeSafeMatcher<View>() {
Resources resources = null;
View childView;
public void describeTo(Description description) {
String idDescription = Integer.toString(recyclerViewId);
if (this.resources != null) {
try {
idDescription = this.resources.getResourceName(recyclerViewId);
} catch (Resources.NotFoundException var4) {
idDescription = String.format("%s (resource name not found)",
new Object[]{Integer.valueOf
(recyclerViewId)});
}
}
description.appendText("with id: " + idDescription);
}
public boolean matchesSafely(View view) {
this.resources = view.getResources();
if (childView == null) {
RecyclerView recyclerView =
(RecyclerView) view.getRootView().findViewById(recyclerViewId);
if (recyclerView != null && recyclerView.getId() == recyclerViewId) {
childView = recyclerView.findViewHolderForAdapterPosition(position).itemView;
} else {
return false;
}
}
if (targetViewId == -1) {
return view == childView;
} else {
View targetView = childView.findViewById(targetViewId);
return view == targetView;
}
}
};
}
/**
* 绘制悬浮组
*
* @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();
}
}
public Matcher<View> atPositionOnView(final int position, final int targetViewId) {
return new TypeSafeMatcher<View>() {
Resources resources = null;
View childView;
public void describeTo(Description description) {
String idDescription = Integer.toString(recyclerViewId);
if (this.resources != null) {
try {
idDescription = this.resources.getResourceName(recyclerViewId);
} catch (Resources.NotFoundException var4) {
idDescription = String.format("%s (resource name not found)",
new Object[] { Integer.valueOf
(recyclerViewId) });
}
}
description.appendText("with id: " + idDescription);
}
public boolean matchesSafely(View view) {
this.resources = view.getResources();
if (childView == null) {
RecyclerView recyclerView =
(RecyclerView) view.getRootView().findViewById(recyclerViewId);
if (recyclerView != null && recyclerView.getId() == recyclerViewId) {
childView = recyclerView.findViewHolderForAdapterPosition(position).itemView;
}
else {
return false;
}
}
if (targetViewId == -1) {
return view == childView;
} else {
View targetView = childView.findViewById(targetViewId);
return view == targetView;
}
}
};
}
public Matcher<View> atPositionOnView(final int position, final int targetViewId) {
return new TypeSafeMatcher<View>() {
Resources resources;
View childView;
public void describeTo(Description description) {
String idDescription = Integer.toString(recyclerViewId);
if (this.resources != null) {
try {
idDescription = this.resources.getResourceName(recyclerViewId);
} catch (Resources.NotFoundException var4) {
idDescription = String.format("%s (resource name not found)",
recyclerViewId);
}
}
description.appendText("RecyclerView with id: "
+ idDescription
+ " at position: "
+ position);
}
public boolean matchesSafely(View view) {
this.resources = view.getResources();
if (childView == null) {
RecyclerView recyclerView =
(RecyclerView) view.getRootView().findViewById(recyclerViewId);
if (recyclerView != null && recyclerView.getId() == recyclerViewId) {
RecyclerView.ViewHolder viewHolder = recyclerView.
findViewHolderForAdapterPosition(position);
if (viewHolder != null) {
childView = viewHolder.itemView;
}
} else {
return false;
}
}
if (targetViewId == -1) {
return view.equals(childView);
} else {
View targetView = childView.findViewById(targetViewId);
return view.equals(targetView);
}
}
};
}