On the solution of sliding conflict in Scrollview of Android practice

1. Preface

In Android development, it is easy to handle some simple layouts, but once complex pages are involved, especially after using Scrollview for compatibility with small screen phones, there will be many click event conflicts. The most classic is that listview is embedded in Scrollview. I think most of the students who have just come into contact with Android have stepped into this pit. This article starts with a recent project, and then provides some ideas to solve conflicts in the process.

2. Project initiation

The project has a page that involves viewpager, MapView and listview. That is to say, there will be these three views in a page. Obviously, the screen cannot be fully displayed. Scrollview is needed for support. Scrollview is introduced as the outer container. However, because the data display of this page needs to be manually refreshed by the user, the official swiperefreshlayout is introduced.

So the layout of this page is like this. As shown below (the detailed layout is ignored).

Figure-1 layout

After adding Scrollview and swiperefreshlayout, a new problem is introduced, that is, the event conflict between various controls. Viewpager, MapView and listview nested in Scrollview need to be able to correctly handle click events. In particular, listview requires that it can slide in Scrollview. The two slides are confused and not particularly easy to handle.

The problem has been raised. Let's look at the solution directly below.

3. Ideas for solving sliding conflict

In the ViewGroup, there is a method called requestdisallowintercepttouchevent (Boolean disallowintercept), which can be used to control whether the ViewGroup truncates click events. When we solve the sliding conflict, we actually call this method at a certain time, so that the parent layout does not truncate the click event, pass the click event to the child view, and let the relevant child view handle it.

Here are some examples and Thoughts on dealing with various click event conflicts in the project. The processing method only provides one idea, which may not be the optimal method. There must be solutions of other ideas.

The following schemes for handling sliding conflicts are handled in the ontouchlistener of the child view. There is no need to copy the click event processing process of the control, which is relatively convenient in use.

3.1 MapView map page sliding conflict

The main conflict between MapView and Scrollview is that when users click on the MapView map and slide, they want the map map to handle the click event, including subsequent sliding events, scaling the map with both hands, etc.

In Scrollview, click events are truncated by default, resulting in no response to the map after the user clicks the map, let alone scaling the map with both hands.

When the user clicks on the map and slides, it is difficult to determine whether the user wants to scroll view up and down or manipulate the map content. Therefore, I simply think that as long as the user clicks on the map with his finger, he wants to operate the map; When the user raises his finger, it is considered that the user does not need to operate the map.

The solution is also very simple, that is, when the user clicks on the map or slides the map, let the Scrollview not cut off the click event and pass it to the sub view for processing, that is, the map handles the click event; When the user raises his finger, the Scrollview state will be restored to the previous state, that is, the Scrollview can truncate the click event.

I use Baidu map, directly on the code, easier to understand.

3.2 viewpager sliding conflict resolution

In this project, the viewpager is at the top of the page. If only the viewpager is nested in the Scrollview, there will be no conflict because the two controls are sliding events in different directions.

However, due to the introduction of swiperefreshlayout, I found that when sliding the viewpager, it is easy to trigger the down refresh of swiperefreshlayout, which may block the left and right sliding effect of the viewpager, and the experience is very bad. Moreover, in the process of sliding the viewpager, the user's sliding is certainly not always horizontal, and there will be a certain degree of upward and downward sliding.

The viewpager processing conflict is somewhat different from the map processing conflict, because when the user clicks on the viewpager, during the sliding process, the user can basically guess whether the user wants to slide the viewpager left and right or slide the Scrollview up and down (or pull-down refresh). This cannot be the same as the map. When the user clicks on the viewpager, the Scrollview is prohibited from truncating the click event (or swiperefreshlayout pull-down refresh function), judgment needs to be made during sliding.

The solution is to set a threshold. Once the user's horizontal sliding distance on the X axis exceeds this threshold, I think the user wants to slide the viewpager left and right, prohibit the Scrollview from truncating click events, and set swiperefreshlayout not to pull-down refresh. When the user raises his finger, it is considered that the user's operation on the viewpager has been completed, and the Scrollview and swiperefreshlayout states are restored.

When the user clicks the viewpager, record the X coordinate of the click position. When the user slides, if the sliding on the X axis exceeds the threshold (I wrote 60F, which can set the best threshold in actual use), the Scrollview is prohibited from truncating the click event, and the non pull-down refresh is set. When the user leaves the screen with his finger, the state of Scrollview and swiperefreshlayout will be restored.

3.3 listview sliding conflict resolution

There are all kinds of strange problems when you nest listviews in Scrollview. For example, there is a problem with the display of listview, which may be as high as one or two items and not fully expanded. There are two ways to solve this problem.

Both methods can solve the problem of incomplete display of listview, and can also slide (actually using the sliding effect of Scrollview), but one of the biggest regrets is that the views in listview cannot be reused. Because both methods calculate the full height of the listview, and then set the height of the listview control to this height. In this way, the listview is equivalent to a LinearLayout layout, which loses the advantage of reusing views, and may not be as useful as LinearLayout in some scenes. What's more, if there are a large number of pictures, it is easy to oom, This is the last thing you want to see in the R & D process.

You can refer to meituan. Meituan's home page is a Scrollview. When you slide down, you will find that you can't slide down indefinitely. At the bottom, you will be reminded to jump to a secondary page to view all group purchase information. This is a solution to deal with the layout of lists nested in Scrollview, which is similar to listview. But in the project I met, it can't be handled like this.

The two solutions mentioned above are very clear. If you want to display the listview normally, you need to determine the height of the listview, which is very important.

So first, I need to set the height of listview in the layout file, which is an explicit value. After setting the height, if the total height of the items of the data in the listview exceeds the height set by the listview, the view can be reused. However, this only solves the display problem of listview. The sliding conflict between listview and Scrollview has not been solved.

To solve the sliding conflict, the most important thing is to determine the time to prohibit Scrollview from truncating click events, and then analyze the time.

Obviously, when judging the time to prohibit Scrollview from truncating click events, you need to know whether Scrollview slides to the bottom. Therefore, the scrollchanged() method of Scrollview is rewritten to determine whether the Scrollview slides to the bottom (in SDK API 23, Scrollview can set setonscrollchangelister() to monitor the sliding changes, but the previous version does not support it. In order to be compatible, you need to rewrite it).

With the idea, you can also get the logo of Scrollview sliding to the bottom. Next, you can directly solve the sliding conflict and look at the code directly.

Compared with other controls, the sliding conflict between listview and Scrollview is more difficult to solve, but in fact, it is not recommended to nest listview in Scrollview in actual use. Once the business is complex, it is easy to make various UI and business logic conflict errors.

4. Operation effect

Because it is troublesome to add maps, maps are not introduced in the demo. Take a look at the operation effect.

Figure-2 operation effect

5. Summary

This article only provides a solution. In a specific scenario, the interaction often fits the specific business needs. However, in any case, it is most important to find out the timing of click event truncation and processing. Around this key point, we can always find corresponding solutions.

Attach demo project address: Demo

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>