Android 从RecyclerView获取可见和不可见项目
下面这个简单的代码只获取所有可见项,但我需要获取所有项(可见项和不可见项) 这是否可能完全获得所有项目?如何获得Android 从RecyclerView获取可见和不可见项目,android,android-recyclerview,Android,Android Recyclerview,下面这个简单的代码只获取所有可见项,但我需要获取所有项(可见项和不可见项) 这是否可能完全获得所有项目?如何获得 // This gets only visible items final RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(index); // Same as this final View child = recyclerView.getChildAt(index);
// This gets only visible items
final RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(index);
// Same as this
final View child = recyclerView.getChildAt(index);
final RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(child);
我也对这方面的任何工作感兴趣。如果可能的话。我相信这个问题是第一次被问到的 在第一个视图中,正如波厄尔指出的那样,你似乎要求的是不可能的,因为除非感兴趣的视图实际上是可见的,否则相应的视图持有者可能存在,也可能不存在,而且显然没有本机方法来强制其创建 我的要求是远程确定数据集中任何项目的可见性和突出显示 实现这一点的策略是通过滚动到所需项目,然后通过回调返回新创建的ViewHolder,从而强制创建ViewHolder 这个解决方案很重要,但我相信代码已经有了很好的文档。我建议您将静态方法和接口复制到一个实用程序类中,并按照dummy exampleOfUse()方法部署它们。如果您不能按原样使用它们,请告诉我 我已经包括了2个滚动相关的完整性只方法。忽略我的记录器:lg() 请记住,预滚动到所需的项目是您获得ViewHolder所付出的代价,因此可以发出notifyItemChanged()。[适合我,但可能不是所有人。]
// ---------------------------------------------------------------------------------------------
// These 3 static methods provide:
// (A) Smooth or direct scrolling for any RecyclerView. [ ScrollTo() ]
// (B) A technique for obtaining the ViewHolder of any item (visible or otherwise).
// [ Achieved via callback when scroll to desired position has completed. ]
// [ Why: (e.g.) To highlight an externally selected (or any) RecyclerView item ]
// ---------------------------------------------------------------------------------------------
/** Sample method of use */
public void dummyExampleOfUse(RecyclerView rv, int pos) {
getAnyViewHolder(rv, pos, true, new GetAnyViewHolder() {
@Override
public void scrollForViewHolder(RecyclerView.ViewHolder vh, int pos) {
if (vh==null) lg("Failed!!!"); // <-- Your logger
//else ((YourViewHolder)vh).yourViewHolderMethod(pos);
// yourViewHolderMethod would typically issue notifyItemChanged(pos);
}
});
}
/** Interface to receive requested ViewHolder */
public interface GetAnyViewHolder {
void scrollForViewHolder(RecyclerView.ViewHolder vh, int pos);
}
/** RecyclerView scroll with callback returning desired ViewHolder */
public static boolean getAnyViewHolder(RecyclerView rv, int pos, boolean smooth, GetAnyViewHolder cb) {
if (rv==null) return false;
if (rv.getAdapter() == null) return false;
if (rv.getAdapter().getItemCount() < 1) return false;
if (pos <0 || pos > rv.getAdapter().getItemCount()-1) return false;
rv.addOnScrollListener(new MPA_SL(rv, cb, pos));
scrollTo(rv, pos, smooth, null); // Note user-specified scroll action!
return true;
}
/** Custom Scroll listener needed for 'getAnyViewHolder()' */
private static class MPA_SL extends RecyclerView.OnScrollListener {
RecyclerView rv; GetAnyViewHolder gavh; int pos;
MPA_SL( RecyclerView rv,GetAnyViewHolder gavh, int pos ) { // Constructor
this.rv = rv; this.gavh = gavh; this.pos = pos;}
@Override public void onScrollStateChanged(@NonNull RecyclerView rv, int newState) {
super.onScrollStateChanged(rv, newState);
lg(format("Scroll state: %d", newState));
if(newState == RecyclerView.SCROLL_STATE_IDLE) {
RecyclerView.ViewHolder vh = rv.findViewHolderForAdapterPosition(pos);
gavh.scrollForViewHolder(vh, pos); // Notify user
rv.removeOnScrollListener(this); // Self-destruct
}
}
}
/** Scroll according to speed */
public static void scrollTo(RecyclerView rv, int os, boolean smooth, TextView tv) {
try {
if (smooth) { smoothScroll(rv, os); }
else { rv.scrollToPosition(os); }
} catch ( IllegalArgumentException ile) {
if (tv==null) {
lg(format("Scroll error: %s", ile.getMessage()));
return;
}
String msg = tv.getText().toString() + " ";
msg += ile.getMessage();
tv.setText(msg);
}
}
/** Smoothly scroll to specified position at 1/4 speed */
private static void smoothScroll(RecyclerView rv, int position) throws IllegalArgumentException {
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(gc()) {
@Override protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_START;
}
@Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
float millesecondsPerPixel = super.calculateSpeedPerPixel(displayMetrics);
return millesecondsPerPixel * 4;
}
};
smoothScroller.setTargetPosition(position);
rv.getLayoutManager().startSmoothScroll(smoothScroller);
}
//---------------------------------------------------------------------------------------------
//这3种静态方法提供:
//(A)平滑或直接滚动任何RecyclerView。[滚动到()]
//(B)获取任何项目(可见或其他)的视图持有人的技术。
//[当滚动到所需位置完成时,通过回调实现。]
//[原因:(例如)突出显示外部选择的(或任何)RecyclerView项目]
// ---------------------------------------------------------------------------------------------
/**使用方法样本*/
公共空间DummeyExampleofuse(回收视图rv,内部位置){
getAnyViewHolder(rv、pos、true、新getAnyViewHolder(){
@凌驾
公共无效scrollForViewHolder(RecyclerView.ViewHolder vh,int pos){
如果(vh==null)lg(“失败!!!”;//我相信这个问题是第一个被问到的
在第一个视图中,正如波厄尔指出的那样,你似乎要求的是不可能的,因为除非感兴趣的视图实际上是可见的,否则相应的视图持有者可能存在,也可能不存在,而且显然没有本机方法来强制其创建
我的要求是远程确定数据集中任何项目的可见性和突出显示
实现这一点的策略是通过滚动到所需项目,然后通过回调返回新创建的ViewHolder,从而强制创建ViewHolder
这个解决方案非常简单,但我相信代码已经有很好的文档记录。我建议您将静态方法和接口复制到实用程序类中,并按照伪exampleOfUse()方法进行部署。如果您不能按原样使用它们,请告诉我
为了完整起见,我加入了2个与滚动相关的方法。忽略我的记录器:lg()
请记住,预滚动到所需的项目是您获得ViewHolder所付出的代价-因此,发布notifyItemChanged()[适合我,但可能不是所有人。]
// ---------------------------------------------------------------------------------------------
// These 3 static methods provide:
// (A) Smooth or direct scrolling for any RecyclerView. [ ScrollTo() ]
// (B) A technique for obtaining the ViewHolder of any item (visible or otherwise).
// [ Achieved via callback when scroll to desired position has completed. ]
// [ Why: (e.g.) To highlight an externally selected (or any) RecyclerView item ]
// ---------------------------------------------------------------------------------------------
/** Sample method of use */
public void dummyExampleOfUse(RecyclerView rv, int pos) {
getAnyViewHolder(rv, pos, true, new GetAnyViewHolder() {
@Override
public void scrollForViewHolder(RecyclerView.ViewHolder vh, int pos) {
if (vh==null) lg("Failed!!!"); // <-- Your logger
//else ((YourViewHolder)vh).yourViewHolderMethod(pos);
// yourViewHolderMethod would typically issue notifyItemChanged(pos);
}
});
}
/** Interface to receive requested ViewHolder */
public interface GetAnyViewHolder {
void scrollForViewHolder(RecyclerView.ViewHolder vh, int pos);
}
/** RecyclerView scroll with callback returning desired ViewHolder */
public static boolean getAnyViewHolder(RecyclerView rv, int pos, boolean smooth, GetAnyViewHolder cb) {
if (rv==null) return false;
if (rv.getAdapter() == null) return false;
if (rv.getAdapter().getItemCount() < 1) return false;
if (pos <0 || pos > rv.getAdapter().getItemCount()-1) return false;
rv.addOnScrollListener(new MPA_SL(rv, cb, pos));
scrollTo(rv, pos, smooth, null); // Note user-specified scroll action!
return true;
}
/** Custom Scroll listener needed for 'getAnyViewHolder()' */
private static class MPA_SL extends RecyclerView.OnScrollListener {
RecyclerView rv; GetAnyViewHolder gavh; int pos;
MPA_SL( RecyclerView rv,GetAnyViewHolder gavh, int pos ) { // Constructor
this.rv = rv; this.gavh = gavh; this.pos = pos;}
@Override public void onScrollStateChanged(@NonNull RecyclerView rv, int newState) {
super.onScrollStateChanged(rv, newState);
lg(format("Scroll state: %d", newState));
if(newState == RecyclerView.SCROLL_STATE_IDLE) {
RecyclerView.ViewHolder vh = rv.findViewHolderForAdapterPosition(pos);
gavh.scrollForViewHolder(vh, pos); // Notify user
rv.removeOnScrollListener(this); // Self-destruct
}
}
}
/** Scroll according to speed */
public static void scrollTo(RecyclerView rv, int os, boolean smooth, TextView tv) {
try {
if (smooth) { smoothScroll(rv, os); }
else { rv.scrollToPosition(os); }
} catch ( IllegalArgumentException ile) {
if (tv==null) {
lg(format("Scroll error: %s", ile.getMessage()));
return;
}
String msg = tv.getText().toString() + " ";
msg += ile.getMessage();
tv.setText(msg);
}
}
/** Smoothly scroll to specified position at 1/4 speed */
private static void smoothScroll(RecyclerView rv, int position) throws IllegalArgumentException {
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(gc()) {
@Override protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_START;
}
@Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
float millesecondsPerPixel = super.calculateSpeedPerPixel(displayMetrics);
return millesecondsPerPixel * 4;
}
};
smoothScroller.setTargetPosition(position);
rv.getLayoutManager().startSmoothScroll(smoothScroller);
}
//---------------------------------------------------------------------------------------------
//这3种静态方法提供:
//(A)平滑或直接滚动任何RecyclerView。[ScrollTo()]
//(B)获取任何项目(可见或其他)的视图持有人的技术。
//[当滚动到所需位置完成时,通过回调实现。]
//[原因:(例如)突出显示外部选择的(或任何)RecyclerView项目]
// ---------------------------------------------------------------------------------------------
/**使用方法样本*/
公共空间DummeyExampleofuse(回收视图rv,内部位置){
getAnyViewHolder(rv、pos、true、新getAnyViewHolder(){
@凌驾
公共无效scrollForViewHolder(RecyclerView.ViewHolder vh,int pos){
如果(vh==null)lg(“失败!!!”);//您是否知道RecyclerView
在滚动时重用ViewHolder
s?即使您的列表中有5000多个项目,也只有足够的ViewHolder
s来容纳您的查看端口。您是否知道RecyclerView
在滚动时重用ViewHolder
s?即使您的列表中有5000多个项目,也会有只有足够的ViewHolder
s适合您的视图端口。