@@ -48,7 +48,6 @@ public abstract class QMUIContinuousNestedBottomDelegateLayout extends QMUIFrame
4848 private Rect mTempRect = new Rect ();
4949 private int mNestedOffsetY = 0 ;
5050
51-
5251 public QMUIContinuousNestedBottomDelegateLayout (Context context ) {
5352 this (context , null );
5453 }
@@ -66,40 +65,78 @@ public QMUIContinuousNestedBottomDelegateLayout(Context context, AttributeSet at
6665 ViewCompat .setNestedScrollingEnabled (this , true );
6766 mHeaderView = onCreateHeaderView ();
6867 mContentView = onCreateContentView ();
69- addView (mHeaderView , getHeaderLayoutParam ());
70- addView (mContentView , getContentLayoutParam ());
68+ if (!(mContentView instanceof IQMUIContinuousNestedBottomView )) {
69+ throw new IllegalStateException ("the view create by onCreateContentView() " +
70+ "should implement from IQMUIContinuousNestedBottomView" );
71+ }
72+ addView (mHeaderView , new FrameLayout .LayoutParams (
73+ ViewGroup .LayoutParams .MATCH_PARENT , getHeaderHeightLayoutParam ()));
74+ addView (mContentView , new FrameLayout .LayoutParams (
75+ ViewGroup .LayoutParams .MATCH_PARENT , ViewGroup .LayoutParams .MATCH_PARENT ));
7176 mHeaderViewOffsetHelper = new QMUIViewOffsetHelper (mHeaderView );
7277 mContentViewOffsetHelper = new QMUIViewOffsetHelper (mContentView );
7378 mViewFlinger = new ViewFlinger ();
7479 }
7580
81+ public View getHeaderView () {
82+ return mHeaderView ;
83+ }
84+
85+ public View getContentView () {
86+ return mContentView ;
87+ }
88+
89+ @ Override
90+ public int getContentHeight () {
91+ IQMUIContinuousNestedBottomView b = (IQMUIContinuousNestedBottomView ) mContentView ;
92+ int bc = b .getContentHeight ();
93+ if (bc == IQMUIContinuousNestedBottomView .HEIGHT_IS_ENOUGH_TO_SCROLL || bc > mContentView .getHeight ()) {
94+ return IQMUIContinuousNestedBottomView .HEIGHT_IS_ENOUGH_TO_SCROLL ;
95+ }
96+ int bottomMargin = getContentBottomMargin ();
97+ if (bc + mHeaderView .getHeight () + bottomMargin > getHeight ()) {
98+ return IQMUIContinuousNestedBottomView .HEIGHT_IS_ENOUGH_TO_SCROLL ;
99+ }
100+ return mHeaderView .getHeight () + bc + bottomMargin ;
101+ }
102+
76103 @ NonNull
77104 protected abstract View onCreateHeaderView ();
78105
79106 @ NonNull
80107 protected abstract View onCreateContentView ();
81108
82- protected FrameLayout .LayoutParams getHeaderLayoutParam () {
83- return new FrameLayout .LayoutParams (
84- ViewGroup .LayoutParams .MATCH_PARENT , ViewGroup .LayoutParams .WRAP_CONTENT );
109+ protected int getHeaderStickyHeight () {
110+ return 0 ;
111+ }
112+
113+
114+ protected int getHeaderHeightLayoutParam () {
115+ return ViewGroup .LayoutParams .WRAP_CONTENT ;
85116 }
86117
87- protected FrameLayout .LayoutParams getContentLayoutParam () {
88- return new FrameLayout .LayoutParams (
89- ViewGroup .LayoutParams .MATCH_PARENT , ViewGroup .LayoutParams .MATCH_PARENT );
118+ protected int getContentBottomMargin () {
119+ return 0 ;
120+ }
121+
122+ @ Override
123+ protected void onMeasure (int widthMeasureSpec , int heightMeasureSpec ) {
124+ super .onMeasure (widthMeasureSpec , heightMeasureSpec );
125+
126+ int heightSize = MeasureSpec .getSize (heightMeasureSpec );
127+ mContentView .measure (widthMeasureSpec , MeasureSpec .makeMeasureSpec (
128+ heightSize - getHeaderStickyHeight () - getContentBottomMargin (),
129+ MeasureSpec .EXACTLY ));
90130 }
91131
92132 @ Override
93133 protected void onLayout (boolean changed , int left , int top , int right , int bottom ) {
94- FrameLayout .LayoutParams headerLp = (LayoutParams ) mHeaderView .getLayoutParams ();
95- mHeaderView .layout (headerLp .leftMargin , headerLp .topMargin ,
96- headerLp .leftMargin + mHeaderView .getMeasuredWidth (),
97- headerLp .topMargin + mHeaderView .getMeasuredHeight ());
98-
99- FrameLayout .LayoutParams contentLp = (LayoutParams ) mContentView .getLayoutParams ();
100- int contentTop = mHeaderView .getBottom () + headerLp .bottomMargin + contentLp .topMargin ;
101- mContentView .layout (contentLp .leftMargin , contentTop ,
102- contentLp .leftMargin + mContentView .getMeasuredWidth (),
134+ mHeaderView .layout (0 , 0 , mHeaderView .getMeasuredWidth (),
135+ mHeaderView .getMeasuredHeight ());
136+
137+
138+ int contentTop = mHeaderView .getBottom ();
139+ mContentView .layout (0 , contentTop , mContentView .getMeasuredWidth (),
103140 contentTop + mContentView .getMeasuredHeight ());
104141
105142 mHeaderViewOffsetHelper .onViewLayout ();
@@ -108,22 +145,18 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
108145
109146 private int offsetBy (int dyUnConsumed ) {
110147 int canConsume = 0 ;
148+ IQMUIContinuousNestedBottomView b = (IQMUIContinuousNestedBottomView ) mContentView ;
149+ int contentHeight = b .getContentHeight ();
150+ FrameLayout .LayoutParams headerLp = (LayoutParams ) mHeaderView .getLayoutParams ();
151+ int minOffset = -mHeaderView .getHeight () - headerLp .bottomMargin + getHeaderStickyHeight ();
152+ if (contentHeight != IQMUIContinuousNestedBottomView .HEIGHT_IS_ENOUGH_TO_SCROLL ) {
153+ minOffset += mContentView .getHeight () - contentHeight ;
154+ minOffset = Math .min (minOffset , 0 );
155+ }
111156 if (dyUnConsumed > 0 ) {
112- FrameLayout .LayoutParams contentLp = (LayoutParams ) mContentView .getLayoutParams ();
113- int maxOffset = mContentView .getBottom () + contentLp .bottomMargin - getHeight ();
114- if (maxOffset >= dyUnConsumed ) {
115- canConsume = dyUnConsumed ;
116- } else {
117- canConsume = maxOffset ;
118- }
157+ canConsume = Math .min (mHeaderView .getTop () - minOffset , dyUnConsumed );
119158 } else if (dyUnConsumed < 0 ) {
120- FrameLayout .LayoutParams headerLp = (LayoutParams ) mHeaderView .getLayoutParams ();
121- int minOffset = mHeaderView .getTop () - headerLp .topMargin ;
122- if (minOffset <= dyUnConsumed ) {
123- canConsume = dyUnConsumed ;
124- } else {
125- canConsume = minOffset ;
126- }
159+ canConsume = Math .max (mHeaderView .getTop () - headerLp .topMargin , dyUnConsumed );
127160 }
128161 if (canConsume != 0 ) {
129162 mHeaderViewOffsetHelper .setTopAndBottomOffset (mHeaderViewOffsetHelper .getTopAndBottomOffset () - canConsume );
@@ -134,17 +167,13 @@ private int offsetBy(int dyUnConsumed) {
134167
135168 @ Override
136169 public void consumeScroll (int dy ) {
137- if (mContentView instanceof IQMUIContinuousNestedBottomView ) {
138- ((IQMUIContinuousNestedBottomView ) mContentView ).consumeScroll (dy );
139- } else {
140- mScrollConsumed [0 ] = 0 ;
141- mScrollConsumed [1 ] = 0 ;
142- dispatchNestedPreScroll (0 , dy , mScrollConsumed , null , ViewCompat .TYPE_NON_TOUCH );
143- int unConsumed = dy - mScrollConsumed [1 ];
144- int remain = offsetBy (unConsumed );
145- dispatchNestedScroll (0 , unConsumed - remain , 0 ,
146- remain , null , ViewCompat .TYPE_NON_TOUCH );
147- }
170+ mScrollConsumed [0 ] = 0 ;
171+ mScrollConsumed [1 ] = 0 ;
172+ dispatchNestedPreScroll (0 , dy , mScrollConsumed , null , ViewCompat .TYPE_NON_TOUCH );
173+ int unConsumed = dy - mScrollConsumed [1 ];
174+ int remain = offsetBy (unConsumed );
175+ dispatchNestedScroll (0 , unConsumed - remain , 0 ,
176+ remain , null , ViewCompat .TYPE_NON_TOUCH );
148177 }
149178
150179 // NestedScrollingChild2
@@ -393,7 +422,7 @@ public boolean onTouchEvent(MotionEvent ev) {
393422 touchSlop = ViewConfiguration .get (getContext ()).getScaledTouchSlop ();
394423 }
395424
396- if (ev .getAction () == MotionEvent .ACTION_DOWN ){
425+ if (ev .getAction () == MotionEvent .ACTION_DOWN ) {
397426 mNestedOffsetY = 0 ;
398427 }
399428
0 commit comments