Use RecyclerView inside ScrollView with flexible R

2019-01-06 14:44发布

问题:

I want to know is there any possible way to use RecyclerView?

before this I use RecyclerView with fix height inside a ScrollView but this time i don't know height of the item.

Hint: I read all question and solution of stack question before ask this question since 4 days ago.

update: some solution learn how to scroll RecyclerView on his own but i want to show this expanded.

回答1:

If you want to just scrolling then you can use to NestedScrollView instead of ScrollView So you can modify your code with following :

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

            //design your content here with RecyclerView 

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>


回答2:

I search for answer this question all over the world but I didn't found any direct answer for this popular question. At last I mixed some trick together and solved this problem!

My problem start when my boss asked me to use a RecyclerView inside a ScrollView, and as you know we cannot use two Scrollable objects inside each other except when we set or know fix item height for our RecyclerView. and this is the answer:

Step 1: at first you should find your RecyclerView flexible item height and this is possible from your RecyclerView>onBindViewHolder

holder.itemView.post(new Runnable() {
        @Override
        public void run() {

            int cellWidth = holder.itemView.getWidth();// this will give you cell width dynamically
            int cellHeight = holder.itemView.getHeight();// this will give you cell height dynamically

            dynamicHeight.HeightChange(position, cellHeight); //call your iterface hear
        }
    });

with this code you find your item height as them build and send the item height to your activity with interface.

for those friend who have problem with interface i leave interface code below that should write in Adapter.

public interface DynamicHeight {
    void HeightChange (int position, int height);
}

Step 2: we found our item height so far and now we want to set height to our RecyclerView. first we should calculate the Summation of item height. in this step we do this by BitMap first implements last step interface and write these code below inside your Activity or Fragment that define your RecyclerView:

@Override
public void HeightChange(int position, int height) {
    itemHeight.put(position, height);
    sumHeight = SumHashItem (itemHeight);

    float density = activity.getResources().getDisplayMetrics().density;
    float viewHeight = sumHeight * density;
    review_recyclerView.getLayoutParams().height = (int) sumHeight;

    int i = review_recyclerView.getLayoutParams().height;
}

int SumHashItem (HashMap<Integer, Integer> hashMap) {
    int sum = 0;

    for(Map.Entry<Integer, Integer> myItem: hashMap.entrySet())  {
        sum += myItem.getValue();
    }

    return sum;
}

Step 3: now we have the summation of your RecyclerView height. for last step we should just send the Interface that we write in last step to adapter with some code like this:

reviewRecyclerAdapter = new ReviewRecyclerAdapter(activity, reviewList, review_recyclerView, this);

when you implement interface, you should send it to your with your context that I use this.

Enjoy it



回答3:

[RESOLVED] I have same issue with Horizontal recycleview. Change Gradle repo for recycleview

 compile 'com.android.support:recyclerview-v7:23.2.1'

Write this: linearLayoutManager.setAutoMeasureEnabled(true);

Fixed bugs related to various measure-spec methods in update

Check http://developer.android.com/intl/es/tools/support-library/features.html#v7-recyclerview

I have found issue with 23.2.1 library: When item is match_parent recycle view fill full item to view, please always go with min height or "wrap_content".

Thanks



回答4:

Use This line to your recyclerview :

android:nestedScrollingEnabled="false"

try it ,recyclerview will be smoothly scrolled with flexible height



回答5:

To fix fling in RecyclerView you must override canScrollVertically in LinearLayoutManager:

linearLayoutManager = new LinearLayoutManager(context) {
 @Override
 public boolean canScrollVertically() {
  return false;
 }
};


回答6:

In case setting fixed height for the RecyclerView didn't work for someone (like me), here is what I've added to the fixed height solution:

   mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        int action = e.getAction();
        switch (action) {
        case MotionEvent.ACTION_MOVE:
            rv.getParent().requestDisallowInterceptTouchEvent(true);
            break;
    }
    return false;
}

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

}

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
});

I



回答7:

I fully agree with Ashkan solution, big thanks (voted +1!), but there is one thing...

If RecyclerView does scroll correctly inside ScrollView/NestedScrollView BUT it doesn't fling (intercept it) then the solution is to extend RecyclerView and override OnInterceptTouchEvent and OnTouchEvent. If you don't need any click actions but just want to present items with working fling then simply return false in both like below:

public class InterceptingRecyclerView extends RecyclerView {

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

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

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return false;
    }
}

Or actually it should be called NonIntercepting... ;) Simple as that.



回答8:

I solved this problem by using NestedScrollView instead of ScrollView. And for RecyclerView

    <android.support.v7.widget.RecyclerView 
android:layout_width="match_parent"
  android:layout_height="match_parent" />

And in Code

recyclerView.setHasFixedSize(true);
recyclerView.setNestedScrollingEnabled(false);