Details about PullScrollView (6) -- extended expansion (getScrollY () in listview is always equal to 0, overScrollBy in ScrollView), listview and scrollview

Source: Internet
Author: User

Details about PullScrollView (6) -- extended expansion (getScrollY () in listview is always equal to 0, overScrollBy in ScrollView), listview and scrollview

Follow your heart is often said. But it was a tough day.

Related Articles:

1. Details of PullScrollView (1) -- custom control attributes
2. Details of PullScrollView (2) -- Animation, Layout, and pull-down Rebound
3. Details about PullScrollView (3) -- Implementation of PullScrollView
4. Details on PullScrollView (4) -- use listview to implement pull-down rebound (method 1)
5. Details on PullScrollView (5) -- use listview to implement pull-down rebound (method 2)
6. Details about PullScrollView (6) -- extended expansion (getScrollY () in listview is always equal to 0 and overScrollBy in ScrollView)

Extended 1: Why does getScrollY () in PullScrollView have a value while getScrollY () in ListView has always been zero. By checking the source code, you will find that getScrollY () is a method of View. Why does ScrollView get scrolly () have a value?
Let's analyze the source code carefully:

(1) first look at the Derivation

ScrollView-> FrameLayout-> ViewGroup-> View
ListView-> AbsListView-> AdapterView-> ViewGroup-> View
As can be seen from the above derivation, all are derived from the View, and none of them are overwritten by the getScrollY () method. That's strange. We didn't rewrite it. It must be a problem of setup.

(2) differences between scrollY settings

In View. java, two functions can be used to set ScrollY:

public void setScrollY(int value) {    scrollTo(mScrollX, value);}public void scrollTo(int x, int y) {    if (mScrollX != x || mScrollY != y) {        int oldX = mScrollX;        int oldY = mScrollY;        mScrollX = x;        mScrollY = y;        invalidateParentCaches();        onScrollChanged(mScrollX, mScrollY, oldX, oldY);        if (!awakenScrollBars()) {            invalidate(true);        }    }}
Let's take a look at what the two functions are called in ScrollView and ListView respectively.
(3) ScrollY settings in ScrollVIew

Because ScrollView is directly derived from FrameLayout, you can directly view what ScrollView. java has done.
First, let's take a look at the usefulness of setScrollY (int value.
Okay, let's take a look at what ScrollTo (int x, int y) uses.
In OnTouchEvent (), the most critical sentence should be here:

@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {    super.onLayout(changed, l, t, r, b);    mIsLayoutDirty = false;    // Give a child focus if it needs it    if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {        scrollToChild(mChildToScrollTo);    }    mChildToScrollTo = null;    // Calling this with the present values causes it to re-clam them    scrollTo(mScrollX, mScrollY);}

During each re-painting, scrollTo () is called to reset the value of mScrollY. Therefore, we can obtain this value when obtaining it.
Then let's take a look at how Listview works:
Wood has setScrollY (int value) and ScrollTo (int x, int y) calls. It seems that I have understood why getScrollY () has no value.
But why does scrollY have a value when OverScrollBy () is rewritten in the previous article? Then let's look for the entire calling process of overScrollBy:
First, in ACTION_MOVE of OnTouchEvent (): (IN AbsListView. java)

case MotionEvent.ACTION_MOVE: {…………    final int y = (int) ev.getY(pointerIndex);    switch (mTouchMode) {    case TOUCH_MODE_DOWN:    case TOUCH_MODE_TAP:    case TOUCH_MODE_DONE_WAITING:        // Check if we have moved far enough that it looks more like a        // scroll than a tap        startScrollIfNeeded(y);        break;    case TOUCH_MODE_SCROLL:    case TOUCH_MODE_OVERSCROLL:        scrollIfNeeded(y);        break;    }    break;}
MotionEvent. ACTION_MOVE will go to scrollIfNeeded (y); (in AbsListView. java)
private void scrollIfNeeded(int y) {    final int rawDeltaY = y - mMotionY;    final int deltaY = rawDeltaY - mMotionCorrection;    int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;    if (mTouchMode == TOUCH_MODE_SCROLL) {        if (y != mLastY) {            ………………            if (motionView != null) {                // Check if the top of the motion view is where it is                // supposed to be                final int motionViewRealTop = motionView.getTop();                if (atEdge) {                    // Apply overscroll                    int overscroll = -incrementalDeltaY -                            (motionViewRealTop - motionViewPrevTop);                    overScrollBy(0, overscroll, 0, mScrollY, 0, 0,                            0, mOverscrollDistance, true);                    …………                }                mMotionY = y;                invalidate();            }            mLastY = y;        }    } else if (mTouchMode == TOUCH_MODE_OVERSCROLL) {        if (y != mLastY) {                        …………            if (overScrollDistance != 0) {                overScrollBy(0, overScrollDistance, 0, mScrollY, 0, 0,                        0, mOverscrollDistance, true);                …………                }            }…………        }    }}
From the source code above, we can see that both normal sliding and OVERSCROLL will determine whether the current boundary has exceeded, and then call overScrollBy (), and then we can see what OverScrollBy () has done;
In View. java:
/*** Scroll the view with standard behavior for scrolling beyond the normal* content boundaries. Views that call this method should override* {@link #onOverScrolled(int, int, boolean, boolean)} to respond to the* results of an over-scroll operation.*/protected boolean overScrollBy(int deltaX, int deltaY,       int scrollX, int scrollY,       int scrollRangeX, int scrollRangeY,       int maxOverScrollX, int maxOverScrollY,       boolean isTouchEvent) {      …………   int newScrollX = scrollX + deltaX;   // Clamp values if at the limits and record   final int left = -maxOverScrollX;   final int right = maxOverScrollX + scrollRangeX;   final int top = -maxOverScrollY;   final int bottom = maxOverScrollY + scrollRangeY;   boolean clampedX = false;   if (newScrollX > right) {       newScrollX = right;       clampedX = true;   } else if (newScrollX < left) {       newScrollX = left;       clampedX = true;   }   boolean clampedY = false;   if (newScrollY > bottom) {       newScrollY = bottom;       clampedY = true;   } else if (newScrollY < top) {       newScrollY = top;       clampedY = true;   }   onOverScrolled(newScrollX, newScrollY, clampedX, clampedY);   return clampedX || clampedY;}
We can see that overScrollBy () does not do anything, but calculates the latest newScrollX and newScrollY, and then passes the result to onOverScrolled;
OnOverScrolled () in View. java is an empty method. From the comments above the overScrollBy () method, we can easily see that we need to rewrite the onOverScrolled () method to implement overScorll scrolling.
protected void onOverScrolled(int scrollX, int scrollY,        boolean clampedX, boolean clampedY) {    // Intentionally empty.}
Let's take a look at what onOverScrolled has done in AbsListView. java.
@Overrideprotected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {    if (mScrollY != scrollY) {        onScrollChanged(mScrollX, scrollY, mScrollX, mScrollY);        mScrollY = scrollY;        invalidateParentIfNeeded();        awakenScrollBars();    }}
Now, I have assigned a new value to mScrollY. This is why getScrollY () has a value in overScrollBy (), while getScrollY () is zero in other cases. Because mScrollY is assigned a value only when overScrollBy () is used. No value is assigned for other times !!!!
Extension 2: overScrollBy () is rewritten in ScrollView. When the source code is compared in the drop-down sliding mode, the ScrollView overwrites onOverScrolled (). The source code is as follows: (IN ScrollView. java)
@Overrideprotected void onOverScrolled(int scrollX, int scrollY,        boolean clampedX, boolean clampedY) {    // Treat animating scrolls differently; see #computeScroll() for why.    if (!mScroller.isFinished()) {        mScrollX = scrollX;        mScrollY = scrollY;        invalidateParentIfNeeded();        if (clampedY) {            mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange());        }    } else {        super.scrollTo(scrollX, scrollY);    }    awakenScrollBars();}
As mentioned above, overScrollBy () does nothing, but calculates the latest moving distance and passes the result to onOverScrolled () and views its onOverScrolled () it is an empty function, that is, if the control derived from View needs to implement the OverScrolled function, it needs to rewrite the onOverScrolled () function and process it in it. Therefore, the overscrolled () control can be rewritten to achieve up-and down-down sliding by overScrollBy !!!!
The following describes how to implement overScrollBy () in ScrollView.
Let's take a look:

The effect is quite obvious, and there is nothing to say about it. It works the same way as PullScrollView (4) -- using listview to implement pull-down rebound (method 1. Let's take a look at the code.

1. Rewrite the ScrollView Code as follows: rewrite the overScrollBy () method and set the maxOverScrollY value in it.

Public class OverScrollView extends ScrollView {// defines the maximum rolling height int mContentMaxMoveHeight = 250; public OverScrollView (Context context) {super (context);} public OverScrollView (Context context, AttributeSet attrs) {super (context, attrs);} public OverScrollView (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle );} @ Override protected boolean overScrollBy (int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {return super. overScrollBy (deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mContentMaxMoveHeight, isTouchEvent );}}
2. The main layout (main. xml) layout is easy to understand. In OverScrollView, put a TableLayout to fill the data.
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"             android:layout_width="fill_parent"             android:layout_height="fill_parent">    <com.harvic.OverScrollView.OverScrollView            android:id="@+id/scrollview"            android:layout_width="match_parent"            android:layout_height="match_parent">        <TableLayout                android:id="@+id/table_layout"                android:layout_width="match_parent"                android:layout_height="wrap_content"/>    </com.harvic.OverScrollView.OverScrollView></FrameLayout>
3. MainActivity. java data filling is the last step of filling TableLayout data in MainActivity. In the second and third blogs, the data is filled with the same code, so we will not discuss it in detail.
public class MainActivity extends Activity {    private TableLayout mMainLayout;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        mMainLayout = (TableLayout) findViewById(R.id.table_layout);        showTable();    }    public void showTable() {        TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(                TableRow.LayoutParams.MATCH_PARENT,                TableRow.LayoutParams.WRAP_CONTENT);        layoutParams.gravity = Gravity.CENTER;        layoutParams.leftMargin = 30;        layoutParams.bottomMargin = 10;        layoutParams.topMargin = 10;        for (int i = 0; i < 30; i++) {            TableRow tableRow = new TableRow(this);            TextView textView = new TextView(this);            textView.setText("Test pull down scroll view " + i);            textView.setTextSize(20);            textView.setPadding(15, 15, 15, 15);            tableRow.addView(textView, layoutParams);            if (i % 2 != 0) {                tableRow.setBackgroundColor(Color.LTGRAY);            } else {                tableRow.setBackgroundColor(Color.WHITE);            }            final int n = i;            tableRow.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    Toast.makeText(getApplicationContext(), "Click item " + n, Toast.LENGTH_SHORT).show();                }            });            mMainLayout.addView(tableRow);        }    }}
Now the code is over. This series is over, and too much content is written. A seemingly complex animation did not expect to involve so much content. It is not easy for students who can finish their work.
The source code is provided at the bottom of the article.


If this article helps you, please pay attention to it.

Source code: http://download.csdn.net/detail/harvic880925/9062283

Please respect the copyright of the original, reprint please indicate the source: http://blog.csdn.net/harvic880925/article/details/48092341 Thank you


Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.