The principle of sliding conflict
Android
The event distribution mechanism is based onViewGroup
of. When the user touches on the screen, the event is first passed to the topmostViewGroup
。ViewGroup
Will decide whether to intercept events based on your sliding direction and sliding ability. ifViewGroup
If an event is intercepted, the event will not be passed to the child.View
. ifViewGroup
There is no intercepting event, then the event will be passed to the child.View
。
If the childView
It also needs to respond to sliding events, thenView
Need to be rewriteonTouchEvent()
Method to handle events. sonView
Can be passedrequestDisallowInterceptTouchEvent()
Method to tell the parentViewGroup
Do not intercept events.
Sliding conflict refers to two or moreView
Sliding events are received at the same time, resulting in the failure to slide normally. There are many reasons for sliding conflicts, such as:
- two
View
The sliding direction is the same, e.g.RecyclerView
andScrollView
Slide at the same time. - two
View
The sliding directions are different, but the sliding ranges overlap, for exampleHorizontalScrollView
andWebView
Slide at the same time.
Solution
Android
There are two main solutions to sliding conflicts: external interception method and internal interception method.
- External interception method: by the parent
View
Intercept the event and pass the event to the child as neededView
。 - Internal interception method: Yuzi
View
Intercept the event and pass the event to the parent as neededView
。
External interception method
The external interception method isAndroid
The default sliding conflict resolution method. In this way, the parentView
The event will be intercepted first, and then the event will be passed to the child as needed.View
。
fatherView
Can be rewriteonInterceptTouchEvent()
Method to implement external interception method. existonInterceptTouchEvent()
In the method, we can judge whether the event needs to be intercepted based on the type and location of the event. If an event is required, returntrue
, otherwise returnfalse
。
class CustomParentView(context: Context, attrs: AttributeSet) : ViewGroup(context, attrs) { private var downX: Float = 0F private var downY: Float = 0F override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { when () { MotionEvent.ACTION_DOWN -> { downX = downY = } MotionEvent.ACTION_MOVE -> { val deltaX = - downX val deltaY = - downY //Judge whether to intercept the event based on the sliding direction if ((deltaX) > (deltaY)) { return true } } } return (ev) } override fun onTouchEvent(event: MotionEvent): Boolean { // Handle sliding logic return true } // Other related codes}
advantage:Simple and easy to use, suitable for most sliding conflict issues.
shortcoming:May cause the parentViewGroup
Unable to respond to events such as parentViewGroup
The sonView
Sliding, while the parentViewGroup
The sliding event was also intercepted.
Internal interception method
Internal interception method refers to YuziView
Intercept the event and pass the event to the parent as neededView
。
sonView
Can be rewritedispatchTouchEvent()
Method to implement internal interception method. existdispatchTouchEvent()
In the method, we can judge whether the event needs to be intercepted based on the type and location of the event. If an event is required, callrequestDisallowInterceptTouchEvent()
Method to tell the parentView
Do not intercept events.
class MyView : View { // Implement internal interception by rewriting the dispatchTouchEvent method override fun dispatchTouchEvent(ev: MotionEvent): Boolean { when () { MotionEvent.ACTION_DOWN -> { // When pressed, the parent View is prohibited from intercepting events (true) } MotionEvent.ACTION_MOVE -> { //Judge whether to intercept events based on business logic if (shouldInterceptTouchEvent(ev)) { return true } } MotionEvent.ACTION_UP -> { // When finger is raised, allow parent View to intercept events (false) } } return (ev) } }
advantage:Will not cause the parentViewGroup
Unable to respond to events, applicable to parentViewGroup
HeziView
All need to slide.
shortcoming:Need to rewrite the subView
ofdispatchTouchEvent()
Methods, may cause code complexity.
Notes and optimization tips
- When judging whether an event needs to be intercepted, factors such as the direction of the event, sliding distance, etc. need to be considered.
- If the parent
ViewGroup
HeziView
If all need to slide, you can use the event distribution mechanism to resolve sliding conflicts. - Avoid too much nesting and minimize the nesting hierarchy of the layout to reduce the probability of sliding conflicts.
Summarize
Android
There are two main ways to resolve sliding conflicts: external interception method and internal interception method. I hope this article can help readers resolve sliding conflict problems and improveAndroid
Development level.
This is the end of this article about the solution to Android sliding conflict. For more related content on Android sliding conflict, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!