Sagar Devanga
Sagar Devanga

Reputation: 2819

ScrollView inside a RecyclerView android

I am currently working with recyclerView and cards.

I have a cards layout. Now i want to add scrollview inside the cards is that possible. If yes then how ? The brown layout is the recycler view layout while the blue layout is the cards layout. Inside each card i need a scrollview is that possible ?

enter image description here

Upvotes: 4

Views: 4110

Answers (3)

damai007
damai007

Reputation: 17

I finally found an another way how the ScrollView can be scrolled inside RecyclerView viewHolder. As Ankit Khare's answer, in order to this works, we should disable the touch of RecyclerView when ScrollView is being touched, but his solution is too simple and it didn't quite work well after I tried that. Yeah I know both question and answers were posted from 6 years ago, maybe at that time it worked, but now it's not work anymore after I tried that.

Here is my analysis. Instead of disable the touch of RecyclerView, we should disable its scroll mechanism instead. In order to RecyclerView's scroll can be disabled, we should use function canScrollVertically() from LayoutManager which you use for the RecyclerView. Then, in RecyclerView's adapter, I implemented onTouchListener() for the ScrollView to trigger the touch on it and disable or enable the RecyclerView. So, here is my sample code (I'm using Kotlin):

class MyActivity : AppCompatActivity(), MyAdapter.AdapterListener {
    private var isVerticalScrollEnabled = true

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
   
        /* Set RecyclerView adapter here */
        recyclerView.apply {
            layoutManager = object : LinearLayoutManager(this@MyActivity) {
                override fun canScrollVertically(): Boolean {
                    return isVerticalScrollEnabled 
                }
            }
            adapter = MyAdapter(callback = this@MyActivity)
        }
    }

    /**
     * Callback from MyAdapter.AdapterListener.
     */
    override fun onScrollViewTouched(isTouched: Boolean) {
        isVerticalScrollEnabled = !isTouched
    }
}

class MyAdapter internal constructor(private val callback: AdapterListener) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, i: Int) {
        /* set touch listener for scrollview */
        scrollView.setOnTouchListener(object : View.OnTouchListener {
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                return when (event?.action) {
                    MotionEvent.ACTION_DOWN -> {
                        callback.onScrollViewTouched(isTouched = true)
                        true
                    }
                    MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                        callback.onScrollViewTouched(isTouched = false)
                        true
                    }
                    else -> {
                        /* return false so that scrollview can scroll the content */
                        false
                    }
                }
            }
        })
    }

    internal interface AdapterListener {
        fun onScrollViewTouched(isTouched: Boolean)
    }
}

Hope this will help on someone who look up another answer.

Upvotes: 0

Deepak Baliga
Deepak Baliga

Reputation: 245

Try this instead.

public class NoInterceptScrollView extends ScrollView {

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

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

}

Upvotes: -1

Ankit Khare
Ankit Khare

Reputation: 1385

I am not sure if this will work but you can try this

  • Disable the touch of recycler view when scrollview is being touched.
  • Similarly disable scrollview touch on recyclerview touch.

This can be acheived like this

//For scrollView

   scrollView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                     // Disallow the touch request for parent scroll on touch of child view
                    view.getParent().requestDisallowInterceptTouchEvent(false);
                    return true;
                }
            }); 

see if this helps you.

Upvotes: 7

Related Questions