44import android .content .res .TypedArray ;
55import android .graphics .Color ;
66import android .util .AttributeSet ;
7+ import android .util .DisplayMetrics ;
78import android .util .Log ;
9+ import android .util .TypedValue ;
810import android .view .MotionEvent ;
911import android .view .VelocityTracker ;
1012import android .view .View ;
@@ -32,9 +34,9 @@ public class StackViewLayout extends ViewGroup{
3234 private float aspectRatio = 0 ;
3335 private boolean autoPlay = true ;
3436 private int stackModel = MODEL_RIGHT ;
35- private int edge = 0 ;
37+ private int edge = 10 ;
3638 private int paddingX = 10 ;
37- private int offsetX = 0 ;
39+ private int offsetX = 2 ;
3840 private int paddingY = 10 ;
3941 private int offsetY = 2 ;
4042
@@ -53,6 +55,7 @@ public class StackViewLayout extends ViewGroup{
5355 private int dragModel ;
5456 private boolean mIsDragged = false ;
5557 private boolean mIsFling = false ;
58+ private boolean continuePlay = false ;
5659
5760 private List <Integer > xSpace = new ArrayList <>(stackSize );
5861 private List <Integer > ySpace = new ArrayList <>(stackSize );
@@ -80,11 +83,12 @@ public StackViewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
8083 aspectRatio = type .getFloat (R .styleable .StackViewLayout_stackAspectRatio ,aspectRatio );
8184 autoPlay = type .getBoolean (R .styleable .StackViewLayout_stackAutoPlay ,autoPlay );
8285 stackModel = type .getInteger (R .styleable .StackViewLayout_stackModel ,stackModel );
83- edge = (int )type .getDimension (R .styleable .StackViewLayout_stackEdge ,edge );
84- paddingX = (int )type .getDimension (R .styleable .StackViewLayout_stackPaddingX ,paddingX );
85- offsetX = (int )type .getDimension (R .styleable .StackViewLayout_stackOffsetX ,offsetX );
86- paddingY = (int )type .getDimension (R .styleable .StackViewLayout_stackPaddingY ,paddingY );
87- offsetY = (int )type .getDimension (R .styleable .StackViewLayout_stackOffsetY ,offsetY );
86+ DisplayMetrics metrics = getResources ().getDisplayMetrics ();
87+ edge = (int )type .getDimension (R .styleable .StackViewLayout_stackEdge ,dp (edge ,metrics ));
88+ paddingX = (int )type .getDimension (R .styleable .StackViewLayout_stackPaddingX ,dp (paddingX ,metrics ));
89+ offsetX = (int )type .getDimension (R .styleable .StackViewLayout_stackOffsetX ,dp (offsetX ,metrics ));
90+ paddingY = (int )type .getDimension (R .styleable .StackViewLayout_stackPaddingY ,dp (paddingY ,metrics ));
91+ offsetY = (int )type .getDimension (R .styleable .StackViewLayout_stackOffsetY ,dp (offsetY ,metrics ));
8892 type .recycle ();
8993
9094 boolean isLeft = MODEL_LEFT == stackModel ;
@@ -120,6 +124,10 @@ public int getItemCount() {
120124 }
121125 }
122126
127+ private int dp (int dp ,DisplayMetrics metrics ){
128+ return (int )(TypedValue .applyDimension (TypedValue .COMPLEX_UNIT_DIP ,dp ,metrics )+0.5f );
129+ }
130+
123131 @ Override
124132 protected void onAttachedToWindow () {
125133 super .onAttachedToWindow ();
@@ -166,19 +174,19 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) {
166174 private void layoutChildView (){
167175 int count = getChildCount ();
168176 for (int i =0 ;i <count ;i ++){
169- int left =getPaddingLeft (),right ,top =getPaddingTop () ,bottom ;
177+ int left =getPaddingLeft (),right ,top =0 ,bottom ;
170178 View child = getChildAt (i );
171179 if (i ==count -1 ){
172180 left += MODEL_LEFT == stackModel ? getMeasuredWidth ():-childWidthMeasure ;
173181 }else {
174182 int index = Math .max (0 , i - 1 );
175183 left += edge + xSpace .get (index );
176- top + = ySpace .get (index );
184+ top = ySpace .get (index );
177185 }
178- bottom = childHeightMeasure - 2 * top ;
186+ bottom = childHeightMeasure - top ;
179187 right = left + childWidthMeasure ;
180-
181- child .setScaleY (1.0f *( bottom - top )/ childHeightMeasure );
188+ float scale = 1.0f *( bottom - top )/ childHeightMeasure ;
189+ child .setScaleY (scale );
182190 top = getPaddingTop ();
183191 bottom = childHeightMeasure - top ;
184192 child .layout (left ,top ,right ,bottom );
@@ -217,26 +225,37 @@ public void computeScroll() {
217225 private void scrollDx (int dx ){
218226 int x = dx *childWidthMeasure /getMeasuredWidth ();
219227 int count = getChildCount ();
220- float ratio = 1.0f *x /childWidthMeasure ;
221-
228+ float percent = 1f * getSign () *x /childWidthMeasure ;
229+ percent = Math . max (- 1f , Math . min ( 1f , percent ));
222230 View child ;
223231 int top = getPaddingTop ();
224232 int left = getPaddingLeft ();
225233 if ( 0 == (dragModel &stackModel )){
226234 int i = count -2 ;
227- // for(int k=0;k<i;k++){
228- // getChildAt(i).setScaleY(1);
229- // }
235+ for (int k =1 ;k <i ;k ++){
236+ float h = childHeightMeasure - 2 *ySpace .get (k -1 ) + 2f *percent *(ySpace .get (k -1 )-ySpace .get (k ));
237+ float scale = h /childHeightMeasure ;
238+ child = getChildAt (k );
239+ child .setScaleY (scale );
240+ int cleft = left +edge + xSpace .get (k -1 ) + (int )(percent *(xSpace .get (k )-xSpace .get (k -1 )));
241+ child .layout (cleft ,top ,cleft + childWidthMeasure ,childHeightMeasure -top );
242+ }
230243 child = getChildAt (i );
231244 left += edge +xSpace .get (i -1 )+x ;
232245 }else {
233246 int i = count -1 ;
247+ for (int k =2 ;k <i ;k ++){
248+ float h = childHeightMeasure - 2 *ySpace .get (k -1 ) - 2f *percent *(ySpace .get (k -1 )-ySpace .get (k -2 ));
249+ float scale = h /childHeightMeasure ;
250+ child = getChildAt (k );
251+ child .setScaleY (scale );
252+ int cleft = left +edge + xSpace .get (k -1 ) - (int )(percent *(xSpace .get (k -2 )-xSpace .get (k -1 )));
253+ child .layout (cleft ,top ,cleft + childWidthMeasure ,childHeightMeasure -top );
254+ }
234255 child = getChildAt (i );
235256 left += (MODEL_LEFT == stackModel ?getMeasuredWidth ():-childWidthMeasure )+x ;
236257 }
237- int right = left + childWidthMeasure ;
238- int bottom = childHeightMeasure -top ;
239- child .layout (left ,top ,right ,bottom );
258+ child .layout (left ,top ,left + childWidthMeasure ,childHeightMeasure -top );
240259 }
241260
242261 private void resetTouch (){
@@ -265,13 +284,13 @@ private void scrollVelocity(int velocity){
265284 sign = -getSign ();
266285 }
267286 if (velocity *sign >getMeasuredWidth () || -dx *sign >0.3 *childWidthMeasure ){
268- int dnx = dx +sign *(getMeasuredWidth () +edge );
287+ int dnx = dx +sign *(childWidthMeasure +edge )* getMeasuredWidth ()/ childWidthMeasure ;
269288 startScroll (-dx ,dnx );
270289 mIsFling = true ;
271290 }else {
272291 startScroll (-dx , dx );
273292 }
274- startAutoPlay () ;
293+ continuePlay = true ;
275294 }
276295
277296 private void autoScroll (){
@@ -299,6 +318,10 @@ private void nextPage(){
299318 removeViewAt (0 );
300319 }
301320 }
321+ if (continuePlay ){
322+ continuePlay = false ;
323+ startAutoPlay ();
324+ }
302325 }
303326
304327 private void startScroll (int begin ,int dx ){
@@ -347,16 +370,43 @@ public void setAutoPlay(boolean autoPlay){
347370
348371 public void setAdapter (StackViewAdapter adapter ) {
349372 this .adapter = adapter ;
350- requestLayout ();
373+ notifyDataChanged ();
374+ }
375+
376+ public void notifyDataChanged (){
377+ mScroller .abortAnimation ();
378+ removeAllViews ();
379+ }
380+
381+ public void setDurationTime (int duration ,int delay ){
382+ this .mDuration = duration ;
383+ this .mDelay = delay ;
384+ stopAutoPlay (false );
385+ startAutoPlay ();
351386 }
352387
353388 public StackViewAdapter getAdapter (){
354389 return adapter ;
355390 }
356391
392+ public void setCurrentItem (int item ){
393+ if (adapter != null && adapter .getItemCount () > 0 ) {
394+ if (item < 0 ) {
395+ item = 0 ;
396+ } else if (item >= adapter .getItemCount ()){
397+ item = adapter .getItemCount ()-1 ;
398+ }
399+ if (current != item ) {
400+ mScroller .abortAnimation ();
401+ current = item ;
402+ removeAllViews ();
403+ }
404+ }
405+ }
406+
357407 @ Override
358408 public boolean onInterceptTouchEvent (MotionEvent ev ) {
359- log (" action=" +ev .getAction ()+",x=" +ev .getX ()+",y=" +ev .getY ()+",slop=" +mTouchSlop );
409+ // log(" action="+ev.getAction()+",x="+ev.getX()+",y="+ev.getY()+",slop="+mTouchSlop);
360410 if (adapter == null || adapter .getItemCount () <= 1 ){
361411 return false ;
362412 }
@@ -389,7 +439,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
389439
390440 @ Override
391441 public boolean onTouchEvent (MotionEvent ev ) {
392- log (" action=" +ev .getAction ()+",x=" +ev .getX ()+",y=" +ev .getY ());
442+ // log(" action="+ev.getAction()+",x="+ev.getX()+",y="+ev.getY());
393443 if (adapter == null || adapter .getItemCount () <= 1 ){
394444 return false ;
395445 }
0 commit comments