RecyclerView LayoutManager findViewByPosition返回null

时间:2015-04-11 14:39:24

标签: android android-recyclerview

我对获得RecyclerView第一项物品大小的正确和第一时间感兴趣?

我试过用:

recyclerView.setLayoutManager(new GridLayoutManager(context, 2));
recyclerView.setAdapter(new MyDymmyGridRecyclerAdapter(context));
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
     @Override
     public void onGlobalLayout() {
         recyclerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
         View firstRecyclerViewItem = recyclerView.getLayoutManager().findViewByPosition(0);
         // firstRecyclerViewItem is null here
     }
});

但此时它返回null。

3 个答案:

答案 0 :(得分:3)

如果您使用的是OnGlobalLayoutListener,则应该记住onGlobalLayout可以多次调用。其中一些调用甚至可以在Layout 准备就绪之前发生(并且准备就绪我指的是当你可以获得View的尺寸时致电view.getHeight()view.getWidth())。因此,实施您的方法的正确方法是:

recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
     @Override
     public void onGlobalLayout() {
         int width = recyclerView.getWidth();
         int height = recyclerView.getHeight();
         if (width > 0 && height > 0) {
             if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                 recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
             } else {
                 recyclerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
             }
         }

         View firstRecyclerViewItem = recyclerView.getLayoutManager().findViewByPosition(0);
     }
});

除此之外,您还需要确保findViewByPosition(0)致电:

  1. 您的RecyclerView's Adapter至少有一个数据元素。
  2. 位于View
  3. 0目前在RecyclerView
  4. 中可见

    告诉我这是否可以解决您的问题,如果没有,还有另一种方法可以满足您的需求。

答案 1 :(得分:0)

在我的扩展RecyclerView中,我像这样覆盖onChildAttachedToWindow

@Override
public void onChildAttachedToWindow(View child) {
    super.onChildAttachedToWindow(child);

    if (!mIsChildHeightSet) {
        // only need height of one child as they are all the same height
        child.measure(0, 0);
        // do stuff with child.getMeasuredHeight()
        mIsChildHeightSet = true;
    }
}

答案 2 :(得分:0)

我有这种类型的问题。我想在recylerview的第一个可见位置默认执行单击。我在onResume上编写了代码,但它没有用。我通过在 onWindowFocusChanged 方法中编写代码解决了我的问题

    @Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    if(isCalledForTheFirstTime)
    {
        LinearLayoutManager manager= (LinearLayoutManager) rcViewHeader.getLayoutManager();
        int pos= manager.findFirstCompletelyVisibleItemPosition();


        View view=manager.findViewByPosition(pos);
        if(view!=null)
        {
            view.performClick();
        }

        // change the vaule so that it would not be call in case a pop up appear or disappear 
        isCalledForTheFirstTime=false;
    }

}