CopyPastor

Detecting plagiarism made easy.

Score: 1.8597671568466132; Reported for: String similarity, Exact paragraph match Open both answers

Possible Plagiarism

Plagiarized on 2020-08-31
by Taha Gorme

Original Post

Original - Posted on 2019-10-17
by dru



            
Present in both answers; Present only in the new answer; Present only in the old answer;

Here's a solution for horizontal scrolling that allows you to turn off scrolling, but still enables it via calling smoothScrollToPosition. It also lets the user interact with child views within the recycler view.
I found that the other solutions which enabled scrolling temporarily to be able to call smoothScrollToPosition had the side effect of letting the user interrupt scrolling, even when disabling touch events or adding another view on top of the recyclerview.
The key is to getting smoothScrollToPosition to work is to override LinearSmoothScroller.calculateDxToMakeVisible and remove the check to canScrollHorizontally()
``` class NoScrollHorizontalLayoutManager(context: Context) : LinearLayoutManager(context, RecyclerView.HORIZONTAL, false) {
override fun canScrollHorizontally(): Boolean { return false }
override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State?, position: Int) { val linearSmoothScroller = ForceHorizontalLinearSmoothScroller(recyclerView.context) linearSmoothScroller.targetPosition = position startSmoothScroll(linearSmoothScroller) } }


class ForceHorizontalLinearSmoothScroller(context: Context) : LinearSmoothScroller(context) { override fun calculateDxToMakeVisible(view: android.view.View, snapPreference: Int): Int { val layoutManager = layoutManager if (layoutManager == null) { return 0 } val params = view.layoutParams as RecyclerView.LayoutParams val left = layoutManager.getDecoratedLeft(view) - params.leftMargin val right = layoutManager.getDecoratedRight(view) + params.rightMargin val start = layoutManager.paddingLeft val end = layoutManager.width - layoutManager.paddingRight return calculateDtToFit(left, right, start, end, snapPreference) } } ```
**EDIT:** I found that the user could still stop scrolling when tapping on the recycle view while the scroll was in progress. The fix was to override the `RecycleView.onInterceptTouchEvent` and prevent events when the smooth scroll was in progress or when the scroll state was set to `SCROLL_STATE_SETTLING`. (Using `RecycleView.addOnItemTouchListener` for this wont work because the RecycleView stops scrolling then the listener returns true in `RecyleView.onInterceptTouchEvent`.)
``` class NoScrollRecyclerView : RecyclerView { constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
override fun onInterceptTouchEvent(e : MotionEvent) : Boolean { if (layoutManager?.isSmoothScrolling() == true || scrollState == SCROLL_STATE_SETTLING) { return true } return super.onInterceptTouchEvent(e) }
@SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(e :MotionEvent) : Boolean { if (layoutManager?.isSmoothScrolling() == true || scrollState == SCROLL_STATE_SETTLING) { return true } return super.onTouchEvent(e) } } ```
Here's a solution for horizontal scrolling that allows you to turn off scrolling, but still enable it via calling smoothScrollToPosition. It also lets the user interact with child views within the recycler view.
I found that the other solutions which enabled scrolling temporarily to be able to call smoothScrollToPosition had the side effect of letting the user interrupt scrolling, even when disabling touch events or adding another view on top of the recyclerview.
The key is to getting smoothScrollToPosition to work is to override LinearSmoothScroller.calculateDxToMakeVisible and remove the check to canScrollHorizontally()
``` class NoScrollHorizontalLayoutManager(context: Context) : LinearLayoutManager(context, RecyclerView.HORIZONTAL, false) {
override fun canScrollHorizontally(): Boolean { return false }
override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State?, position: Int) { val linearSmoothScroller = ForceHorizontalLinearSmoothScroller(recyclerView.context) linearSmoothScroller.targetPosition = position startSmoothScroll(linearSmoothScroller) } }


class ForceHorizontalLinearSmoothScroller(context: Context) : LinearSmoothScroller(context) { override fun calculateDxToMakeVisible(view: android.view.View, snapPreference: Int): Int { val layoutManager = layoutManager if (layoutManager == null) { return 0 } val params = view.layoutParams as RecyclerView.LayoutParams val left = layoutManager.getDecoratedLeft(view) - params.leftMargin val right = layoutManager.getDecoratedRight(view) + params.rightMargin val start = layoutManager.paddingLeft val end = layoutManager.width - layoutManager.paddingRight return calculateDtToFit(left, right, start, end, snapPreference) } } ```
**EDIT:** I found that the user could still stop scrolling when tapping on the recycle view while the scroll was in progress. The fix was to override the `RecycleView.onInterceptTouchEvent` and prevent events when the smooth scroll was in progress or when the scroll state was set to `SCROLL_STATE_SETTLING`. (Using `RecycleView.addOnItemTouchListener` for this wont work because the RecycleView stops scrolling then the listener returns true in `RecyleView.onInterceptTouchEvent`.)
``` class NoScrollRecyclerView : RecyclerView { constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
override fun onInterceptTouchEvent(e : MotionEvent) : Boolean { if (layoutManager?.isSmoothScrolling() == true || scrollState == SCROLL_STATE_SETTLING) { return true } return super.onInterceptTouchEvent(e) }
@SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(e :MotionEvent) : Boolean { if (layoutManager?.isSmoothScrolling() == true || scrollState == SCROLL_STATE_SETTLING) { return true } return super.onTouchEvent(e) } } ```

        
Present in both answers; Present only in the new answer; Present only in the old answer;