2

I have used RecyclerView and StaggeredGridLayoutManager.

When I scroll from top to the bottom, it looked well. But when I scroll from bottom to the top , the top child view appear a blank.

Now, I found when I scroll from top to bottom, it looks :

  left1     right1
  left2     right2
  left3     right3
  left4     right4
  left5     right5
  left6     right6
  left7     right7

When I scroll from bottom to the top, something happened, it looks like this:

  right1    left1
  right2    left2
  right3    left3
  right4    left4
  left5     right5
  left6     right6
  left7     right7

and the height of left and right is different, so when on the top , it appeared a blank.

Here is my code :

recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setItemAnimator(new DefaultItemAnimator());
staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new ViewItemDecoration());

Now I do not know how to solve it.

here is my Adapter code:

 @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        int itemViewType = getItemViewType(position);
        StaggeredGridLayoutManager.LayoutParams layoutParams1 = ((StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams());
        if (itemViewType < 0) {
            return;
        }
        Logger.i("Topic_viewType", viewType.get(itemViewType) + "");
        switch (viewType.get(itemViewType)) {
            case ITEM:
                layoutParams1.setFullSpan(true);
                onBindItemViewHolder(holder, position);
                break;
            case ITEMS:
                layoutParams1.setFullSpan(true);
                onBindItemsViewHolder(holder, position);
                break;
            case IMAGES:
                layoutParams1.setFullSpan(true);
                onBindImageViewHolder(holder, position);
                break;
            case BLANK:
                layoutParams1.setFullSpan(true);
                break;
            case COVER:
                layoutParams1.setFullSpan(true);
                onBindCoverImageViewHolder(holder, position);
                break;
            case LINE:
                layoutParams1.setFullSpan(true);
                onBindLineViewHolder(holder, position);
                break;
            case TEXT:
                layoutParams1.setFullSpan(true);
                onBindTextViewHolder(holder, position);
                break;
            case SPACING:
                layoutParams1.setFullSpan(true);
                onBindSpacingViewHolder(holder, position);
                break;
            case READ_COUNT:
                layoutParams1.setFullSpan(true);
                onBindReadCountViewHolder(holder, position);
                break;
            case OTHER_TOPIC:
                layoutParams1.setFullSpan(true);
                break;
            case HOT:
                layoutParams1.setFullSpan(true);
                onBindHotViewHolder(holder, position);
                break;
            case MORE:
                layoutParams1.setFullSpan(true);
                onBindMoreViewHolder(holder, position);
                break;
            case ITEMS_MORE:
                layoutParams1.setFullSpan(true);
                onBindItemsMoreViewHolder(holder, position);
                break;
            case WALL_ITEM_TITLE:
                layoutParams1.setFullSpan(true);
                break;
            case WALL_ITEM:
                layoutParams1.setFullSpan(false);
                onBindWallItemViewHolder(holder, position);
                break;
            case WALL_LOAD_MORE:
                layoutParams1.setFullSpan(true);
                onBindLoadMoreViewHolder(holder, position);
                break;

        }
    }

here is my bindHolder code:

String url = info.getImageSrc();
int width = info.getWidth();
int height = info.getHeight();
SimpleDraweeView imageView = viewHolder.image;
imageView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
            UIHelper.jumpByUri(activity, info.getLink());
      }
});
if (height > 0) {
      // set the aspect ratio
      imageView.setAspectRatio(width * 1.0f / height);
}
imageView.setImageURI(Uri.parse(url));

here is my xml code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/ll_topic_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include layout="@layout/toolbar_custom" />

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

    </LinearLayout>

    <ImageView
        android:id="@+id/iv_feedback"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_feedback"
        android:layout_alignParentRight="true"
        android:layout_above="@+id/iv_back_top"
        android:layout_marginBottom="@dimen/space_30px"
        android:layout_marginRight="@dimen/space_30px"
        android:adjustViewBounds="true"
        android:contentDescription="@null"
        android:visibility="gone"/>

    <ImageView
        android:id="@+id/iv_back_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="@dimen/space_30px"
        android:layout_marginEnd="@dimen/space_30px"
        android:layout_marginRight="@dimen/space_30px"
        android:adjustViewBounds="true"
        android:contentDescription="@null"
        android:src="@drawable/up_top_icon"
        android:visibility="gone" />

</RelativeLayout>
Leo.lu
  • 31
  • 5
  • Please share your layout and adapter code. Also, not sure why you are doing `recyclerView.setItemAnimator(new DefaultItemAnimator());` followed by `recyclerView.setItemAnimator(null);`. Forgotten test code ? – yigit Sep 08 '15 at 04:55
  • I hava upload my code. I do not know what is wrong – Leo.lu Sep 09 '15 at 02:38
  • you have image views whose dimensions are not set. I believe (you haven't shared the code that sets it) your on bind method does not set it either. So the views will not have their final dimensions when onBind is called and they'll be resized when image is loaded. So when they are loaded and images are resized, the initial staggering layout may not fit the final one, causing another shuffling of the items. Instead, pass your image dimensions in server response so that you can layout the image based on the aspect ratio such that it will have its final size before the image is ready. – yigit Sep 09 '15 at 06:16
  • Thank you very much for your answer. I had set the aspect ratio before the image is loaded. it does not work , And I found that , when I scroll from bottom, in the middle position , the left view appears on the right , and the right view appears on the left. so it`s height being changed. I have upload the describe and my bind code. – Leo.lu Sep 09 '15 at 08:45
  • 1
    I have solved my question. If I called method adapter.notifyDataSetChanged(), this error will happend, Instead, if I called adapter.notifyItemRangeChanged(start, count). it`s fine. – Leo.lu Sep 09 '15 at 09:49
  • I got this problem too... i think the problem is because you modified the layoutparams – Zyoo May 09 '16 at 13:33

2 Answers2

0

try this?

staggeredGridLayoutManager..setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS)
RyanShao
  • 429
  • 2
  • 9
  • Please *describe* how this might solve the problem from the question. Posting only code is oftentimes entirely unhelpful. – Artjom B. Sep 07 '15 at 20:50
0

StaggeredGridLayoutManager uses two strategies to deal with gaps. The default strategy is GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS, which means that StaggeredGridLayoutManager can rearrange your items. In your case you can use GAP_HANDLING_NONE to prevent rearranging. For example:

recyclerView.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL).apply {
            gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_NONE
}
Bracadabra
  • 3,609
  • 3
  • 26
  • 46