(Nested view in ScrollView) Call method of onTouchEvent in overlapping view, ontouchevent

Source: Internet
Author: User

(Nested view in ScrollView) Call method of onTouchEvent in overlapping view, ontouchevent

In the code of the custom cropping window in front of me, I put the cropping view in a large scrollview, so that the program can only trigger the scrollview and cannot operate on the cropping window. So I added the last two pieces of code below the blog. In fact, when I encountered this problem, I added an Edittext in a scrollview. I restricted the height of Edittext. Therefore, when there are too many content in edittext, I will generate a scroll bar. However, I was unable to trigger the scroll event of edittext. Later I checked the information and understood it. Later, I did not record it, but now I will make a summary of this knowledge point.

Old rules: first, we recommend blog materials. After all, the knowledge learned from others should be shared with others:

[Android instance] [original version] ScrollView nested ScrollView

[Android instance] [original version] nested ListView in ScrollView of android

In fact, these two are an author, and many people may also repost this (it is disgusting to say that only the original address is reprinted ). But it's a bit cool .. In fact, the following are more clear:

Solution to ScrollView nested in Android ScrollView

This is a transfer from a foreigner. I cannot open a foreigner website .. It's easy and clear: tell you that it is not recommended to nest scrollview, but it doesn't matter if it is nested. Then tell you the cause of the problem and then give you a solution, just two lines of code, blabla.

Finally, the key to understanding the principle is: Explanation of the solution code

RequestDisallowInterceptTouchEvent in android event handling mechanism

10 thousand likes!

Well, if you have finished reading the above, you will basically understand it. It will be over here.

 

 

 

 

 

Summary:

In this case, the onTouchEvent of the upper view overlaps with the onTouchEvent of the lower view, and the system cannot determine which onTouchEvent you want to activate. Then the system is very painful, when running the program, the upper layer moves, and the lower layer moves, and the result cannot be any layer (or a small offset ). This is the relationship between views. It is not limited to scrollview, listView, gridView, custom view or something. So there is a problem with the title. To put it bluntly, it is the nesting of view. However, for more articles to be searched, I just don't change the title (what kind of mentality ).

"When there are multiple levels of views, this action will be passed down until the deepest View is encountered if the parent level permits. So the touch event first calls the onTouchEent of the bottom View"

Note: Yes. How can I set whether to allow it? In addition, when running the program, it is indeed obvious that the lower-level view is active and the upper-level view is backward. It is estimated that the parent level by default allows messages to be transmitted to the lower-level view.

"If the onTouchEvent of View receives a touch action and performs corresponding processing, there are two return methods: return true and return false; return true will tell the system that the current View needs to process this touch event. Later, the system will send ACTION_MOVE and ACTION_UP will continue to listen and receive the event, the action has been processed, and the View on the parent layer cannot trigger onTouchEvent"

Measure the test taker's knowledge about the usage of the onTouchEvent return value.

"So each action can only have one onTouchEvent interface to return true"

Multi-layer (> 2) situations need to be considered

"If return false, the system will be notified. The current View does not care about this touch event. At this time, this action will be sent to the parent level and the onTouchEvent of the parent level View will be called. However, this View will not accept any action sent after this touch event, and onTouchEvent will no longer be triggered in this touch event, that is, once the View returns false, then the ACTION_MOVE, ACTION_UP and other actions will not be passed in this View, but the ACTION of the next touch event will still be passed in."

I don't quite understand it here. In the code, return is in the last line, so the previous ACTION _ * will be executed first. If return is true, aiction will return true after execution. It is understandable that the upper layer no longer responds to the event, but if it is false, he should have executed all of them? Then run the command on the upper layer?

After reading the source code, the onTouchEvent in the view Source Code has an int-type flag. Before the action is triggered, the onTouchEvent will be judged, but the method will be rewritten by itself... I think it's strange .. Think about it .. There are many principles here ..

 1 public boolean onTouchEvent(MotionEvent event) { 2         final int viewFlags = mViewFlags; 3  4         if ((viewFlags & ENABLED_MASK) == DISABLED) { 5             if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) { 6                 setPressed(false); 7             } 8             // A disabled view that is clickable still consumes the touch 9             // events, it just doesn't respond to them.10             return (((viewFlags & CLICKABLE) == CLICKABLE ||11                     (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));12         }13 14         if (mTouchDelegate != null) {15             if (mTouchDelegate.onTouchEvent(event)) {16                 return true;17             }18         }19 20         if (((viewFlags & CLICKABLE) == CLICKABLE ||21                 (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {22             switch (event.getAction()) {23                 case MotionEvent.ACTION_UP:24                     ...25                     break;26 27                 case MotionEvent.ACTION_DOWN:28                     ...29                     break;30 31                 case MotionEvent.ACTION_CANCEL:32             ...33                     break;34 35                 case MotionEvent.ACTION_MOVE:36                     ...37                     break;38             }39             return true;40         }41 42         return false;43     }

"If the parent level permits it. If the dispatch method at the parent level is not changed, the system will first call the onInterceptTouchEvent method of the parent View before calling the underlying onTouchEvent to determine whether the parent View wants to intercept the action after the touch event ."

Here, I have a clue about the above questions. Let's look at the source code again.

Draw a flowchart tomorrow

 

"If onInterceptTouchEvent returns true, all actions after this touch event will not be passed to the deep View, and all actions will be passed to the onTouchEvent of the negative View, that is to say, the parent layer has intercepted this touch event, and the subsequent action does not need to ask onInterceptTouchEvent. when the action is triggered after this touch event, onInterceptTouchEvent will not be called again, know the next touch event. If onInterceptTouchEvent returns false, this action will be sent to a deeper View, and each subsequent action will ask the parent-layer onInterceptTouchEvent to intercept this touch event. Only ViewGroup has the onInterceptTouchEvent method, because a common View must be located in the deepest View, and the touch event can be uploaded to the last site, so it will definitely call the onTouchEvent of the View ."

Let's take a look at this section. I have learned a lot about it.

"For the underlying View, there is a way to prevent the parent View from intercepting touch events, that is, call getParent (). requestDisallowInterceptTouchEvent (true); method. Once the underlying View receives the touch action and calls this method, the parent View will no longer call onInterceptTouchEvent, nor will it be able to intercept future actions ."

The final key method can be used to implement functions ~ (But it is best to understand the principle first)

 

Finally, paste the code that first finds this problem. For edittext in scrollview, set the attribute true for the touch sub-view, and set the attribute false for the touch parent view ~

 1     mEssay.setOnTouchListener(new View.OnTouchListener() { 2  3             @Override 4             public boolean onTouch(View v, MotionEvent event) { 5                 // TODO Auto-generated method stub 6                 v.getParent().requestDisallowInterceptTouchEvent(true); 7                 return false; 8             } 9         });10 11         mScrollView.setOnTouchListener(new View.OnTouchListener() {12 13             @Override14             public boolean onTouch(View v, MotionEvent event) {15                 // TODO Auto-generated method stub16                 mEssay.getParent().requestDisallowInterceptTouchEvent(false);17                 return false;18             }19         });

 


Android embeds ViewPage in ScrollView. ViewPage cannot scroll left or right.

Pager. setOnTouchListener (new View. OnTouchListener (){

@ Override
Public boolean onTouch (View v, MotionEvent event ){
V. getParent (). requestDisallowInterceptTouchEvent (true );
Return false;
}
});

Pager. setOnPageChangeListener (new OnPageChangeListener (){

@ Override
Public void onPageSelected (int arg0 ){
}

@ Override
Public void onPageScrolled (int arg0, float arg1, int arg2 ){
MPager. getParent (). requestDisallowInterceptTouchEvent (true );
}

@ Override
Public void onPageScrollStateChanged (int arg0 ){
}
});

Customize ScrollView to solve the gesture conflict between viewflipper and scrollview

Customize the ScrollView, and override its onTouchEvent and dispatchTouchEvent methods to solve the gesture conflict between viewflipper and scrollview. Let's talk about the Code directly: import android. content. context; import android. util. attributeSet; import android. view. gestureDetector; import android. view. motionEvent; import android. widget. scrollView;/*** custom ScrollView, and override its onTouchEvent and dispatchTouchEvent methods, * solves the gesture conflict between viewflipper and scrollview * @ author yangji1_g */public class MyScrollView extends ScrollView {GestureDetector gestureDetector; public MyScrollView (Context context) {super (context ); // TODO Auto-generated constructor stub} public MyScrollView (Context context, AttributeSet attrs) {super (context, attrs ); // TODO Auto-generated constructor stub} public MyScrollView (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle ); // TODO Auto-generated constructor stub} public void setGestureDetector (GestureDetector gestureDetector) {this. gestureDetector = gestureDetector;} @ Override public boolean onTouchEvent (MotionEvent ev) {// TODO Auto-generated method stub super. onTouchEvent (ev); return gestureDetector. onTouchEvent (ev) ;}@ Override public boolean dispatchTouchEvent (MotionEvent ev) {gestureDetector. onTouchEvent (ev); super. dispatchTouchEvent (ev); return true ;}}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.