1

现在有这样一个需求,RecyclerView里面的每个item都嵌套了一个垂直滚动的viewpager,而viewpager是会自动无限循环滚动的。我使用嵌套的RecyclerView RecyclerView 来实现,以及滚动viewpager 的效果。我使用 RecyclerView smoothScrollToPosition 来实现。但是在这个过程中,我遇到了一个问题,就是在RecyclerView外面来回滑动几次,里面的RecyclerViwe smoothScrollToPosition会乱滑动。如果做了同样的要求。麻烦分享下

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRvOuter;
    private LinearLayoutManager linearLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRvOuter = (RecyclerView) findViewById(R.id.rv_outer);
        linearLayoutManager = new LinearLayoutManager(this);
        mRvOuter.setLayoutManager(linearLayoutManager);
        mRvOuter.setAdapter(new OuterAdapter(this));
    }
}

MainActivity 的布局

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#eeeeee">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_outer"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
    </RelativeLayout>

外适配器:

    public class OuterAdapter extends RecyclerView.Adapter<OuterAdapter.OuterViewHolder> {
        LayoutInflater layoutInflater;
        List<String> mDatas;
        Context mContext;

        public OuterAdapter(Context context) {
            mContext = context;
            layoutInflater = LayoutInflater.from(context);
        }

        @Override
        public OuterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            OuterViewHolder viewHolder = new OuterViewHolder(layoutInflater.inflate(R.layout.item_outer, parent, false));
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(final OuterViewHolder holder, int position) {
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
            holder.mRvInner.setLayoutManager(linearLayoutManager);
            holder.mRvInner.setAdapter(new InnerAdapter(mContext, initDada(position)));

            holder.mRvInner.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
                @Override
                public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                    return e.getAction() == MotionEvent.ACTION_MOVE;
                }

                @Override
                public void onTouchEvent(RecyclerView rv, MotionEvent e) {

                }

                @Override
                public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

                }
            });
            final Handler handler = new Handler();
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        SystemClock.sleep(2000);
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                holder.mRvInner.smoothScrollToPosition(holder.i++);
                            }
                        });
                    }
                }
            });
            thread.start();
        }

        @Override
        public int getItemCount() {
            return 30;
        }

        public class OuterViewHolder extends RecyclerView.ViewHolder {
            RecyclerView mRvInner;

            int i;

            public OuterViewHolder(View itemView) {
                super(itemView);
                mRvInner = (RecyclerView) itemView.findViewById(R.id.rv_inner);
            }
        }


        private List<String> initDada(int i) {
            mDatas = new ArrayList<String>();
            for (int j = 0; j <= i; j++) {
                mDatas.add("" + j);
            }
            return mDatas;
        }
    }


    InnerAdapter:

    public class InnerAdapter extends RecyclerView.Adapter<InnerAdapter.InnerViewHolder> {


        private List<String> mInnerDatas;
        private LayoutInflater mInflater;

        public InnerAdapter(Context context, List<String> innerDatas) {
            mInflater = LayoutInflater.from(context);
            mInnerDatas = innerDatas;
        }

        @Override
        public InnerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            InnerViewHolder viewHolder = new InnerViewHolder(mInflater.inflate(R.layout.item_inner, parent, false));
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(InnerViewHolder holder, int position) {
            holder.mTvInner.setText(mInnerDatas.get(position % mInnerDatas.size()));
        }

        @Override
        public int getItemCount() {
            return Integer.MAX_VALUE;
        }

        public class InnerViewHolder extends RecyclerView.ViewHolder {
            TextView mTvInner;

            public InnerViewHolder(View itemView) {
                super(itemView);
                mTvInner = (TextView) itemView.findViewById(R.id.tv_inner);
            }
        }
    }

项目外部布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:background="#ffffff"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:gravity="center"
            android:text="i am belong outerRecyclerView"
            android:textSize="20sp" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_inner"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:layout_marginTop="15dp"
            android:background="#ffaadd"></android.support.v7.widget.RecyclerView>
    </LinearLayout>

    item inner:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_inner"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:textColor="#000"
            android:textSize="30sp" />
    </LinearLayout>

这张图片是我想要的

这是错误的图像,当我滚动外部 recycerview 时,smoothScrollToPosition() 无法正常工作

4

2 回答 2

0

起初,添加监听onBindViewHolder器是一个坏主意。

final Handler handler = new Handler();
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        while (true) {
            SystemClock.sleep(2000);
            handler.post(new Runnable() {
                @Override
                public void run() {
                    holder.mRvInner.smoothScrollToPosition(holder.i++);
                }
            });
       }
    }
});
thread.start();

现在,您在项目的每个绑定上创建一个新线程。因此,每个单线程可以有几个线程RecyclerView。而且你不能制作 +100500 个线程。您应该创建一个线程来遍历所有项目(可见)并滚动它们的位置。

要获取可见项目的位置,您应该使用:

int findFirstVisibleItemPosition();
int findLastVisibleItemPosition();

ViewHolder使用它们:

ViewHolder findViewHolderForLayoutPosition(int position);

例如

    while (isRunned) {
     SystemClock.sleep(2000);
     handler.post(new Runnable() {
     @Override
     public void run() {
      int last = findLastVisibleItemPosition();
      for(int i = findFirstVisibleItemPosition(); i <= last; ++i) {
       ViewHolder holder = findViewHolderForLayoutPosition(i);
       holder.mRvInner.smoothScrollToPosition(holder.i++);
      }
     }
     });
}
于 2016-05-19T04:32:35.247 回答
0

我在这里看到你的代码。试想一下,当滚动停止时,你会说“如果 while 是假的,甚至计数器会结束”。会吗?

让我们在上面记录 1 行

holder.mRvInner.smoothScrollToPosition(holder.i++);

我们会得到什么。

final Handler handler = new Handler();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    SystemClock.sleep(2000);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            holder.mRvInner.smoothScrollToPosition(holder.i++);
                        }
                    });
                }
            }
        });
        thread.start();
于 2016-05-19T02:51:47.033 回答