2014-05-19 53 views
2

有一個ListView,當活動開始時,我希望它從底部滾動到頂部。我可以通過在onCreate中設置myListView.setStackFromBottom(true)來完成這項工作,因此列表在活動加載時處於最底部。從下往上滾動ListView

然後我重寫onWindowFocusChanged並使用smoothScrollToPosition(0)這將滾動列表頂部。不過,我需要滾動速度逐漸減慢,因爲它到達頂部,類似於一個看起來像什麼。有什麼辦法可以用動畫或其他方式做到這一點?

謝謝。

+0

爲什麼?我已經看到一些列表會自動滾動,我通常以用戶的身份來討論這種體驗。 – Booger

回答

2

您可以使用CountDownTimer編寫自己的滾動條。

import android.content.Context; 
import android.os.CountDownTimer; 
import android.util.AttributeSet; 
import android.view.KeyEvent; 
import android.view.MotionEvent; 
import android.view.animation.AnticipateOvershootInterpolator; 
import android.view.animation.Interpolator; 
import android.widget.ScrollView; 

public class SmoothScrollView extends ScrollView { 

    private static final long SCROLL_DURATION = 1500; //milliseconds 
    //interpolator for scroller 
    private static final Interpolator INTERPOLATOR = new AnticipateOvershootInterpolator(1); 

    private SmoothScroller smoothScroller; 


    public SmoothScrollView(Context context) { 
     this(context, null, 0); 
    } 


    public SmoothScrollView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 


    public SmoothScrollView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     setSmoothScrollingEnabled(true); 
    } 


    @Override 
    public boolean onTouchEvent(MotionEvent ev) { 
     if (smoothScroller != null)//we are scrolling 
      return true; 
     else return super.onTouchEvent(ev); 
    } 

    @Override 
    public boolean executeKeyEvent(KeyEvent ev) { 
     if (smoothScroller != null)//we are scrolling 
      return true; 
     else return super.executeKeyEvent(ev); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     if (smoothScroller != null)//we are scrolling 
      return true; 
     else return super.onInterceptTouchEvent(ev); 
    } 

    public void smoothScrollTo(int scrollX, int scrollY) { 
     if (smoothScroller != null) { 
      smoothScroller.cancel(); 
     } 
     int deltaY = scrollY - getScrollY(); 
    int deltaX = scrollX - getScrollX(); 
     smoothScroller = new SmoothScroller(SCROLL_DURATION, getScrollX(), getScrollY(), deltaX, deltaY); 
     smoothScroller.start(); 
    } 

    private class SmoothScroller extends CountDownTimer { 

     private int fromX; 
     private int fromY; 
     private int deltaX; 
     private int deltaY; 
     private float scrollTime; 

     public SmoothScroller(long scrollTime, int fromX, int fromY, int deltaX, int deltaY) { 
      super(scrollTime, 1); 
      this.scrollTime = scrollTime; 
      this.fromX = fromX; 
      this.fromY = fromY; 
      this.deltaX = deltaX; 
      this.deltaY = deltaY; 
     } 

     @Override 
     public void onTick(long millisUntilFinished) { 
       float delta = (scrollTime - millisUntilFinished)/scrollTime; 
       delta = INTERPOLATOR.getInterpolation(delta); 
       int x = fromX + ((int) (delta * deltaX)); 
       int y = fromY + ((int) (delta * deltaY)); 
       smoothScrollTo(x, y); 
     } 

     @Override 
     public void onFinish() { 
       float delta = 1f; 
       int x = fromX + ((int) (delta * deltaX)); 
       int y = fromY + ((int) (delta * deltaY)); 
       smoothScroller = null; 
       scrollTo(x, y); 
     } 
    } 
} 

這就是我使用的。只需根據您的需求更改INTERPOLATORSCROLL_DURATION,然後撥打smoothScrollTo而不是scrollTo

我很確定將ScrollView更改爲ListView不會導致任何問題。

+0

真棒,這工作很好。我不得不做一些修改,但總體思路完美。 – Nick

+0

你有沒有機會得到這個使用擴展AdapterView的HListView(https://github.com/sephiroth74/Horizo​​ntalVariableListView)? – lgdroid57