viewHolder null和scrollToPosition不正确

时间:2016-06-07 14:04:20

标签: android scroll android-recyclerview bind android-viewholder

我试图实现第一个回收商视图项目的选择+滚动到Sunshine ForecastFragment非常类似的位置

https://github.com/udacity/Advanced_Android_Development/blob/master/app/src/main/java/com/example/android/sunshine/app/ForecastFragment.java

但我一直面临两个问题:

滚动并不总是正确的 viewHolder有时为null(我需要访问它才能显示第一行)

我首先要知道这是因为当滚动不正确时,视图不在屏幕上且持有者没有绑定。所以我尝试了几件事。

首先我尝试了

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mAdapter.swapCursor(data);
    Log.e("FF", Thread.currentThread().getStackTrace()[2] + "swapCursor ");
    mRecyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {

            if (mRecyclerView.getChildCount() > 0) {
                // Since we know we're going to get items, we keep the listener around until
                // we see Children.
                mRecyclerView.getViewTreeObserver().removeOnPreDrawListener(this);
                int position = mAdapter.getSelectedItemPosition(getContext());
                if (position == RecyclerView.NO_POSITION) {
                    position = mPosition == null ? getFirstContactPosition(mAdapter) : mPosition;
                }
                mRecyclerView.smoothScrollToPosition(position);

                //this method findViewHolderForAdapterPosition will always return null if we
                // call it after a swapCursor
                //(because it always return null after a notifyDataSetChanged) that's why we
                // call findViewHolderForAdapterPosition in the onPreDraw method
                RecyclerView.ViewHolder vh = mRecyclerView.findViewHolderForAdapterPosition(position);

                Log.e("FF", Thread.currentThread().getStackTrace()[2] + "vh " + vh);
                if (null != vh) {
                    if (getResources().getInteger(R.integer.orientation) == MainActivity.W700dp_LAND)
                        mAdapter.selectView(vh);
                }
                mPosition = position;
                return true;
            }
            return false;
        }
    });
}

然后我尝试更换

mRecyclerView.smoothScrollToPosition(position);

我找到了所有可行的解决方案

mRecyclerView.getLayoutManager().scrollToPosition(position);
mLayoutManager.scrollToPosition(position);
mLayoutManager.scrollToPositionWithOffset(position, 20);
mRecyclerView.scrollToPosition(position);

然后我尝试在postDelayed线程中执行滚动,如下所示

final int finalPosition = position;
mRecyclerView.postDelayed(new Runnable() {
    @Override
    public void run() {
        mRecyclerView.smoothScrollToPosition(finalPosition);
    }
}, 1000);

所有这些都没有成功。

现在我不知道在哪个方向寻找。我仍然不完全确定viewHolder为null的事实是由于滚动不正确。 以下是我选择onScreen项目时的正确行为

on first orientation change
    - scrolling is correct
    - view holder is not null
on second and following orientation change
    - same as before, it work well

以下是我选择offScreen项目时的行为

on first orientation change
    - scrolling is correct
    - view holder IS null
on second and following orientation change
    - scrolling is incorrect (seems to scroll to the last onScreen item)
    - view holder is NOT null
on third orientation change
    - like first
on fourth orientation change
    - like second
etc

onScreen注意我指的是首次向用户显示而无需滚动的项目。

有什么想法吗?

提前致谢。

0 个答案:

没有答案