1313import android .widget .Scroller ;
1414import androidx .core .view .ViewCompat ;
1515
16+ import java .util .ArrayList ;
17+ import java .util .List ;
1618import java .util .concurrent .ScheduledThreadPoolExecutor ;
1719import java .util .concurrent .TimeUnit ;
1820
@@ -30,7 +32,6 @@ public class StackViewLayout extends ViewGroup{
3032 private int stackSize = 3 ;
3133 private float aspectRatio = 0 ;
3234 private boolean autoPlay = true ;
33- private boolean enableGesture = true ;
3435 private int stackModel = MODEL_RIGHT ;
3536 private int edge = 0 ;
3637 private int paddingX = 10 ;
@@ -48,6 +49,8 @@ public class StackViewLayout extends ViewGroup{
4849 private int mDuration = 500 ;
4950 private int mDelay = 3000 ;
5051 private int childWidthMeasure ,childHeightMeasure ;
52+ private boolean mIsDragged = false ;
53+ private List <Integer > padxArray = new ArrayList <>(stackSize );
5154
5255 public StackViewLayout (Context context ) {
5356 this (context , null );
@@ -63,7 +66,6 @@ public StackViewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
6366 stackSize = type .getInteger (R .styleable .StackViewLayout_stackSize ,stackSize );
6467 aspectRatio = type .getFloat (R .styleable .StackViewLayout_stackAspectRatio ,aspectRatio );
6568 autoPlay = type .getBoolean (R .styleable .StackViewLayout_stackAutoPlay ,autoPlay );
66- enableGesture = type .getBoolean (R .styleable .StackViewLayout_stackEnableGesture ,enableGesture );
6769 stackModel = type .getInteger (R .styleable .StackViewLayout_stackModel ,stackModel );
6870 edge = (int )type .getDimension (R .styleable .StackViewLayout_stackEdge ,edge );
6971 paddingX = (int )type .getDimension (R .styleable .StackViewLayout_stackPaddingX ,paddingX );
@@ -85,7 +87,7 @@ public View onCreateView(ViewGroup parent, int viewType) {
8587
8688 @ Override
8789 public void onBindView (View view , int position ) {
88- view .setBackgroundColor (Color .GRAY );
90+ view .setBackgroundColor (Color .LTGRAY );
8991 }
9092
9193 @ Override
@@ -100,52 +102,82 @@ public int getItemCount() {
100102 protected void onMeasure (int widthMeasureSpec , int heightMeasureSpec ) {
101103 int width = getDefaultSize (0 , widthMeasureSpec );
102104 int height = getDefaultSize (0 ,heightMeasureSpec );
103- childWidthMeasure = width -2 *edge -getSeriesSum (paddingX ,offsetX ,getOffsetXSize ())-getPaddingLeft ()-getPaddingRight ();
105+ childWidthMeasure = width -2 *edge -getSeriesSum (paddingX ,offsetX ,getOffsetXSize ()- 1 )-getPaddingLeft ()-getPaddingRight ();
104106 if (aspectRatio > 0 ){
105- height = (int )(childWidthMeasure /aspectRatio )+getPaddingTop ()+getPaddingBottom ();
107+ height = (int )(1f * childWidthMeasure /aspectRatio )+getPaddingTop ()+getPaddingBottom ();
106108 }
107109 childHeightMeasure = height ;
110+
108111 setMeasuredDimension (width ,height );
109112 }
110113
111114 @ Override
112115 protected void onLayout (boolean changed , int l , int t , int r , int b ) {
113- createdChildView ();
116+ addChildView ();
117+ layoutChildView ();
118+ }
119+
120+ private void layoutChildView (){
121+ boolean isLeft = MODEL_LEFT == stackModel ;
114122 int count = getChildCount ();
115123 for (int i =0 ;i <count ;i ++){
124+ int left =getPaddingLeft (),right ,top =getPaddingTop (),bottom ;
116125 View child = getChildAt (i );
117- int left = edge +getSeriesSum (paddingX ,offsetX ,i );
118- int right = left + childWidthMeasure ;
119- int top = edge *i /5 ;
120- int bottom = childHeightMeasure -top ;
126+
127+ // int index = count-1-i;//2,1,0
128+ // int size = MODEL_LEFT == stackModel ? i:index;
129+ // int start = MODEL_LEFT == stackModel ? paddingX-(index)*offsetX:paddingX;
130+
131+ if (0 == i ){
132+ int index = count - 3 ;
133+ left += edge + getSeriesSum (isLeft ? paddingX -index *offsetX :paddingX , offsetX , isLeft ? i :index );
134+ right = left + childWidthMeasure ;
135+ top += getSeriesSum (paddingY , offsetY , index );
136+ bottom = childHeightMeasure - top ;
137+ }else if (count -1 == i ){
138+ left = -childWidthMeasure ;
139+ right = 0 ;
140+ bottom = childHeightMeasure - top ;
141+ }else {
142+ int index = count - 2 - i ;
143+ int size = isLeft ? i -1 : index ;
144+ int start = isLeft ? paddingX - index * offsetX : paddingX ;
145+ left += edge + getSeriesSum (start , offsetX , size );
146+ right = left + childWidthMeasure ;
147+ top += getSeriesSum (paddingY , offsetY , index );
148+ bottom = childHeightMeasure - top ;
149+ }
150+ setChildMeasureDimension (child ,right -left ,bottom -top );
121151 child .layout (left ,top ,right ,bottom );
122152 }
123153 }
124154
125- private void createdChildView (){
155+ private void addChildView (){
126156 int size = getOffsetXSize ();
127- for (int i = getChildCount (); i < 1 +size && size > 0 ; i ++) {
128- int position = (current +i )%adapter .getItemCount ();
157+ int cnt = adapter .getItemCount ();
158+ for (int i = getChildCount (); i < size +2 ; i ++) {
159+ int position = (current +size -i +cnt )%cnt ;
129160 int viewType = adapter .getItemViewType (position );
130161 View child = adapter .onCreateView (this , viewType );
131- child .measure (MeasureSpec .makeMeasureSpec (childWidthMeasure , MeasureSpec .EXACTLY ),
132- MeasureSpec .makeMeasureSpec (childHeightMeasure , MeasureSpec .EXACTLY ));
133162 addView (child );
134163 adapter .onBindView (child ,position );
164+ adapter .onPageSelected (current );
135165 }
136166 }
137167
168+ private void addChildPoleView (){
169+
170+ }
171+
172+ private void setChildMeasureDimension (View child ,int w ,int h ){
173+ child .measure (MeasureSpec .makeMeasureSpec (w , MeasureSpec .EXACTLY ),MeasureSpec .makeMeasureSpec (h , MeasureSpec .EXACTLY ));
174+ }
175+
138176 private int getOffsetXSize (){
139177 return null ==adapter ? 0 : Math .min (adapter .getItemCount (),stackSize );
140178 }
141179
142- /**
143- * 等差数列求和
144- * @param start 起始值
145- * @param ratio 公差
146- * @param size 数量
147- * @return
148- */
180+ /** 等差数列求和*/
149181 private int getSeriesSum (int start ,int ratio ,int size ){
150182 return size *(2 *start -(size -1 )*ratio )/2 ;
151183 }
@@ -161,6 +193,23 @@ public void computeScroll() {
161193 }
162194 }
163195
196+ private void scrollDx (int dx ){
197+ int count = getChildCount ();
198+ int i = count -2 ;
199+ View child = getChildAt (i );
200+ int size = MODEL_LEFT == stackModel ? i -1 :0 ;
201+ int start = paddingX ;
202+ int left = edge +getSeriesSum (start ,offsetX ,size )+getPaddingLeft ()+dx ;
203+ int right = left + childWidthMeasure ;
204+ int top = getPaddingTop ();
205+ int bottom = childHeightMeasure -top ;
206+ child .layout (left ,top ,right ,bottom );
207+ }
208+
209+ private void scrollVelocity (int velocity ){
210+
211+ }
212+
164213 private void startScroll (){
165214 mScroller .startScroll (getScrollX (),getScrollY (),0 ,0 ,mDuration );
166215 ViewCompat .postInvalidateOnAnimation (this );
@@ -217,26 +266,33 @@ protected void onDetachedFromWindow() {
217266
218267 @ Override
219268 public boolean onInterceptTouchEvent (MotionEvent ev ) {
269+ log (" action=" +ev .getAction ()+",x=" +ev .getX ()+",y=" +ev .getY ());
220270 final int action = ev .getAction () & MotionEvent .ACTION_MASK ;
221-
222271 switch (action ) {
223272 case MotionEvent .ACTION_DOWN :
224273 initVelocityTracker ();
225274 startX = (int ) ev .getX ();
226275 startY = (int ) ev .getY ();
227-
228276 break ;
229277 //fixed inner view touch
230278 case MotionEvent .ACTION_MOVE :
231-
279+ float xDistance = Math .abs (startX - ev .getX ());
280+ float yDistance = Math .abs (startY - ev .getY ());
281+ if (xDistance > yDistance && xDistance > mTouchSlop ) {
282+ //水平滑动,需要拦截 在RecyclerView中需要禁止父类拦截
283+ requestDisallowInterceptTouchEvent (true );
284+ mIsDragged = true ;
285+ return true ;
286+ }
232287 default :
233288 }
234- return super . onInterceptTouchEvent ( ev ) ;
289+ return false ;
235290 }
236291
237292 @ Override
238293 public boolean onTouchEvent (MotionEvent ev ) {
239- if (adapter == null || adapter .getItemCount () == 0 ){
294+ log ("action=" +ev .getAction ()+",x=" +ev .getX ()+",y=" +ev .getY ());
295+ if (adapter == null || adapter .getItemCount () <= 1 ){
240296 return false ;
241297 }
242298 if (ev .getAction () == MotionEvent .ACTION_DOWN && ev .getEdgeFlags () != 0 ) {
@@ -246,22 +302,26 @@ public boolean onTouchEvent(MotionEvent ev) {
246302 int action = ev .getActionMasked ();
247303 switch (action ) {
248304 case MotionEvent .ACTION_DOWN :
249-
305+ mIsDragged = false ;
250306 break ;
251307 case MotionEvent .ACTION_MOVE :
252- if (adapter != null && adapter .getItemCount () > 1 ) {
308+ float xDistance = Math .abs (startX - ev .getX ());
309+ float yDistance = Math .abs (startY - ev .getY ());
310+ if (xDistance > yDistance && xDistance > mTouchSlop ) {
311+ requestDisallowInterceptTouchEvent (true );
312+ mIsDragged = true ;
313+ }
314+ if (mIsDragged ){
253315 int currentX = (int ) ev .getX ();
316+ scrollDx (currentX -startX );
254317 }
255318 break ;
256319 case MotionEvent .ACTION_UP :
257-
258320 case MotionEvent .ACTION_CANCEL :
259- if (adapter != null && adapter .getItemCount () > 1 ) {
260- mVelocity .computeCurrentVelocity (1000 , mMaximumVelocity );
261- int velocity = (int ) mVelocity .getXVelocity ();
262-
263- recycleVelocityTracker ();
264- }
321+ mVelocity .computeCurrentVelocity (1000 , mMaximumVelocity );
322+ int velocity = (int ) mVelocity .getXVelocity ();
323+ scrollVelocity (velocity );
324+ recycleVelocityTracker ();
265325 default :
266326 }
267327 return true ;
@@ -294,7 +354,7 @@ public static abstract class StackViewAdapter{
294354
295355 public int getItemViewType (int position ){ return 0 ; }
296356
297- public void onItemDisplay (int position ) { }
357+ public void onPageSelected (int position ) { }
298358 }
299359
300360 void log (String msg ){
0 commit comments