0

I am using recyclerView (TwowayView) and it behaves strange (in scrolling) when data changes. I am using following code to set adapter to it (each time data changes).

// sites = list , rvlinks = twowayview

    adapter = new SitesAdapter(getActivity(), rvLinks, LinksFragment.this, sites);
    rvLinks.setAdapter(adapter);

I've made video of error for better understanding.

https://youtu.be/xPvHper3gpc

As seen , recyclerview is having large top and bottom area (see image) inspite of having only 2 items in list.

only using notifyDatasetChanged() produces the same result. Stucked in this.

Recyclerview has fixed size set.

rvLinks.setHasFixedSize(true);

Any help would be great.

enter image description here

Here is my xml layout :

 <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/dummyview"
    android:layout_below="@+id/sp_category"
    android:layout_marginTop="15dp"
    android:background="@drawable/white_round">

    <Widget.EmptyRecyclerView
    android:id="@+id/rv_links"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:drawSelectorOnTop="false"

    android:orientation="vertical"
    app:twowayview_layoutManager="GridLayoutManager"
    app:twowayview_numColumns="2"

    tools:context=".MainActivity" />



    <TextView
        android:id="@+id/tv_empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="No Sites Found" />

</RelativeLayout>

Here is My RecyclerView with implementation of emptyView.

public class EmptyRecyclerView extends TwoWayView {
    private View emptyView;
    final private AdapterDataObserver observer = new AdapterDataObserver() {
        @Override
        public void onChanged() {
            checkIfEmpty();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            checkIfEmpty();
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            checkIfEmpty();
        }
    };

    public EmptyRecyclerView(Context context) {
        super(context);
    }

    public EmptyRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EmptyRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    void checkIfEmpty() {
        if (emptyView != null && getAdapter() != null) {
            final boolean emptyViewVisible = getAdapter().getItemCount() == 0;
            emptyView.setVisibility(emptyViewVisible ? VISIBLE : GONE);
            setVisibility(emptyViewVisible ? GONE : VISIBLE);
        }
    }

    @Override
    public void setAdapter(Adapter adapter) {
        final Adapter oldAdapter = getAdapter();
        if (oldAdapter != null) {
            oldAdapter.unregisterAdapterDataObserver(observer);
        }
        super.setAdapter(adapter);
        if (adapter != null) {
            adapter.registerAdapterDataObserver(observer);
        }

        checkIfEmpty();
    }

    public void setEmptyView(View emptyView) {
        this.emptyView = emptyView;
        checkIfEmpty();
    }
}
MohK
  • 1,873
  • 1
  • 18
  • 29
  • have you specified any size for recyclerview? There's a bug that you cannot use "wrap_content" for recyclerview to size the view based on its contents https://code.google.com/p/android/issues/detail?id=74772. So just assuming that you have specified the height to may be match_parent or some fixed dp value – random Apr 06 '15 at 10:49
  • I've added my xml to question. See edited. – MohK Apr 06 '15 at 10:54
  • Don't set EmptyRecyclerView height to match_parent, instead first try putting a dp value close to expected height – random Apr 06 '15 at 10:59
  • I tried with 300 dp but same result .may be it's getting top blank area for earlier data , what you think ? – MohK Apr 06 '15 at 11:03
  • what is your device's screen resolution? – random Apr 06 '15 at 11:07
  • app:twowayview_numRows="2" - do you want to set 2 rows or just 1 row with 2 items? – random Apr 06 '15 at 11:09
  • I removed that line , but no luck. and my device is 720*1280 – MohK Apr 06 '15 at 11:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/74557/discussion-between-random-and-mohammad-khatri). – random Apr 06 '15 at 11:14

2 Answers2

1

Try setting an exact height for your recyclerview as it does not respect wrap_content and setting match_parent will take the height of entire space below your listview

Once you start seeing the results, you can use a custom layout manager for your recyclerview, overriding onMeasure().

Check this for an example

Nested Recycler view height doesn't wrap its content

Community
  • 1
  • 1
random
  • 10,238
  • 8
  • 57
  • 101
0

As suggested by @random I tried match_parent but the same issue with TwoWayView. So I decided to change it to RecyclerView in support-v7 lib.

And surprisingly it works as expected. May be it's doing some fancy work in its own GridLayoutManager that causes the problem. GridlayoutManager of recyclerview works great.

Thanks for your help. :)

MohK
  • 1,873
  • 1
  • 18
  • 29