Previous articlePerfectly resolve scroll conflict between EditText and ScrollView (Part 1)It mentioned that we have written a method to determine whether EditText can scroll in a vertical direction. So how did this method be obtained?
In fact, there is a method in the Android API to determine whether the control can scroll in a vertical direction. The method name is canScrollVertically(int direction), and the code is as follows:
/** * Check if this view can be scrolled vertically in a certain direction. * * @param direction Negative to check scrolling up, positive to check scrolling down. * @return true if this view can be scrolled in the specified direction, false otherwise. */ public boolean canScrollVertically(int direction) { final int offset = computeVerticalScrollOffset(); final int range = computeVerticalScrollRange() - computeVerticalScrollExtent(); if (range == 0) return false; if (direction < 0) { return offset > 0; } else { return offset < range - 1; } }
According to the comments, it is not difficult to know that this method is used to determine whether the current control can scroll in a vertical direction: when the parameter direction passes a negative value, it will determine whether the current control can scroll up; otherwise, when the parameter direction passes a non-negative value, it will determine whether the current control can scroll down.
From this we know that we can use this method to determine whether a control can scroll in the vertical direction:
if((-1) || (0)) { //Can be rolled in the vertical direction }
So why not use this method? It's helpless, because this method is only provided in API 14 (that is, Android 4.0), and many times we need to be compatible with mobile phones below 4.0, so we cannot use it directly. Although we cannot use this method directly, we can see how it is implemented internally. Just copy it directly! However, there is still a tragic news. The three methods of computeVerticalScrollOffset(), computeVerticalScrollRange() and computeVerticalScrollExtent() are all protected methods, so we still cannot use them. There is no way, so we have to take a look at the internal implementations of these three methods together.
()method
First is the computeVerticalScrollOffset() method:`
protected int computeVerticalScrollOffset() { return mScrollY; }
This method is defined in the View, and neither EditText nor TextView are rewritten, so the return must be mScrollY. So if this method is not applicable, how should we get mScrollY? Let’s guess a little, since there is a variable like mScrollY, there should be a get method. When looking at the API, it is not difficult to find that there is indeed a getScrollY() method in the View:
public final int getScrollY() { return mScrollY; }
2. computeVerticalScrollRange() method
OK, we got the value of the first method through getScrollY(). Next, let’s look at the second method computeVerticalScrollRange():
protected int computeVerticalScrollRange() { return getHeight(); }
This method was found very quickly in the View, but does this method make what we need? Don't forget that we are using EditText! So we need to check if this method is overloaded in EditText and TextView. As we expected, this method was really overloaded in the TextView:
@Override protected int computeVerticalScrollRange() { if (mLayout != null) return (); return (); }
This method returns the height of mLayout, so how do we get mLayout? We just used the getScrollY() method when we got mScrollY. So is there a getLayout() method? With a try-and-see attitude, I suddenly realized that there is really such a method in TextView:
public final Layout getLayout() { return mLayout; }
()method
Well, we also got the value of the second method through getLayout().getHeight() method. Now let's take a look at the last method computeVerticalScrollExtent():
protected int computeVerticalScrollExtent() { return getHeight(); }
We also found this method in the View, but based on the experience of the second method, we should also go to EditText and TextView to see if there is any overload. Once again, as we expected, this method was indeed overloaded in the TextView:
@Override protected int computeVerticalScrollExtent() { return getHeight() - getCompoundPaddingTop() - getCompoundPaddingBottom(); }
Then it is not difficult to find that the three methods used here getHeight(), getCompoundPaddingTop() and getCompoundPaddingBottom() are all public methods, so we can just call them directly.
At this point, we can completely rewrite the canScrollVertically(int direction) method, and the method after rewriting is the canVerticalScroll(EditText editText) method used in our previous article.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.