sy ruan
sy ruan

Reputation: 21

ScrollToPosition() do not work well on RecyclerView with Images

I have a RecyclerView page like this:

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

The xml of RecyclerView item is an ImageView:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/iv_chat_item_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:maxHeight="@dimen/height_xl"
        android:maxWidth="@dimen/width_l"
        android:scaleType="centerInside"
        android:src="?attr/chat_image_loading" />

Adapter:

public ChatAdapter(Context context, List<String> urls)
{
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

         //download image from internet
         downloadImage(url);
    }
}

MainActivity:

    //image urls
    List<String> urls;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        //initialize recyclerview
        chatListView = (RecyclerView) findViewById(R.id.rv_chat);
        chatListView.setHasFixedSize(true);
        chatListView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        chatListView.setItemAnimator(new DefaultItemAnimator());

        chatAdapter = new ChatAdapter(this,null);
        chatListView.setAdapter(chatAdapter);

        //add datas
        chatAdapter.addDatas(urls);

        //scroll to bottom
        chatListView.smoothScrollToPosition(chatListView.getBottom());
    }

I just want to do this:after downloading images,let the recyclerview scrolls to the bottom.But because of the asynchronous image loading ,the recyclerview could not correctly scroll to the bottom——it just scroll to the middle. So how I do to make it working well?

Upvotes: 2

Views: 1116

Answers (2)

KodyTsang
KodyTsang

Reputation: 26

RecyclerViewScroller :

public class RecyclerViewScroller {
RecyclerView recycler;
LinearLayoutManager manager;
private boolean isMove = false;
private int index = 0;

public RecyclerViewScroller(RecyclerView recycler, LinearLayoutManager manager){
    this.recycler = recycler;
    this.manager = manager;
    recycler.addOnScrollListener(myScrollListener);
}

public void scrollTo(int position){
    recycler.scrollToPosition(position);
    int firstItem = manager.findFirstVisibleItemPosition();
    int lastItem = manager.findLastVisibleItemPosition();
    if (position <= firstItem) {
        recycler.scrollToPosition(position);
    } else if (position <= lastItem) {
        int top = recycler.getChildAt(position - firstItem).getTop();
        recycler.scrollBy(0, top);
    } else {
        recycler.scrollToPosition(position);
        index = position;
        isMove = true;
    }
}

private RecyclerView.OnScrollListener myScrollListener = new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        if (isMove) {
            isMove = false;
            int n = index - manager.findFirstVisibleItemPosition();
            if (0 <= n && n < recycler.getChildCount()) {
                int top = recycler.getChildAt(n).getTop();
                recycler.scrollBy(0, top);
            }
        }
    }
};

}

Activity:

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    chatListView.setLayoutManager(linearLayoutManager);
    RecyclerViewScroller scroller = new RecyclerViewScroller(chatListView, linearLayoutManager);
    scroller.scrollTo(chatListView.getBottom());

Upvotes: 0

user3313994
user3313994

Reputation:

Get image size before downloading it and set blank image in view.

Upvotes: 3

Related Questions