1

Now have such a demand, RecyclerView inside each item nested a vertical scroll viewpager, and viewpager is will automatically infinite loop rolling. I use nested RecyclerView RecyclerView to achieve, and the effect of rolling viewpager. I used RecyclerView smoothScrollToPosition to achieve. But in this process, I encountered a problem, is back and forth sliding several times outside the sliding of the RecyclerView, internal RecyclerViwe smoothScrollToPosition will chaos sliding. If done the same demand. Trouble share under

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's layout

    <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>

OuterAdapter:

    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);
            }
        }
    }

Item outer layout:

    <?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>

this image is what i want

this is the wrong image, when i sroll outer recycerview, smoothScrollToPosition() does not work well

2 Answers2

0

I see your code here. Just imagine, when scroll will stop?, you will be say "if while is false or even counter will ended". will it?

Lets log 1 line above

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

and what will we get.

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();
raditya gumay
  • 2,951
  • 3
  • 17
  • 24
  • thanks for your anwser, but i don't know how to fix it – zqandroiddev May 19 '16 at 04:06
  • @zqandroiddev please put your complete code somewhere, then i can help you to solve that problem. or create a new project and just copy past this piece of code, adapter and activity. – raditya gumay May 29 '16 at 06:23
0

At first, add listener in onBindViewHolder is a bad idea.

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();

Now, you create a new thread on each binding of item. So, you can have a few thread per single RecyclerView. And you cannot make +100500 threads. You should make one thread which will go through all items (visible) and scroll their position.

To get positions of visible items you should use:

int findFirstVisibleItemPosition();
int findLastVisibleItemPosition();

To get their ViewHolder use:

ViewHolder findViewHolderForLayoutPosition(int position);

E.g.

    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++);
      }
     }
     });
}
Denis Sologub
  • 7,277
  • 11
  • 56
  • 123