从RecyclerView获取可见和不可见的项目

时间:2019-09-26 13:48:17

标签: android android-recyclerview

下面的简单代码仅获取所有可见项目,但我需要获取所有项目(可见和不可见)。

是否有可能完全获得所有物品以及如何获得?

[ngStyle]="{'transform:rotate(.5turn)': dashService.variable}"

我也对此感兴趣。如果可能的话。

1 个答案:

答案 0 :(得分:0)

我相信首先要问3 years ago这个问题。

在第一个视图上,正如 Pawel 所指出的那样,您似乎要求的是不可能,因为除非感兴趣的视图实际上是可见的,否则相应的ViewHolder可能会或可能不存在-显然没有任何本地方法可以强制其创建。

我的要求是要远程确定

确定数据集中任何项目的可见性和突出显示!

实现此目标的策略是通过滚动到所需项目来强制创建 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);
}

祝你好运!